2007-03-20 Martin Baulig <martin@ximian.com>
[mono.git] / mcs / mcs / class.cs
1 //
2 // class.cs: Class and Struct handlers
3 //
4 // Authors: Miguel de Icaza (miguel@gnu.org)
5 //          Martin Baulig (martin@ximian.com)
6 //          Marek Safar (marek.safar@seznam.cz)
7 //
8 // Licensed under the terms of the GNU GPL
9 //
10 // (C) 2001, 2002, 2003 Ximian, Inc (http://www.ximian.com)
11 // (C) 2004 Novell, Inc
12 //
13 //
14 //  2002-10-11  Miguel de Icaza  <miguel@ximian.com>
15 //
16 //      * class.cs: Following the comment from 2002-09-26 to AddMethod, I
17 //      have fixed a remaining problem: not every AddXXXX was adding a
18 //      fully qualified name.  
19 //
20 //      Now everyone registers a fully qualified name in the DeclSpace as
21 //      being defined instead of the partial name.  
22 //
23 //      Downsides: we are slower than we need to be due to the excess
24 //      copies and the names being registered this way.  
25 //
26 //      The reason for this is that we currently depend (on the corlib
27 //      bootstrap for instance) that types are fully qualified, because
28 //      we dump all the types in the namespace, and we should really have
29 //      types inserted into the proper namespace, so we can only store the
30 //      basenames in the defined_names array.
31 //
32 //
33 #define CACHE
34 using System;
35 using System.Collections;
36 using System.Collections.Specialized;
37 using System.Reflection;
38 using System.Reflection.Emit;
39 using System.Runtime.CompilerServices;
40 using System.Runtime.InteropServices;
41 using System.Security;
42 using System.Security.Permissions;
43 using System.Text;
44
45 #if BOOTSTRAP_WITH_OLDLIB
46 using XmlElement = System.Object;
47 #else
48 using System.Xml;
49 #endif
50
51 using Mono.CompilerServices.SymbolWriter;
52
53 namespace Mono.CSharp {
54
55         public enum Kind {
56                 Root,
57                 Struct,
58                 Class,
59                 Interface,
60                 Enum
61         }
62
63         /// <summary>
64         ///   This is the base class for structs and classes.  
65         /// </summary>
66         public abstract class TypeContainer : DeclSpace, IMemberContainer {
67
68                 public class MemberCoreArrayList: ArrayList
69                 {
70                         /// <summary>
71                         ///   Defines the MemberCore objects that are in this array
72                         /// </summary>
73                         public virtual void DefineContainerMembers ()
74                         {
75                                 foreach (MemberCore mc in this) {
76                                         try {
77                                                 mc.Define ();
78                                         } catch (Exception e) {
79                                                 throw new InternalErrorException (mc, e);
80                                         }
81                                 }
82                         }
83
84                         public virtual void Emit ()
85                         {
86                                 foreach (MemberCore mc in this)
87                                         mc.Emit ();
88                         }
89                 }
90
91                 public class MethodArrayList : MemberCoreArrayList
92                 {
93                         [Flags]
94                         enum CachedMethods {
95                                 Equals                  = 1,
96                                 GetHashCode             = 1 << 1
97                         }
98  
99                         CachedMethods cached_method;
100                         TypeContainer container;
101
102                         public MethodArrayList (TypeContainer container)
103                         {
104                                 this.container = container;
105                         }
106  
107                         /// <summary>
108                         /// Method container contains Equals method
109                         /// </summary>
110                         public bool HasEquals {
111                                 set {
112                                         cached_method |= CachedMethods.Equals;
113                                 }
114  
115                                 get {
116                                         return (cached_method & CachedMethods.Equals) != 0;
117                                 }
118                         }
119  
120                         /// <summary>
121                         /// Method container contains GetHashCode method
122                         /// </summary>
123                         public bool HasGetHashCode {
124                                 set {
125                                         cached_method |= CachedMethods.GetHashCode;
126                                 }
127  
128                                 get {
129                                         return (cached_method & CachedMethods.GetHashCode) != 0;
130                                 }
131                         }
132  
133                         public override void DefineContainerMembers ()
134                         {
135                                 base.DefineContainerMembers ();
136  
137                                 if (HasEquals && !HasGetHashCode) {
138                                         Report.Warning (659, 3, container.Location, "`{0}' overrides Object.Equals(object) but does not override Object.GetHashCode()", container.GetSignatureForError ());
139                                 }
140                         }
141                 }
142
143                 public sealed class IndexerArrayList : MemberCoreArrayList
144                 {
145                         /// <summary>
146                         /// The indexer name for this container
147                         /// </summary>
148                         public string IndexerName = DefaultIndexerName;
149
150                         bool seen_normal_indexers = false;
151
152                         TypeContainer container;
153
154                         public IndexerArrayList (TypeContainer container)
155                         {
156                                 this.container = container;
157                         }
158
159                         /// <summary>
160                         /// Defines the indexers, and also verifies that the IndexerNameAttribute in the
161                         /// class is consistent.  Either it is `Item' or it is the name defined by all the
162                         /// indexers with the `IndexerName' attribute.
163                         ///
164                         /// Turns out that the IndexerNameAttribute is applied to each indexer,
165                         /// but it is never emitted, instead a DefaultMember attribute is attached
166                         /// to the class.
167                         /// </summary>
168                         public override void DefineContainerMembers()
169                         {
170                                 base.DefineContainerMembers ();
171
172                                 string class_indexer_name = null;
173
174                                 //
175                                 // If there's both an explicit and an implicit interface implementation, the
176                                 // explicit one actually implements the interface while the other one is just
177                                 // a normal indexer.  See bug #37714.
178                                 //
179
180                                 // Invariant maintained by AddIndexer(): All explicit interface indexers precede normal indexers
181                                 foreach (Indexer i in this) {
182                                         if (i.InterfaceType != null) {
183                                                 if (seen_normal_indexers)
184                                                         throw new Exception ("Internal Error: 'Indexers' array not sorted properly.");
185                                                 continue;
186                                         }
187
188                                         seen_normal_indexers = true;
189
190                                         if (class_indexer_name == null) {
191                                                 class_indexer_name = i.ShortName;
192                                                 continue;
193                                         }
194
195                                         if (i.ShortName != class_indexer_name)
196                                                 Report.Error (668, i.Location, "Two indexers have different names; the IndexerName attribute must be used with the same name on every indexer within a type");
197                                 }
198
199                                 if (class_indexer_name != null)
200                                         IndexerName = class_indexer_name;
201                         }
202
203                         public override void Emit ()
204                         {
205                                 base.Emit ();
206
207                                 if (!seen_normal_indexers)
208                                         return;
209
210                                 CustomAttributeBuilder cb = new CustomAttributeBuilder (TypeManager.default_member_ctor, new string [] { IndexerName });
211                                 container.TypeBuilder.SetCustomAttribute (cb);
212                         }
213                 }
214
215                 public class OperatorArrayList: MemberCoreArrayList
216                 {
217                         TypeContainer container;
218
219                         public OperatorArrayList (TypeContainer container)
220                         {
221                                 this.container = container;
222                         }
223
224                         //
225                         // Operator pair checking
226                         //
227                         class OperatorEntry
228                         {
229                                 public int flags;
230                                 public Type ret_type;
231                                 public Type type1, type2;
232                                 public Operator op;
233                                 public Operator.OpType ot;
234                                 
235                                 public OperatorEntry (int f, Operator o)
236                                 {
237                                         flags = f;
238
239                                         ret_type = o.MemberType;
240                                         Type [] pt = o.ParameterTypes;
241                                         type1 = pt [0];
242                                         type2 = pt [1];
243                                         op = o;
244                                         ot = o.OperatorType;
245                                 }
246
247                                 public override int GetHashCode ()
248                                 {       
249                                         return ret_type.GetHashCode ();
250                                 }
251
252                                 public override bool Equals (object o)
253                                 {
254                                         OperatorEntry other = (OperatorEntry) o;
255
256                                         if (other.ret_type != ret_type)
257                                                 return false;
258                                         if (other.type1 != type1)
259                                                 return false;
260                                         if (other.type2 != type2)
261                                                 return false;
262                                         return true;
263                                 }
264                         }
265                                 
266                         //
267                         // Checks that some operators come in pairs:
268                         //  == and !=
269                         // > and <
270                         // >= and <=
271                         // true and false
272                         //
273                         // They are matched based on the return type and the argument types
274                         //
275                         void CheckPairedOperators ()
276                         {
277                                 IDictionary pairs = new HybridDictionary ();
278                                 Operator true_op = null;
279                                 Operator false_op = null;
280                                 bool has_equality_or_inequality = false;
281                                 
282                                 // Register all the operators we care about.
283                                 foreach (Operator op in this){
284                                         int reg = 0;
285
286                                         // Skip erroneous code.
287                                         if (op.MethodBuilder == null)
288                                                 continue;
289
290                                         switch (op.OperatorType){
291                                         case Operator.OpType.Equality:
292                                                 reg = 1;
293                                                 has_equality_or_inequality = true;
294                                                 break;
295                                         case Operator.OpType.Inequality:
296                                                 reg = 2;
297                                                 has_equality_or_inequality = true;
298                                                 break;
299
300                                         case Operator.OpType.True:
301                                                 true_op = op;
302                                                 break;
303                                         case Operator.OpType.False:
304                                                 false_op = op;
305                                                 break;
306                                                 
307                                         case Operator.OpType.GreaterThan:
308                                                 reg = 1; break;
309                                         case Operator.OpType.LessThan:
310                                                 reg = 2; break;
311                                                 
312                                         case Operator.OpType.GreaterThanOrEqual:
313                                                 reg = 1; break;
314                                         case Operator.OpType.LessThanOrEqual:
315                                                 reg = 2; break;
316                                         }
317                                         if (reg == 0)
318                                                 continue;
319
320                                         OperatorEntry oe = new OperatorEntry (reg, op);
321
322                                         object o = pairs [oe];
323                                         if (o == null)
324                                                 pairs [oe] = oe;
325                                         else {
326                                                 oe = (OperatorEntry) o;
327                                                 oe.flags |= reg;
328                                         }
329                                 }
330
331                                 if (true_op != null){
332                                         if (false_op == null)
333                                                 Report.Error (216, true_op.Location, "The operator `{0}' requires a matching operator `false' to also be defined",
334                                                         true_op.GetSignatureForError ());
335                                 } else if (false_op != null)
336                                         Report.Error (216, false_op.Location, "The operator `{0}' requires a matching operator `true' to also be defined",
337                                                 false_op.GetSignatureForError ());
338                                 
339                                 //
340                                 // Look for the mistakes.
341                                 //
342                                 foreach (DictionaryEntry de in pairs){
343                                         OperatorEntry oe = (OperatorEntry) de.Key;
344
345                                         if (oe.flags == 3)
346                                                 continue;
347
348                                         string s = "";
349                                         switch (oe.ot){
350                                         case Operator.OpType.Equality:
351                                                 s = "!=";
352                                                 break;
353                                         case Operator.OpType.Inequality: 
354                                                 s = "==";
355                                                 break;
356                                         case Operator.OpType.GreaterThan: 
357                                                 s = "<";
358                                                 break;
359                                         case Operator.OpType.LessThan:
360                                                 s = ">";
361                                                 break;
362                                         case Operator.OpType.GreaterThanOrEqual:
363                                                 s = "<=";
364                                                 break;
365                                         case Operator.OpType.LessThanOrEqual:
366                                                 s = ">=";
367                                                 break;
368                                         }
369                                         Report.Error (216, oe.op.Location,
370                                                 "The operator `{0}' requires a matching operator `{1}' to also be defined",
371                                                 oe.op.GetSignatureForError (), s);
372                                 }
373
374                                 if (has_equality_or_inequality && (RootContext.WarningLevel > 2)) {
375                                         if (container.Methods == null || !container.Methods.HasEquals)
376                                                 Report.Warning (660, 2, container.Location, "`{0}' defines operator == or operator != but does not override Object.Equals(object o)", container.GetSignatureForError ());
377  
378                                         if (container.Methods == null || !container.Methods.HasGetHashCode)
379                                                 Report.Warning (661, 2, container.Location, "`{0}' defines operator == or operator != but does not override Object.GetHashCode()", container.GetSignatureForError ());
380                                 }
381                         }
382
383                         public override void DefineContainerMembers ()
384                         {
385                                 base.DefineContainerMembers ();
386                                 CheckPairedOperators ();
387                         }
388                 }
389
390
391                 // Whether this is a struct, class or interface
392                 public readonly Kind Kind;
393
394                 // Holds a list of classes and structures
395                 protected ArrayList types;
396
397                 // Holds the list of properties
398                 MemberCoreArrayList properties;
399
400                 // Holds the list of delegates
401                 MemberCoreArrayList delegates;
402                 
403                 // Holds the list of constructors
404                 protected MemberCoreArrayList instance_constructors;
405
406                 // Holds the list of fields
407                 MemberCoreArrayList fields;
408
409                 // Holds a list of fields that have initializers
410                 protected ArrayList initialized_fields;
411
412                 // Holds a list of static fields that have initializers
413                 protected ArrayList initialized_static_fields;
414
415                 // Holds the list of constants
416                 MemberCoreArrayList constants;
417
418                 // Holds the methods.
419                 MethodArrayList methods;
420
421                 // Holds the events
422                 protected MemberCoreArrayList events;
423
424                 // Holds the indexers
425                 IndexerArrayList indexers;
426
427                 // Holds the operators
428                 MemberCoreArrayList operators;
429
430                 // Holds the compiler generated classes
431                 ArrayList compiler_generated;
432
433                 //
434                 // Pointers to the default constructor and the default static constructor
435                 //
436                 protected Constructor default_constructor;
437                 protected Constructor default_static_constructor;
438
439                 //
440                 // Points to the first non-static field added to the container.
441                 //
442                 // This is an arbitrary choice.  We are interested in looking at _some_ non-static field,
443                 // and the first one's as good as any.
444                 //
445                 FieldBase first_nonstatic_field = null;
446
447                 //
448                 // This one is computed after we can distinguish interfaces
449                 // from classes from the arraylist `type_bases' 
450                 //
451                 TypeExpr base_type;
452                 TypeExpr[] iface_exprs;
453                 Type GenericType;
454
455                 ArrayList type_bases;
456
457                 bool members_resolved;
458                 bool members_resolved_ok;
459                 bool members_defined;
460                 bool members_defined_ok;
461
462                 // The interfaces we implement.
463                 protected Type[] ifaces;
464
465                 // The base member cache and our member cache
466                 MemberCache base_cache;
467                 MemberCache member_cache;
468
469                 public const string DefaultIndexerName = "Item";
470
471 #if GMCS_SOURCE
472                 GenericTypeParameterBuilder[] gen_params;
473 #endif
474
475                 ArrayList partial_parts;
476
477                 /// <remarks>
478                 ///  The pending methods that need to be implemented
479                 //   (interfaces or abstract methods)
480                 /// </remarks>
481                 PendingImplementation pending;
482
483                 public TypeContainer (NamespaceEntry ns, DeclSpace parent, MemberName name,
484                                       Attributes attrs, Kind kind)
485                         : base (ns, parent, name, attrs)
486                 {
487                         if (parent != null && parent.NamespaceEntry != ns)
488                                 throw new InternalErrorException ("A nested type should be in the same NamespaceEntry as its enclosing class");
489
490                         this.Kind = kind;
491                         this.PartialContainer = this;
492                 }
493
494                 public bool AddMember (MemberCore symbol)
495                 {
496                         return AddToContainer (symbol, symbol.MemberName.MethodName);
497                 }
498
499                 protected virtual bool AddMemberType (DeclSpace ds)
500                 {
501                         return AddToContainer (ds, ds.Basename);
502                 }
503
504                 public void AddConstant (Const constant)
505                 {
506                         if (!AddMember (constant))
507                                 return;
508
509                         if (constants == null)
510                                 constants = new MemberCoreArrayList ();
511                         
512                         constants.Add (constant);
513                 }
514
515                 public TypeContainer AddTypeContainer (TypeContainer tc)
516                 {
517                         if (!AddMemberType (tc))
518                                 return tc;
519
520                         if (types == null)
521                                 types = new MemberCoreArrayList ();
522                         types.Add (tc);
523
524                         return tc;
525                 }
526
527                 public virtual TypeContainer AddPartial (TypeContainer nextPart)
528                 {
529                         return AddPartial (nextPart, nextPart.Basename);
530                 }
531
532                 protected TypeContainer AddPartial (TypeContainer nextPart, string name)
533                 {
534                         nextPart.ModFlags |= Modifiers.PARTIAL;
535                         TypeContainer tc = defined_names [name] as TypeContainer;
536
537                         if (tc == null)
538                                 return AddTypeContainer (nextPart);
539
540                         if ((tc.ModFlags & Modifiers.PARTIAL) == 0) {
541                                 Report.SymbolRelatedToPreviousError (tc);
542                                 Error_MissingPartialModifier (nextPart);
543                                 return tc;
544                         }
545
546                         if (tc.Kind != nextPart.Kind) {
547                                 Report.SymbolRelatedToPreviousError (tc);
548                                 Report.Error (261, nextPart.Location,
549                                         "Partial declarations of `{0}' must be all classes, all structs or all interfaces",
550                                         nextPart.GetSignatureForError ());
551                                 return tc;
552                         }
553
554                         if ((tc.ModFlags & Modifiers.Accessibility) != (nextPart.ModFlags & Modifiers.Accessibility) &&
555                                 ((tc.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) == 0 &&
556                                  (nextPart.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) == 0)) {
557                                 Report.SymbolRelatedToPreviousError (tc);
558                                 Report.Error (262, nextPart.Location,
559                                         "Partial declarations of `{0}' have conflicting accessibility modifiers",
560                                         nextPart.GetSignatureForError ());
561                                 return tc;
562                         }
563
564                         if (tc.MemberName.IsGeneric) {
565                                 TypeParameter[] tc_names = tc.TypeParameters;
566                                 TypeParameterName[] part_names = nextPart.MemberName.TypeArguments.GetDeclarations ();
567
568                                 for (int i = 0; i < tc_names.Length; ++i) {
569                                         if (tc_names[i].Name == part_names[i].Name)
570                                                 continue;
571
572                                         Report.SymbolRelatedToPreviousError (part_names[i].Location, "");
573                                         Report.Error (264, tc.Location, "Partial declarations of `{0}' must have the same type parameter names in the same order",
574                                                 tc.GetSignatureForError ());
575                                         return tc;
576                                 }
577                         }
578
579                         if (tc.partial_parts == null)
580                                 tc.partial_parts = new ArrayList (1);
581
582                         tc.ModFlags |= nextPart.ModFlags;
583                         if (nextPart.attributes != null) {
584                                 if (tc.attributes == null)
585                                         tc.attributes = nextPart.attributes;
586                                 else
587                                         tc.attributes.AddAttributes (nextPart.attributes.Attrs);
588                         }
589
590                         nextPart.PartialContainer = tc;
591                         tc.partial_parts.Add (nextPart);
592                         return tc;
593                 }
594
595                 public void AddDelegate (Delegate d)
596                 {
597                         if (!AddMemberType (d))
598                                 return;
599
600                         if (delegates == null)
601                                 delegates = new MemberCoreArrayList ();
602
603                         delegates.Add (d);
604                 }
605
606                 public void AddMethod (Method method)
607                 {
608                         if (!AddMember (method))
609                                 return;
610
611                         if (methods == null)
612                                 methods = new MethodArrayList (this);
613                         
614                         if (method.MemberName.Left != null)
615                                 methods.Insert (0, method);
616                         else 
617                                 methods.Add (method);
618                 }
619
620                 //
621                 // Do not use this method: use AddMethod.
622                 //
623                 // This is only used by iterators.
624                 //
625                 public void AppendMethod (Method method)
626                 {
627                         if (!AddMember (method))
628                                 return;
629
630                         if (methods == null)
631                                 methods = new MethodArrayList (this);
632
633                         methods.Add (method);
634                 }
635
636                 public void AddConstructor (Constructor c)
637                 {
638                         if (c.Name != MemberName.Name) {
639                                 Report.Error (1520, c.Location, "Class, struct, or interface method must have a return type");
640                         }
641
642                         bool is_static = (c.ModFlags & Modifiers.STATIC) != 0;
643                         
644                         if (is_static){
645                                 if (default_static_constructor != null) {
646                                         Report.SymbolRelatedToPreviousError (default_static_constructor);
647                                         Report.Error (111, c.Location, Error111, c.GetSignatureForError ());
648                                         return;
649                                 }
650
651                                 default_static_constructor = c;
652                         } else {
653                                 if (c.Parameters.Empty){
654                                         if (default_constructor != null) {
655                                                 Report.SymbolRelatedToPreviousError (default_constructor);
656                                                 Report.Error (111, c.Location, Error111, c.GetSignatureForError ());
657                                                 return;
658                                         }
659                                         default_constructor = c;
660                                 }
661                                 
662                                 if (instance_constructors == null)
663                                         instance_constructors = new MemberCoreArrayList ();
664                                 
665                                 instance_constructors.Add (c);
666                         }
667                 }
668
669                 internal static string Error111 {
670                         get {
671                                 return "`{0}' is already defined. Rename this member or use different parameter types";
672                         }
673                 }
674
675                 public void AddField (FieldBase field)
676                 {
677                         if (!AddMember (field))
678                                 return;
679
680                         if (fields == null)
681                                 fields = new MemberCoreArrayList ();
682
683                         fields.Add (field);
684
685                         if ((field.ModFlags & Modifiers.STATIC) != 0)
686                                 return;
687
688                         if (first_nonstatic_field == null) {
689                                 first_nonstatic_field = field;
690                                 return;
691                         }
692
693                         if (Kind == Kind.Struct &&
694                             first_nonstatic_field.Parent != field.Parent &&
695                             RootContext.WarningLevel >= 3) {
696                                 Report.SymbolRelatedToPreviousError (first_nonstatic_field.Parent);
697                                 Report.Warning (282, 3, field.Location,
698                                         "struct instance field `{0}' found in different declaration from instance field `{1}'",
699                                         field.GetSignatureForError (), first_nonstatic_field.GetSignatureForError ());
700                         }
701                 }
702
703                 public void AddProperty (Property prop)
704                 {
705                         if (!AddMember (prop) || 
706                                 !AddMember (prop.Get) || !AddMember (prop.Set))
707                                 return;
708
709                         if (properties == null)
710                                 properties = new MemberCoreArrayList ();
711
712                         if (prop.MemberName.Left != null)
713                                 properties.Insert (0, prop);
714                         else
715                                 properties.Add (prop);
716                 }
717
718                 public void AddEvent (Event e)
719                 {
720                         if (!AddMember (e))
721                                 return;
722
723                         if (e is EventProperty) {
724                                 if (!AddMember (e.Add))
725                                         return;
726
727                                 if (!AddMember (e.Remove))
728                                         return;
729                         }
730
731                         if (events == null)
732                                 events = new MemberCoreArrayList ();
733
734                         events.Add (e);
735                 }
736
737                 /// <summary>
738                 /// Indexer has special handling in constrast to other AddXXX because the name can be driven by IndexerNameAttribute
739                 /// </summary>
740                 public void AddIndexer (Indexer i)
741                 {
742                         if (indexers == null)
743                                 indexers = new IndexerArrayList (this);
744
745                         if (i.IsExplicitImpl)
746                                 indexers.Insert (0, i);
747                         else
748                                 indexers.Add (i);
749                 }
750
751                 public void AddOperator (Operator op)
752                 {
753                         if (!AddMember (op))
754                                 return;
755
756                         if (operators == null)
757                                 operators = new OperatorArrayList (this);
758
759                         operators.Add (op);
760                 }
761
762                 public void AddCompilerGeneratedClass (CompilerGeneratedClass c)
763                 {
764                         Report.Debug (64, "ADD COMPILER GENERATED CLASS", this, c);
765
766                         if (compiler_generated == null)
767                                 compiler_generated = new ArrayList ();
768
769                         compiler_generated.Add (c);
770                 }
771
772                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
773                 {
774                         if (a.Type == TypeManager.default_member_type) {
775                                 if (Indexers != null) {
776                                         Report.Error (646, a.Location, "Cannot specify the `DefaultMember' attribute on type containing an indexer");
777                                         return;
778                                 }
779                         }
780                         
781                         base.ApplyAttributeBuilder (a, cb);
782                 } 
783
784                 public override AttributeTargets AttributeTargets {
785                         get {
786                                 throw new NotSupportedException ();
787                         }
788                 }
789
790                 public ArrayList Types {
791                         get {
792                                 return types;
793                         }
794                 }
795
796                 public MethodArrayList Methods {
797                         get {
798                                 return methods;
799                         }
800                 }
801
802                 public ArrayList Constants {
803                         get {
804                                 return constants;
805                         }
806                 }
807
808                 public ArrayList CompilerGenerated {
809                         get {
810                                 return compiler_generated;
811                         }
812                 }
813
814                 protected Type BaseType {
815                         get {
816                                 return TypeBuilder.BaseType;
817                         }
818                 }
819                 
820                 public ArrayList Bases {
821                         get {
822                                 return type_bases;
823                         }
824
825                         set {
826                                 type_bases = value;
827                         }
828                 }
829
830                 public ArrayList Fields {
831                         get {
832                                 return fields;
833                         }
834                 }
835
836                 public ArrayList InstanceConstructors {
837                         get {
838                                 return instance_constructors;
839                         }
840                 }
841
842                 public ArrayList Properties {
843                         get {
844                                 return properties;
845                         }
846                 }
847
848                 public ArrayList Events {
849                         get {
850                                 return events;
851                         }
852                 }
853                 
854                 public ArrayList Indexers {
855                         get {
856                                 return indexers;
857                         }
858                 }
859
860                 public ArrayList Operators {
861                         get {
862                                 return operators;
863                         }
864                 }
865
866                 public ArrayList Delegates {
867                         get {
868                                 return delegates;
869                         }
870                 }
871                 
872                 protected override TypeAttributes TypeAttr {
873                         get {
874                                 return Modifiers.TypeAttr (ModFlags, IsTopLevel) | base.TypeAttr;
875                         }
876                 }
877
878                 public string IndexerName {
879                         get {
880                                 return indexers == null ? DefaultIndexerName : indexers.IndexerName;
881                         }
882                 }
883
884                 public bool IsComImport {
885                         get {
886                                 if (OptAttributes == null)
887                                         return false;
888
889                                 return OptAttributes.Contains (TypeManager.comimport_attr_type);
890                         }
891                 }
892
893                 public virtual void RegisterFieldForInitialization (MemberCore field, FieldInitializer expression)
894                 {
895                         if ((field.ModFlags & Modifiers.STATIC) != 0){
896                                 if (initialized_static_fields == null)
897                                         initialized_static_fields = new ArrayList (4);
898
899                                 initialized_static_fields.Add (expression);
900                         } else {
901                                 if (initialized_fields == null)
902                                         initialized_fields = new ArrayList (4);
903
904                                 initialized_fields.Add (expression);
905                         }
906                 }
907
908                 //
909                 // Emits the instance field initializers
910                 //
911                 public bool EmitFieldInitializers (EmitContext ec)
912                 {
913                         ArrayList fields;
914                         
915                         if (ec.IsStatic){
916                                 fields = initialized_static_fields;
917                         } else {
918                                 fields = initialized_fields;
919                         }
920
921                         if (fields == null)
922                                 return true;
923
924                         foreach (FieldInitializer f in fields) {
925                                 f.EmitStatement (ec);
926                         }
927                         return true;
928                 }
929                 
930                 public override string DocComment {
931                         get {
932                                 return comment;
933                         }
934                         set {
935                                 if (value == null)
936                                         return;
937
938                                 comment += value;
939                         }
940                 }
941
942                 public PendingImplementation PendingImplementations {
943                         get { return pending; }
944                 }
945
946                 public override bool GetClsCompliantAttributeValue ()
947                 {
948                         if (PartialContainer != this)
949                                 return PartialContainer.GetClsCompliantAttributeValue ();
950
951                         return base.GetClsCompliantAttributeValue ();
952                 }
953
954                 public void AddBasesForPart (DeclSpace part, ArrayList bases)
955                 {
956                         // FIXME: get rid of partial_parts and store lists of bases of each part here
957                         // assumed, not verified: 'part' is in 'partial_parts' 
958                         ((TypeContainer) part).Bases = bases;
959                 }
960
961                 TypeExpr[] GetNormalBases (out TypeExpr base_class)
962                 {
963                         base_class = null;
964                         if (Bases == null)
965                                 return null;
966
967                         int count = Bases.Count;
968                         int start = 0, i, j;
969
970                         if (Kind == Kind.Class){
971                                 TypeExpr name = ((Expression) Bases [0]).ResolveAsBaseTerminal (this, false);
972
973                                 if (name == null){
974                                         return null;
975                                 }
976
977                                 if (!name.IsInterface) {
978                                         // base_class could be a class, struct, enum, delegate.
979                                         // This is validated in GetClassBases.
980                                         base_class = name;
981                                         start = 1;
982                                 }
983                         }
984
985                         TypeExpr [] ifaces = new TypeExpr [count-start];
986                         
987                         for (i = start, j = 0; i < count; i++, j++){
988                                 TypeExpr resolved = ((Expression) Bases [i]).ResolveAsBaseTerminal (this, false);
989                                 if (resolved == null) {
990                                         return null;
991                                 }
992                                 
993                                 ifaces [j] = resolved;
994                         }
995
996                         return ifaces.Length == 0 ? null : ifaces;
997                 }
998
999
1000                 TypeExpr[] GetNormalPartialBases (ref TypeExpr base_class)
1001                 {
1002                         ArrayList ifaces = new ArrayList (0);
1003                         if (iface_exprs != null)
1004                                 ifaces.AddRange (iface_exprs);
1005
1006                         foreach (TypeContainer part in partial_parts) {
1007                                 TypeExpr new_base_class;
1008                                 TypeExpr[] new_ifaces = part.GetClassBases (out new_base_class);
1009                                 if (new_base_class != TypeManager.system_object_expr) {
1010                                         if (base_class == TypeManager.system_object_expr)
1011                                                 base_class = new_base_class;
1012                                         else {
1013                                                 if (new_base_class != null && !new_base_class.Equals (base_class)) {
1014                                                         Report.SymbolRelatedToPreviousError (base_class.Location, "");
1015                                                         Report.Error (263, part.Location,
1016                                                                 "Partial declarations of `{0}' must not specify different base classes",
1017                                                                 part.GetSignatureForError ());
1018
1019                                                         return null;
1020                                                 }
1021                                         }
1022                                 }
1023
1024                                 if (new_ifaces == null)
1025                                         continue;
1026
1027                                 foreach (TypeExpr iface in new_ifaces) {
1028                                         if (ifaces.Contains (iface))
1029                                                 continue;
1030
1031                                         ifaces.Add (iface);
1032                                 }
1033                         }
1034
1035                         if (ifaces.Count == 0)
1036                                 return null;
1037
1038                         return (TypeExpr[])ifaces.ToArray (typeof (TypeExpr));
1039                 }
1040
1041                 /// <summary>
1042                 ///   This function computes the Base class and also the
1043                 ///   list of interfaces that the class or struct @c implements.
1044                 ///   
1045                 ///   The return value is an array (might be null) of
1046                 ///   interfaces implemented (as Types).
1047                 ///   
1048                 ///   The @base_class argument is set to the base object or null
1049                 ///   if this is `System.Object'. 
1050                 /// </summary>
1051                 public virtual TypeExpr [] GetClassBases (out TypeExpr base_class)
1052                 {
1053                         TypeExpr[] ifaces = GetNormalBases (out base_class);
1054
1055                         if (ifaces == null)
1056                                 return null;
1057
1058                         int count = ifaces.Length;
1059
1060                         for (int i = 0; i < count; i++) {
1061                                 TypeExpr iface = (TypeExpr) ifaces [i];
1062
1063                                 if (!iface.IsInterface) {
1064                                         if (Kind != Kind.Class) {
1065                                                 // TODO: location of symbol related ....
1066                                                 Error_TypeInListIsNotInterface (Location, iface.GetSignatureForError ());
1067                                         }
1068                                         else if (base_class != null)
1069                                                 Report.Error (1721, Location, "`{0}': Classes cannot have multiple base classes (`{1}' and `{2}')",
1070                                                         GetSignatureForError (), base_class.GetSignatureForError (), iface.GetSignatureForError ());
1071                                         else {
1072                                                 Report.Error (1722, Location, "`{0}': Base class `{1}' must be specified as first",
1073                                                         GetSignatureForError (), iface.GetSignatureForError ());
1074                                         }
1075                                         return null;
1076                                 }
1077
1078                                 for (int x = 0; x < i; x++) {
1079                                         if (iface.Equals (ifaces [x])) {
1080                                                 Report.Error (528, Location,
1081                                                               "`{0}' is already listed in " +
1082                                                               "interface list", iface.GetSignatureForError ());
1083                                                 return null;
1084                                         }
1085                                 }
1086
1087                                 if ((Kind == Kind.Interface) &&
1088                                     !iface.AsAccessible (Parent, ModFlags)) {
1089                                         Report.Error (61, Location,
1090                                                       "Inconsistent accessibility: base " +
1091                                                       "interface `{0}' is less accessible " +
1092                                                       "than interface `{1}'", iface.Name,
1093                                                       Name);
1094                                         return null;
1095                                 }
1096                         }
1097                         return ifaces;
1098                 }
1099
1100                 bool CheckGenericInterfaces (Type[] ifaces)
1101                 {
1102 #if GMCS_SOURCE
1103                         ArrayList already_checked = new ArrayList ();
1104
1105                         for (int i = 0; i < ifaces.Length; i++) {
1106                                 Type iface = ifaces [i];
1107                                 foreach (Type t in already_checked) {
1108                                         if (iface == t)
1109                                                 continue;
1110
1111                                         Type[] inferred = new Type [CountTypeParameters];
1112                                         if (!TypeManager.MayBecomeEqualGenericInstances (iface, t, inferred, null))
1113                                                 continue;
1114
1115                                         Report.Error (695, Location,
1116                                                 "`{0}' cannot implement both `{1}' and `{2}' " +
1117                                                 "because they may unify for some type parameter substitutions",
1118                                                 TypeManager.CSharpName (TypeBuilder), TypeManager.CSharpName (iface),
1119                                                 TypeManager.CSharpName (t));
1120                                         return false;
1121                                 }
1122
1123                                 already_checked.Add (iface);
1124                         }
1125 #endif
1126
1127                         return true;
1128                 }
1129
1130                 bool error = false;
1131                 
1132                 protected void Error_TypeInListIsNotInterface (Location loc, string type)
1133                 {
1134                         Report.Error (527, loc, "Type `{0}' in interface list is not an interface", type);
1135                 }
1136
1137                 bool CreateTypeBuilder ()
1138                 {
1139                         try {
1140                                 Type default_parent = null;
1141                                 if (Kind == Kind.Struct)
1142                                         default_parent = TypeManager.value_type;
1143                                 else if (Kind == Kind.Enum)
1144                                         default_parent = TypeManager.enum_type;
1145
1146                                 if (IsTopLevel){
1147                                         if (TypeManager.NamespaceClash (Name, Location)) {
1148                                                 return false;
1149                                         }
1150
1151                                         ModuleBuilder builder = CodeGen.Module.Builder;
1152                                         TypeBuilder = builder.DefineType (
1153                                                 Name, TypeAttr, default_parent, null);
1154                                 } else {
1155                                         TypeBuilder builder = Parent.TypeBuilder;
1156
1157                                         TypeBuilder = builder.DefineNestedType (
1158                                                 Basename, TypeAttr, default_parent, null);
1159                                 }
1160                         } catch (ArgumentException) {
1161                                 Report.RuntimeMissingSupport (Location, "static classes");
1162                                 return false;
1163                         }
1164
1165                         TypeManager.AddUserType (this);
1166
1167 #if GMCS_SOURCE
1168                         if (IsGeneric) {
1169                                 string[] param_names = new string [TypeParameters.Length];
1170                                 for (int i = 0; i < TypeParameters.Length; i++)
1171                                         param_names [i] = TypeParameters [i].Name;
1172
1173                                 gen_params = TypeBuilder.DefineGenericParameters (param_names);
1174
1175                                 int offset = CountTypeParameters - CurrentTypeParameters.Length;
1176                                 for (int i = offset; i < gen_params.Length; i++)
1177                                         CurrentTypeParameters [i - offset].Define (gen_params [i]);
1178                         }
1179 #endif
1180
1181                         return true;
1182                 }
1183
1184                 bool DefineBaseTypes ()
1185                 {
1186                         iface_exprs = GetClassBases (out base_type);
1187                         if (partial_parts != null) {
1188                                 iface_exprs = GetNormalPartialBases (ref base_type);
1189                         }
1190
1191                         //
1192                         // GetClassBases calls ResolveBaseTypeExpr() on the various type expressions involved,
1193                         // which in turn should have called DefineType()s on base types if necessary.
1194                         //
1195                         // None of the code below should trigger DefineType()s on classes that we depend on.
1196                         // Thus, we are eligible to be on the topological sort `type_container_resolve_order'.
1197                         //
1198                         // Let's do it as soon as possible, since code below can call DefineType() on classes
1199                         // that depend on us to be populated before they are.
1200                         //
1201                         if (!(this is CompilerGeneratedClass))
1202                                 RootContext.RegisterOrder (this); 
1203
1204                         if (IsGeneric && base_type != null && TypeManager.IsAttributeType (base_type.Type)) {
1205                                 Report.Error (698, base_type.Location,
1206                                               "A generic type cannot derive from `{0}' because it is an attribute class",
1207                                               base_type.Name);
1208                                 return false;
1209                         }
1210
1211                         if (!CheckRecursiveDefinition (this))
1212                                 return false;
1213
1214                         if (base_type != null) {
1215                                 TypeBuilder.SetParent (base_type.Type);
1216
1217                                 ObsoleteAttribute obsolete_attr = AttributeTester.GetObsoleteAttribute (base_type.Type);
1218                                 if (obsolete_attr != null && !IsInObsoleteScope)
1219                                         AttributeTester.Report_ObsoleteMessage (obsolete_attr, base_type.GetSignatureForError (), Location);
1220                         }
1221
1222                         // add interfaces that were not added at type creation
1223                         if (iface_exprs != null) {
1224                                 ifaces = TypeManager.ExpandInterfaces (iface_exprs);
1225                                 if (ifaces == null)
1226                                         return false;
1227
1228                                 foreach (Type itype in ifaces)
1229                                         TypeBuilder.AddInterfaceImplementation (itype);
1230
1231                                 foreach (TypeExpr ie in iface_exprs) {
1232                                         ObsoleteAttribute oa = AttributeTester.GetObsoleteAttribute (ie.Type);
1233                                         if ((oa != null) && !IsInObsoleteScope)
1234                                                 AttributeTester.Report_ObsoleteMessage (
1235                                                         oa, ie.GetSignatureForError (), Location);
1236                                 }
1237
1238                                 if (!CheckGenericInterfaces (ifaces))
1239                                         return false;
1240
1241                                 TypeManager.RegisterBuilder (TypeBuilder, ifaces);
1242                         }
1243
1244                         return true;
1245                 }
1246
1247                 //
1248                 // Defines the type in the appropriate ModuleBuilder or TypeBuilder.
1249                 //
1250                 public TypeBuilder CreateType ()
1251                 {
1252                         if (TypeBuilder != null)
1253                                 return TypeBuilder;
1254
1255                         if (error)
1256                                 return null;
1257
1258                         if (!CreateTypeBuilder ()) {
1259                                 error = true;
1260                                 return null;
1261                         }
1262
1263                         if (partial_parts != null) {
1264                                 foreach (TypeContainer part in partial_parts)
1265                                         part.TypeBuilder = TypeBuilder;
1266                         }
1267
1268                         if (Types != null) {
1269                                 foreach (TypeContainer tc in Types) {
1270                                         if (tc.CreateType () == null) {
1271                                                 error = true;
1272                                                 return null;
1273                                         }
1274                                 }
1275                         }
1276
1277                         return TypeBuilder;
1278                 }
1279
1280                 bool type_defined;
1281
1282                 public override TypeBuilder DefineType ()
1283                 {
1284                         if (error)
1285                                 return null;
1286                         if (type_defined)
1287                                 return TypeBuilder;
1288
1289                         type_defined = true;
1290
1291                         if (CreateType () == null) {
1292                                 error = true;
1293                                 return null;
1294                         }
1295
1296                         if (!DefineBaseTypes ()) {
1297                                 error = true;
1298                                 return null;
1299                         }
1300
1301                         if (!(this is CompilerGeneratedClass)) {
1302                                 if (!ResolveMembers ()) {
1303                                         error = true;
1304                                         return null;
1305                                 }
1306                         }
1307
1308                         if (!DefineNestedTypes ()) {
1309                                 error = true;
1310                                 return null;
1311                         }
1312
1313                         return TypeBuilder;
1314                 }
1315
1316                 public bool ResolveMembers ()
1317                 {
1318                         if (members_resolved)
1319                                 return members_resolved_ok;
1320
1321                         members_resolved_ok = DoResolveMembers ();
1322                         members_resolved = true;
1323
1324                         return members_resolved_ok;
1325                 }
1326
1327                 protected virtual bool DoResolveMembers ()
1328                 {
1329                         if (methods != null) {
1330                                 foreach (Method method in methods) {
1331                                         if (!method.ResolveMembers ())
1332                                                 return false;
1333                                 }
1334                         }
1335
1336                         if (instance_constructors != null) {
1337                                 foreach (Constructor c in instance_constructors) {
1338                                         if (!c.ResolveMembers ())
1339                                                 return false;
1340                                 }
1341                         }
1342
1343                         if (default_static_constructor != null) {
1344                                 if (!default_static_constructor.ResolveMembers ())
1345                                         return false;
1346                         }
1347
1348                         if (operators != null) {
1349                                 foreach (Operator o in operators) {
1350                                         if (!o.ResolveMembers ())
1351                                                 return false;
1352                                 }
1353                         }
1354
1355                         if (properties != null) {
1356                                 foreach (PropertyBase p in properties) {
1357                                         if (!p.Get.IsDummy && !p.Get.ResolveMembers ())
1358                                                 return false;
1359                                         if (!p.Set.IsDummy && !p.Set.ResolveMembers ())
1360                                                 return false;
1361                                 }
1362                         }
1363
1364                         if (indexers != null) {
1365                                 foreach (PropertyBase p in indexers) {
1366                                         if (!p.Get.IsDummy && !p.Get.ResolveMembers ())
1367                                                 return false;
1368                                         if (!p.Set.IsDummy && !p.Set.ResolveMembers ())
1369                                                 return false;
1370                                 }
1371                         }
1372
1373                         if (events != null) {
1374                                 foreach (Event e in events) {
1375                                         if (!e.Add.ResolveMembers ())
1376                                                 return false;
1377                                         if (!e.Remove.ResolveMembers ())
1378                                                 return false;
1379                                 }
1380                         }
1381
1382                         if (compiler_generated != null) {
1383                                 foreach (CompilerGeneratedClass c in compiler_generated) {
1384                                         if (c.DefineType () == null)
1385                                                 return false;
1386                                 }
1387                         }
1388
1389                         return true;
1390                 }
1391
1392                 Constraints [] constraints;
1393                 public override void SetParameterInfo (ArrayList constraints_list)
1394                 {
1395                         if (PartialContainer == this) {
1396                                 base.SetParameterInfo (constraints_list);
1397                                 return;
1398                         }
1399
1400                         if (constraints_list == null)
1401                                 return;
1402
1403                         constraints = new Constraints [PartialContainer.CountCurrentTypeParameters];
1404
1405                         TypeParameter[] current_params = PartialContainer.CurrentTypeParameters;
1406                         for (int i = 0; i < constraints.Length; i++) {
1407                                 foreach (Constraints constraint in constraints_list) {
1408                                         if (constraint.TypeParameter == current_params [i].Name) {
1409                                                 constraints [i] = constraint;
1410                                                 break;
1411                                         }
1412                                 }
1413                         }
1414                 }
1415
1416                 bool UpdateTypeParameterConstraints ()
1417                 {
1418                         if (constraints == null)
1419                                 return true;
1420
1421                         TypeParameter[] current_params = PartialContainer.CurrentTypeParameters;
1422                         for (int i = 0; i < current_params.Length; i++) {
1423                                 if (!current_params [i].UpdateConstraints (this, constraints [i])) {
1424                                         Report.SymbolRelatedToPreviousError (Location, "");
1425                                         Report.Error (265, PartialContainer.Location,
1426                                                 "Partial declarations of `{0}' have inconsistent constraints for type parameter `{1}'",
1427                                                 PartialContainer.GetSignatureForError (), current_params [i].Name);
1428                                         return false;
1429                                 }
1430                         }
1431
1432                         return true;
1433                 }
1434
1435                 public bool ResolveType ()
1436                 {
1437                         if (!DoResolveType ())
1438                                 return false;
1439
1440                         if (compiler_generated != null) {
1441                                 foreach (CompilerGeneratedClass c in compiler_generated)
1442                                         if (!c.ResolveType ())
1443                                                 return false;
1444                         }
1445
1446                         return true;
1447                 }
1448
1449                 protected virtual bool DoResolveType ()
1450                 {
1451                         if ((base_type != null) &&
1452                             (base_type.ResolveAsTypeTerminal (this, false) == null)) {
1453                                 error = true;
1454                                 return false;
1455                         }
1456
1457                         if (!IsGeneric)
1458                                 return true;
1459
1460                         if (PartialContainer != this)
1461                                 throw new InternalErrorException ();
1462
1463                         TypeExpr current_type = null;
1464
1465                         foreach (TypeParameter type_param in CurrentTypeParameters) {
1466                                 if (!type_param.Resolve (this)) {
1467                                         error = true;
1468                                         return false;
1469                                 }
1470                         }
1471
1472                         if (partial_parts != null) {
1473                                 foreach (TypeContainer part in partial_parts) {
1474                                         if (!part.UpdateTypeParameterConstraints ()) {
1475                                                 error = true;
1476                                                 return false;
1477                                         }
1478                                 }
1479                         }
1480
1481                         foreach (TypeParameter type_param in TypeParameters) {
1482                                 if (!type_param.DefineType (this)) {
1483                                         error = true;
1484                                         return false;
1485                                 }
1486                         }
1487
1488                         current_type = new ConstructedType (TypeBuilder, TypeParameters, Location);
1489
1490                         foreach (TypeParameter type_param in TypeParameters)
1491                                 if (!type_param.CheckDependencies ()) {
1492                                         error = true;
1493                                         return false;
1494                                 }
1495
1496                         if (current_type != null) {
1497                                 current_type = current_type.ResolveAsTypeTerminal (this, false);
1498                                 if (current_type == null) {
1499                                         error = true;
1500                                         return false;
1501                                 }
1502
1503                                 CurrentType = current_type.Type;
1504                         }
1505
1506                         return true;
1507                 }
1508
1509                 protected virtual bool DefineNestedTypes ()
1510                 {
1511                         if (Types != null) {
1512                                 foreach (TypeContainer tc in Types)
1513                                         if (tc.DefineType () == null)
1514                                                 return false;
1515                         }
1516
1517                         if (Delegates != null) {
1518                                 foreach (Delegate d in Delegates)
1519                                         if (d.DefineType () == null)
1520                                                 return false;
1521                         }
1522
1523                         return true;
1524                 }
1525
1526                 TypeContainer InTransit;
1527
1528                 protected bool CheckRecursiveDefinition (TypeContainer tc)
1529                 {
1530                         if (InTransit != null) {
1531                                 Report.SymbolRelatedToPreviousError (this);
1532                                 if (this is Interface)
1533                                         Report.Error (
1534                                                 529, tc.Location, "Inherited interface `{0}' causes a " +
1535                                                 "cycle in the interface hierarchy of `{1}'",
1536                                                 GetSignatureForError (), tc.GetSignatureForError ());
1537                                 else
1538                                         Report.Error (
1539                                                 146, tc.Location, "Circular base class dependency " +
1540                                                 "involving `{0}' and `{1}'",
1541                                                 tc.GetSignatureForError (), GetSignatureForError ());
1542                                 return false;
1543                         }
1544
1545                         InTransit = tc;
1546
1547                         if (base_type != null) {
1548                                 Type t = TypeManager.DropGenericTypeArguments (base_type.Type);
1549                                 TypeContainer ptc = TypeManager.LookupTypeContainer (t);
1550                                 if ((ptc != null) && !ptc.CheckRecursiveDefinition (this))
1551                                         return false;
1552                         }
1553
1554                         if (iface_exprs != null) {
1555                                 foreach (TypeExpr iface in iface_exprs) {
1556                                         Type itype = TypeManager.DropGenericTypeArguments (iface.Type);
1557                                         TypeContainer ptc = TypeManager.LookupTypeContainer (itype);
1558                                         if ((ptc != null) && !ptc.CheckRecursiveDefinition (this))
1559                                                 return false;
1560                                 }
1561                         }
1562
1563                         if (!IsTopLevel && !Parent.PartialContainer.CheckRecursiveDefinition (this))
1564                                 return false;
1565
1566                         InTransit = null;
1567                         return true;
1568                 }
1569
1570                 public static void Error_KeywordNotAllowed (Location loc)
1571                 {
1572                         Report.Error (1530, loc, "Keyword `new' is not allowed on namespace elements");
1573                 }
1574
1575                 /// <summary>
1576                 ///   Populates our TypeBuilder with fields and methods
1577                 /// </summary>
1578                 public override bool DefineMembers ()
1579                 {
1580                         if (members_defined)
1581                                 return members_defined_ok;
1582
1583                         if (!base.DefineMembers ())
1584                                 return false;
1585
1586                         members_defined_ok = DoDefineMembers ();
1587                         members_defined = true;
1588
1589                         return members_defined_ok;
1590                 }
1591
1592                 protected virtual bool DoDefineMembers ()
1593                 {
1594                         if (iface_exprs != null) {
1595                                 foreach (TypeExpr iface in iface_exprs) {
1596                                         ConstructedType ct = iface as ConstructedType;
1597                                         if ((ct != null) && !ct.CheckConstraints (this))
1598                                                 return false;
1599                                 }
1600                         }
1601
1602                         if (base_type != null) {
1603                                 ConstructedType ct = base_type as ConstructedType;
1604                                 if ((ct != null) && !ct.CheckConstraints (this))
1605                                         return false;
1606                         }
1607
1608                         if (!IsTopLevel) {
1609                                 MemberInfo conflict_symbol = Parent.PartialContainer.FindBaseMemberWithSameName (Basename, false);
1610                                 if (conflict_symbol == null) {
1611                                         if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0))
1612                                                 Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
1613                                 } else {
1614                                         if ((ModFlags & Modifiers.NEW) == 0) {
1615                                                 Report.SymbolRelatedToPreviousError (conflict_symbol);
1616                                                 Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
1617                                                         GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
1618                                         }
1619                                 }
1620                         }
1621
1622                         DefineContainerMembers (constants);
1623                         DefineContainerMembers (fields);
1624
1625                         if (Kind == Kind.Struct || Kind == Kind.Class) {
1626                                 pending = PendingImplementation.GetPendingImplementations (this);
1627                         }
1628                 
1629                         //
1630                         // Constructors are not in the defined_names array
1631                         //
1632                         DefineContainerMembers (instance_constructors);
1633                 
1634                         DefineContainerMembers (properties);
1635                         DefineContainerMembers (events);
1636                         DefineContainerMembers (indexers);
1637                         DefineContainerMembers (methods);
1638                         DefineContainerMembers (operators);
1639                         DefineContainerMembers (delegates);
1640
1641                         if (CurrentType != null) {
1642                                 GenericType = CurrentType;
1643                         }
1644
1645 #if CACHE
1646                         member_cache = new MemberCache (this);
1647                         if (partial_parts != null) {
1648                                 foreach (TypeContainer part in partial_parts)
1649                                         part.member_cache = member_cache;
1650                         }
1651 #endif
1652
1653                         return true;
1654                 }
1655
1656                 protected virtual void DefineContainerMembers (MemberCoreArrayList mcal)
1657                 {
1658                         if (mcal != null)
1659                                 mcal.DefineContainerMembers ();
1660                 }
1661
1662                 public override bool Define ()
1663                 {
1664                         if (compiler_generated != null) {
1665                                 foreach (CompilerGeneratedClass c in compiler_generated) {
1666                                         if (!c.Define ())
1667                                                 return false;
1668                                 }
1669                         }
1670
1671                         return true;
1672                 }
1673
1674                 public MemberInfo FindBaseMemberWithSameName (string name, bool ignore_methods)
1675                 {
1676                         return BaseCache == null ? null : BaseCache.FindMemberWithSameName (name, ignore_methods, null);
1677                 }
1678
1679                 /// <summary>
1680                 ///   This function is based by a delegate to the FindMembers routine
1681                 /// </summary>
1682                 static bool AlwaysAccept (MemberInfo m, object filterCriteria)
1683                 {
1684                         return true;
1685                 }
1686
1687                 /// <summary>
1688                 ///   This filter is used by FindMembers, and we just keep
1689                 ///   a global for the filter to `AlwaysAccept'
1690                 /// </summary>
1691                 static MemberFilter accepting_filter;
1692
1693                 
1694                 static TypeContainer ()
1695                 {
1696                         accepting_filter = new MemberFilter (AlwaysAccept);
1697                 }
1698
1699                 public MethodInfo[] GetMethods ()
1700                 {
1701                         ArrayList members = new ArrayList ();
1702
1703                         DefineMembers ();
1704
1705                         if (methods != null) {
1706                                 int len = methods.Count;
1707                                 for (int i = 0; i < len; i++) {
1708                                         Method m = (Method) methods [i];
1709
1710                                         members.Add (m.MethodBuilder);
1711                                 }
1712                         }
1713
1714                         if (operators != null) {
1715                                 int len = operators.Count;
1716                                 for (int i = 0; i < len; i++) {
1717                                         Operator o = (Operator) operators [i];
1718
1719                                         members.Add (o.MethodBuilder);
1720                                 }
1721                         }
1722
1723                         if (properties != null) {
1724                                 int len = properties.Count;
1725                                 for (int i = 0; i < len; i++) {
1726                                         Property p = (Property) properties [i];
1727
1728                                         if (p.GetBuilder != null)
1729                                                 members.Add (p.GetBuilder);
1730                                         if (p.SetBuilder != null)
1731                                                 members.Add (p.SetBuilder);
1732                                 }
1733                         }
1734                                 
1735                         if (indexers != null) {
1736                                 int len = indexers.Count;
1737                                 for (int i = 0; i < len; i++) {
1738                                         Indexer ix = (Indexer) indexers [i];
1739
1740                                         if (ix.GetBuilder != null)
1741                                                 members.Add (ix.GetBuilder);
1742                                         if (ix.SetBuilder != null)
1743                                                 members.Add (ix.SetBuilder);
1744                                 }
1745                         }
1746
1747                         if (events != null) {
1748                                 int len = events.Count;
1749                                 for (int i = 0; i < len; i++) {
1750                                         Event e = (Event) events [i];
1751
1752                                         if (e.AddBuilder != null)
1753                                                 members.Add (e.AddBuilder);
1754                                         if (e.RemoveBuilder != null)
1755                                                 members.Add (e.RemoveBuilder);
1756                                 }
1757                         }
1758
1759                         MethodInfo[] retMethods = new MethodInfo [members.Count];
1760                         members.CopyTo (retMethods, 0);
1761                         return retMethods;
1762                 }
1763                 
1764                 // Indicated whether container has StructLayout attribute set Explicit
1765                 public bool HasExplicitLayout {
1766                         get { return (caching_flags & Flags.HasExplicitLayout) != 0; }
1767                         set { caching_flags |= Flags.HasExplicitLayout; }
1768                 }
1769
1770                 //
1771                 // Return the nested type with name @name.  Ensures that the nested type
1772                 // is defined if necessary.  Do _not_ use this when you have a MemberCache handy.
1773                 //
1774                 public Type FindNestedType (string name)
1775                 {
1776                         if (PartialContainer != this)
1777                                 throw new InternalErrorException ("should not happen");
1778
1779                         ArrayList [] lists = { types, delegates };
1780
1781                         for (int j = 0; j < lists.Length; ++j) {
1782                                 ArrayList list = lists [j];
1783                                 if (list == null)
1784                                         continue;
1785                                 
1786                                 int len = list.Count;
1787                                 for (int i = 0; i < len; ++i) {
1788                                         DeclSpace ds = (DeclSpace) list [i];
1789                                         if (ds.Basename == name) {
1790                                                 return ds.DefineType ();
1791                                         }
1792                                 }
1793                         }
1794
1795                         return null;
1796                 }
1797
1798                 private void FindMembers_NestedTypes (int modflags,
1799                                                       BindingFlags bf, MemberFilter filter, object criteria,
1800                                                       ref ArrayList members)
1801                 {
1802                         ArrayList [] lists = { types, delegates };
1803
1804                         for (int j = 0; j < lists.Length; ++j) {
1805                                 ArrayList list = lists [j];
1806                                 if (list == null)
1807                                         continue;
1808                         
1809                                 int len = list.Count;
1810                                 for (int i = 0; i < len; i++) {
1811                                         DeclSpace ds = (DeclSpace) list [i];
1812                                         
1813                                         if ((ds.ModFlags & modflags) == 0)
1814                                                 continue;
1815                                         
1816                                         TypeBuilder tb = ds.TypeBuilder;
1817                                         if (tb == null) {
1818                                                 if (!(criteria is string) || ds.Basename.Equals (criteria))
1819                                                         tb = ds.DefineType ();
1820                                         }
1821                                         
1822                                         if (tb != null && (filter (tb, criteria) == true)) {
1823                                                 if (members == null)
1824                                                         members = new ArrayList ();
1825                                                 
1826                                                 members.Add (tb);
1827                                         }
1828                                 }
1829                         }
1830                 }
1831                 
1832                 /// <summary>
1833                 ///   This method returns the members of this type just like Type.FindMembers would
1834                 ///   Only, we need to use this for types which are _being_ defined because MS' 
1835                 ///   implementation can't take care of that.
1836                 /// </summary>
1837                 //
1838                 // FIXME: return an empty static array instead of null, that cleans up
1839                 // some code and is consistent with some coding conventions I just found
1840                 // out existed ;-)
1841                 //
1842                 //
1843                 // Notice that in various cases we check if our field is non-null,
1844                 // something that would normally mean that there was a bug elsewhere.
1845                 //
1846                 // The problem happens while we are defining p-invoke methods, as those
1847                 // will trigger a FindMembers, but this happens before things are defined
1848                 //
1849                 // Since the whole process is a no-op, it is fine to check for null here.
1850                 //
1851                 public override MemberList FindMembers (MemberTypes mt, BindingFlags bf,
1852                                                         MemberFilter filter, object criteria)
1853                 {
1854                         ArrayList members = null;
1855
1856                         int modflags = 0;
1857                         if ((bf & BindingFlags.Public) != 0)
1858                                 modflags |= Modifiers.PUBLIC | Modifiers.PROTECTED |
1859                                         Modifiers.INTERNAL;
1860                         if ((bf & BindingFlags.NonPublic) != 0)
1861                                 modflags |= Modifiers.PRIVATE;
1862
1863                         int static_mask = 0, static_flags = 0;
1864                         switch (bf & (BindingFlags.Static | BindingFlags.Instance)) {
1865                         case BindingFlags.Static:
1866                                 static_mask = static_flags = Modifiers.STATIC;
1867                                 break;
1868
1869                         case BindingFlags.Instance:
1870                                 static_mask = Modifiers.STATIC;
1871                                 static_flags = 0;
1872                                 break;
1873
1874                         default:
1875                                 static_mask = static_flags = 0;
1876                                 break;
1877                         }
1878
1879                         Timer.StartTimer (TimerType.TcFindMembers);
1880
1881                         if (filter == null)
1882                                 filter = accepting_filter; 
1883
1884                         if ((mt & MemberTypes.Field) != 0) {
1885                                 if (fields != null) {
1886                                         int len = fields.Count;
1887                                         for (int i = 0; i < len; i++) {
1888                                                 FieldBase f = (FieldBase) fields [i];
1889                                                 
1890                                                 if ((f.ModFlags & modflags) == 0)
1891                                                         continue;
1892                                                 if ((f.ModFlags & static_mask) != static_flags)
1893                                                         continue;
1894
1895                                                 FieldBuilder fb = f.FieldBuilder;
1896                                                 if (fb != null && filter (fb, criteria) == true) {
1897                                                         if (members == null)
1898                                                                 members = new ArrayList ();
1899                                                         
1900                                                         members.Add (fb);
1901                                                 }
1902                                         }
1903                                 }
1904
1905                                 if (constants != null) {
1906                                         int len = constants.Count;
1907                                         for (int i = 0; i < len; i++) {
1908                                                 Const con = (Const) constants [i];
1909                                                 
1910                                                 if ((con.ModFlags & modflags) == 0)
1911                                                         continue;
1912                                                 if ((con.ModFlags & static_mask) != static_flags)
1913                                                         continue;
1914
1915                                                 FieldBuilder fb = con.FieldBuilder;
1916                                                 if (fb == null) {
1917                                                         if (con.Define ())
1918                                                                 fb = con.FieldBuilder;
1919                                                 }
1920                                                 if (fb != null && filter (fb, criteria) == true) {
1921                                                         if (members == null)
1922                                                                 members = new ArrayList ();
1923                                                         
1924                                                         members.Add (fb);
1925                                                 }
1926                                         }
1927                                 }
1928                         }
1929
1930                         if ((mt & MemberTypes.Method) != 0) {
1931                                 if (methods != null) {
1932                                         int len = methods.Count;
1933                                         for (int i = 0; i < len; i++) {
1934                                                 Method m = (Method) methods [i];
1935                                                 
1936                                                 if ((m.ModFlags & modflags) == 0)
1937                                                         continue;
1938                                                 if ((m.ModFlags & static_mask) != static_flags)
1939                                                         continue;
1940                                                 
1941                                                 MethodBuilder mb = m.MethodBuilder;
1942
1943                                                 if (mb != null && filter (mb, criteria) == true) {
1944                                                         if (members == null)
1945                                                                 members = new ArrayList ();
1946                                                         
1947                                                         members.Add (mb);
1948                                                 }
1949                                         }
1950                                 }
1951
1952                                 if (operators != null) {
1953                                         int len = operators.Count;
1954                                         for (int i = 0; i < len; i++) {
1955                                                 Operator o = (Operator) operators [i];
1956                                                 
1957                                                 if ((o.ModFlags & modflags) == 0)
1958                                                         continue;
1959                                                 if ((o.ModFlags & static_mask) != static_flags)
1960                                                         continue;
1961                                                 
1962                                                 MethodBuilder ob = o.MethodBuilder;
1963                                                 if (ob != null && filter (ob, criteria) == true) {
1964                                                         if (members == null)
1965                                                                 members = new ArrayList ();
1966                                                         
1967                                                         members.Add (ob);
1968                                                 }
1969                                         }
1970                                 }
1971
1972                                 if (events != null) {
1973                                         foreach (Event e in events) {
1974                                                 if ((e.ModFlags & modflags) == 0)
1975                                                         continue;
1976                                                 if ((e.ModFlags & static_mask) != static_flags)
1977                                                         continue;
1978
1979                                                 MethodBuilder b = e.AddBuilder;
1980                                                 if (b != null && filter (b, criteria)) {
1981                                                         if (members == null)
1982                                                                 members = new ArrayList (4);
1983
1984                                                         members.Add (b);
1985                                                 }
1986
1987                                                 b = e.RemoveBuilder;
1988                                                 if (b != null && filter (b, criteria)) {
1989                                                         if (members == null) 
1990                                                                 members = new ArrayList (4);
1991
1992                                                         members.Add (b);
1993                                                 }
1994                                         }
1995                                 }
1996
1997                                 if (properties != null) {
1998                                         int len = properties.Count;
1999                                         for (int i = 0; i < len; i++) {
2000                                                 Property p = (Property) properties [i];
2001                                                 
2002                                                 if ((p.ModFlags & modflags) == 0)
2003                                                         continue;
2004                                                 if ((p.ModFlags & static_mask) != static_flags)
2005                                                         continue;
2006                                                 
2007                                                 MethodBuilder b;
2008
2009                                                 b = p.GetBuilder;
2010                                                 if (b != null && filter (b, criteria) == true) {
2011                                                         if (members == null)
2012                                                                 members = new ArrayList ();
2013                                                         
2014                                                         members.Add (b);
2015                                                 }
2016
2017                                                 b = p.SetBuilder;
2018                                                 if (b != null && filter (b, criteria) == true) {
2019                                                         if (members == null)
2020                                                                 members = new ArrayList ();
2021                                                         
2022                                                         members.Add (b);
2023                                                 }
2024                                         }
2025                                 }
2026                                 
2027                                 if (indexers != null) {
2028                                         int len = indexers.Count;
2029                                         for (int i = 0; i < len; i++) {
2030                                                 Indexer ix = (Indexer) indexers [i];
2031                                                 
2032                                                 if ((ix.ModFlags & modflags) == 0)
2033                                                         continue;
2034                                                 if ((ix.ModFlags & static_mask) != static_flags)
2035                                                         continue;
2036                                                 
2037                                                 MethodBuilder b;
2038
2039                                                 b = ix.GetBuilder;
2040                                                 if (b != null && filter (b, criteria) == true) {
2041                                                         if (members == null)
2042                                                                 members = new ArrayList ();
2043                                                         
2044                                                         members.Add (b);
2045                                                 }
2046
2047                                                 b = ix.SetBuilder;
2048                                                 if (b != null && filter (b, criteria) == true) {
2049                                                         if (members == null)
2050                                                                 members = new ArrayList ();
2051                                                         
2052                                                         members.Add (b);
2053                                                 }
2054                                         }
2055                                 }
2056                         }
2057
2058                         if ((mt & MemberTypes.Event) != 0) {
2059                                 if (events != null) {
2060                                         int len = events.Count;
2061                                         for (int i = 0; i < len; i++) {
2062                                                 Event e = (Event) events [i];
2063                                                 
2064                                                 if ((e.ModFlags & modflags) == 0)
2065                                                         continue;
2066                                                 if ((e.ModFlags & static_mask) != static_flags)
2067                                                         continue;
2068
2069                                                 MemberInfo eb = e.EventBuilder;
2070                                                 if (eb != null && filter (eb, criteria) == true) {
2071                                                         if (members == null)
2072                                                                 members = new ArrayList ();
2073                                                         
2074                                                         members.Add (e.EventBuilder);
2075                                                 }
2076                                         }
2077                                 }
2078                         }
2079                         
2080                         if ((mt & MemberTypes.Property) != 0){
2081                                 if (properties != null) {
2082                                         int len = properties.Count;
2083                                         for (int i = 0; i < len; i++) {
2084                                                 Property p = (Property) properties [i];
2085                                                 
2086                                                 if ((p.ModFlags & modflags) == 0)
2087                                                         continue;
2088                                                 if ((p.ModFlags & static_mask) != static_flags)
2089                                                         continue;
2090
2091                                                 MemberInfo pb = p.PropertyBuilder;
2092                                                 if (pb != null && filter (pb, criteria) == true) {
2093                                                         if (members == null)
2094                                                                 members = new ArrayList ();
2095                                                         
2096                                                         members.Add (p.PropertyBuilder);
2097                                                 }
2098                                         }
2099                                 }
2100
2101                                 if (indexers != null) {
2102                                         int len = indexers.Count;
2103                                         for (int i = 0; i < len; i++) {
2104                                                 Indexer ix = (Indexer) indexers [i];
2105                                                 
2106                                                 if ((ix.ModFlags & modflags) == 0)
2107                                                         continue;
2108                                                 if ((ix.ModFlags & static_mask) != static_flags)
2109                                                         continue;
2110
2111                                                 MemberInfo ib = ix.PropertyBuilder;
2112                                                 if (ib != null && filter (ib, criteria) == true) {
2113                                                         if (members == null)
2114                                                                 members = new ArrayList ();
2115                                                         
2116                                                         members.Add (ix.PropertyBuilder);
2117                                                 }
2118                                         }
2119                                 }
2120                         }
2121                         
2122                         if ((mt & MemberTypes.NestedType) != 0)
2123                                 FindMembers_NestedTypes (modflags, bf, filter, criteria, ref members);
2124
2125                         if ((mt & MemberTypes.Constructor) != 0){
2126                                 if (((bf & BindingFlags.Instance) != 0) && (instance_constructors != null)){
2127                                         int len = instance_constructors.Count;
2128                                         for (int i = 0; i < len; i++) {
2129                                                 Constructor c = (Constructor) instance_constructors [i];
2130                                                 
2131                                                 ConstructorBuilder cb = c.ConstructorBuilder;
2132                                                 if (cb != null && filter (cb, criteria) == true) {
2133                                                         if (members == null)
2134                                                                 members = new ArrayList ();
2135                                                         
2136                                                         members.Add (cb);
2137                                                 }
2138                                         }
2139                                 }
2140
2141                                 if (((bf & BindingFlags.Static) != 0) && (default_static_constructor != null)){
2142                                         ConstructorBuilder cb =
2143                                                 default_static_constructor.ConstructorBuilder;
2144                                         
2145                                         if (cb != null && filter (cb, criteria) == true) {
2146                                                 if (members == null)
2147                                                         members = new ArrayList ();
2148                                                 
2149                                                 members.Add (cb);
2150                                         }
2151                                 }
2152                         }
2153
2154                         //
2155                         // Lookup members in base if requested.
2156                         //
2157                         if ((bf & BindingFlags.DeclaredOnly) == 0) {
2158                                 if (TypeBuilder.BaseType != null) {
2159                                         MemberList list = FindMembers (TypeBuilder.BaseType, mt, bf, filter, criteria);
2160                                         if (list.Count > 0) {
2161                                                 if (members == null)
2162                                                         members = new ArrayList ();
2163                                         
2164                                                 members.AddRange (list);
2165                                         }
2166                                 }
2167                         }
2168
2169                         Timer.StopTimer (TimerType.TcFindMembers);
2170
2171                         if (members == null)
2172                                 return MemberList.Empty;
2173                         else
2174                                 return new MemberList (members);
2175                 }
2176
2177                 public override MemberCache MemberCache {
2178                         get {
2179                                 return member_cache;
2180                         }
2181                 }
2182
2183                 public static MemberList FindMembers (Type t, MemberTypes mt, BindingFlags bf,
2184                                                       MemberFilter filter, object criteria)
2185                 {
2186                         DeclSpace ds = TypeManager.LookupDeclSpace (t);
2187
2188                         if (ds != null)
2189                                 return ds.FindMembers (mt, bf, filter, criteria);
2190                         else
2191                                 return new MemberList (t.FindMembers (mt, bf, filter, criteria));
2192                 }
2193
2194                 /// <summary>
2195                 ///   Emits the values for the constants
2196                 /// </summary>
2197                 public void EmitConstants ()
2198                 {
2199                         if (constants != null)
2200                                 foreach (Const con in constants)
2201                                         con.Emit ();
2202                         return;
2203                 }
2204
2205                 static void CheckMemberUsage (MemberCoreArrayList al, string member_type)
2206                 {
2207                         if (al == null)
2208                                 return;
2209
2210                         foreach (MemberCore mc in al) {
2211                                 if ((mc.ModFlags & Modifiers.Accessibility) != Modifiers.PRIVATE)
2212                                         continue;
2213
2214                                 if (!mc.IsUsed) {
2215                                         Report.Warning (169, 3, mc.Location, "The private {0} `{1}' is never used", member_type, mc.GetSignatureForError ());
2216                                 }
2217                         }
2218                 }
2219
2220                 public virtual void VerifyMembers ()
2221                 {
2222                         //
2223                         // Check for internal or private fields that were never assigned
2224                         //
2225                         if (RootContext.WarningLevel >= 3) {
2226                                 CheckMemberUsage (properties, "property");
2227                                 CheckMemberUsage (methods, "method");
2228                                 CheckMemberUsage (constants, "constant");
2229
2230                                 if (fields != null){
2231                                         foreach (FieldBase f in fields) {
2232                                                 if ((f.ModFlags & Modifiers.Accessibility) != Modifiers.PRIVATE)
2233                                                         continue;
2234                                                 
2235                                                 if (!f.IsUsed){
2236                                                         if ((f.caching_flags & Flags.IsAssigned) == 0)
2237                                                                 Report.Warning (169, 3, f.Location, "The private field `{0}' is never used", f.GetSignatureForError ());
2238                                                         else {
2239 #if NET_2_0
2240                                                                 const int error_code = 414;
2241 #else
2242                                                                 const int error_code = 169;
2243 #endif
2244                                                                 Report.Warning (error_code, 3, f.Location, "The private field `{0}' is assigned but its value is never used",
2245                                                                         f.GetSignatureForError ());
2246                                                         }
2247                                                         continue;
2248                                                 }
2249                                                 
2250                                                 //
2251                                                 // Only report 649 on level 4
2252                                                 //
2253                                                 if (RootContext.WarningLevel < 4)
2254                                                         continue;
2255                                                 
2256                                                 if ((f.caching_flags & Flags.IsAssigned) != 0)
2257                                                         continue;
2258                                                 
2259                                                 Constant c = New.Constantify (f.Type.Type);
2260                                                 Report.Warning (649, 4, f.Location, "Field `{0}' is never assigned to, and will always have its default value `{1}'",
2261                                                         f.GetSignatureForError (), c == null ? "null" : c.AsString ());
2262                                         }
2263                                 }
2264                         }
2265                 }
2266
2267                 // TODO: move to ClassOrStruct
2268                 void EmitConstructors ()
2269                 {
2270                         if (instance_constructors == null)
2271                                 return;
2272
2273                         if (TypeBuilder.IsSubclassOf (TypeManager.attribute_type) && RootContext.VerifyClsCompliance && IsClsComplianceRequired ()) {
2274                                 bool has_compliant_args = false;
2275
2276                                 foreach (Constructor c in instance_constructors) {
2277                                         try {
2278                                                 c.Emit ();
2279                                         }
2280                                         catch (Exception e) {
2281                                                 throw new InternalErrorException (c, e);
2282                                         }
2283
2284                                         if (has_compliant_args)
2285                                                 continue;
2286
2287                                         has_compliant_args = c.HasCompliantArgs;
2288                                 }
2289                                 if (!has_compliant_args)
2290                                         Report.Error (3015, Location, "`{0}' has no accessible constructors which use only CLS-compliant types", GetSignatureForError ());
2291                         } else {
2292                                 foreach (Constructor c in instance_constructors) {
2293                                         try {
2294                                                 c.Emit ();
2295                                         }
2296                                         catch (Exception e) {
2297                                                 throw new InternalErrorException (c, e);
2298                                         }
2299                                 }
2300                         }
2301                 }
2302
2303                 /// <summary>
2304                 ///   Emits the code, this step is performed after all
2305                 ///   the types, enumerations, constructors
2306                 /// </summary>
2307                 public virtual void EmitType ()
2308                 {
2309                         if (OptAttributes != null)
2310                                 OptAttributes.Emit ();
2311
2312 #if GMCS_SOURCE
2313                         if (IsGeneric) {
2314                                 int offset = CountTypeParameters - CurrentTypeParameters.Length;
2315                                 for (int i = offset; i < gen_params.Length; i++)
2316                                         CurrentTypeParameters [i - offset].EmitAttributes ();
2317                         }
2318 #endif
2319
2320                         //
2321                         // Structs with no fields need to have at least one byte.
2322                         // The right thing would be to set the PackingSize in a DefineType
2323                         // but there are no functions that allow interfaces *and* the size to
2324                         // be specified.
2325                         //
2326
2327                         if (Kind == Kind.Struct && first_nonstatic_field == null){
2328                                 FieldBuilder fb = TypeBuilder.DefineField ("$PRIVATE$", TypeManager.byte_type,
2329                                                                            FieldAttributes.Private);
2330
2331                                 if (HasExplicitLayout){
2332                                         object [] ctor_args = new object [1];
2333                                         ctor_args [0] = 0;
2334                                 
2335                                         CustomAttributeBuilder cba = new CustomAttributeBuilder (
2336                                                 TypeManager.field_offset_attribute_ctor, ctor_args);
2337                                         fb.SetCustomAttribute (cba);
2338                                 }
2339                         }
2340
2341                         Emit ();
2342
2343                         EmitConstructors ();
2344
2345                         // Can not continue if constants are broken
2346                         EmitConstants ();
2347                         if (Report.Errors > 0)
2348                                 return;
2349
2350                         if (default_static_constructor != null)
2351                                 default_static_constructor.Emit ();
2352                         
2353                         if (methods != null){
2354                                 foreach (Method m in methods)
2355                                         m.Emit ();
2356                         }
2357
2358                         if (operators != null)
2359                                 foreach (Operator o in operators)
2360                                         o.Emit ();
2361
2362                         if (properties != null)
2363                                 foreach (Property p in properties)
2364                                         p.Emit ();
2365
2366                         if (indexers != null){
2367                                 indexers.Emit ();
2368                         }
2369                         
2370                         if (fields != null)
2371                                 foreach (FieldBase f in fields)
2372                                         f.Emit ();
2373
2374                         if (events != null){
2375                                 foreach (Event e in Events)
2376                                         e.Emit ();
2377                         }
2378
2379                         if (delegates != null) {
2380                                 foreach (Delegate d in Delegates) {
2381                                         d.Emit ();
2382                                 }
2383                         }
2384
2385                         if (pending != null)
2386                                 if (pending.VerifyPendingMethods ())
2387                                         return;
2388
2389                         if (Report.Errors > 0)
2390                                 return;
2391
2392                         if (compiler_generated != null) {
2393                                 foreach (CompilerGeneratedClass c in compiler_generated) {
2394                                         if (!c.DefineMembers ())
2395                                                 throw new InternalErrorException ();
2396                                 }
2397                                 foreach (CompilerGeneratedClass c in compiler_generated)
2398                                         c.EmitType ();
2399                         }
2400                 }
2401                 
2402                 public override void CloseType ()
2403                 {
2404                         if ((caching_flags & Flags.CloseTypeCreated) != 0)
2405                                 return;
2406
2407                         try {
2408                                 caching_flags |= Flags.CloseTypeCreated;
2409                                 TypeBuilder.CreateType ();
2410                         } catch (TypeLoadException){
2411                                 //
2412                                 // This is fine, the code still created the type
2413                                 //
2414 //                              Report.Warning (-20, "Exception while creating class: " + TypeBuilder.Name);
2415 //                              Console.WriteLine (e.Message);
2416                         } catch (Exception e) {
2417                                 throw new InternalErrorException (this, e);
2418                         }
2419                         
2420                         if (Types != null){
2421                                 foreach (TypeContainer tc in Types)
2422                                         if (tc.Kind == Kind.Struct)
2423                                                 tc.CloseType ();
2424
2425                                 foreach (TypeContainer tc in Types)
2426                                         if (tc.Kind != Kind.Struct)
2427                                                 tc.CloseType ();
2428                         }
2429
2430                         if (Delegates != null)
2431                                 foreach (Delegate d in Delegates)
2432                                         d.CloseType ();
2433
2434                         if (CompilerGenerated != null)
2435                                 foreach (CompilerGeneratedClass c in CompilerGenerated)
2436                                         c.CloseType ();
2437                         
2438                         types = null;
2439                         properties = null;
2440                         delegates = null;
2441                         fields = null;
2442                         initialized_fields = null;
2443                         initialized_static_fields = null;
2444                         constants = null;
2445                         methods = null;
2446                         events = null;
2447                         indexers = null;
2448                         operators = null;
2449                         compiler_generated = null;
2450                         default_constructor = null;
2451                         default_static_constructor = null;
2452                         type_bases = null;
2453                         OptAttributes = null;
2454                         ifaces = null;
2455                         base_cache = null;
2456                         member_cache = null;
2457                 }
2458
2459                 //
2460                 // Performs the validation on a Method's modifiers (properties have
2461                 // the same properties).
2462                 //
2463                 public bool MethodModifiersValid (MemberCore mc)
2464                 {
2465                         const int vao = (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE);
2466                         const int va = (Modifiers.VIRTUAL | Modifiers.ABSTRACT);
2467                         const int nv = (Modifiers.NEW | Modifiers.VIRTUAL);
2468                         bool ok = true;
2469                         int flags = mc.ModFlags;
2470                         
2471                         //
2472                         // At most one of static, virtual or override
2473                         //
2474                         if ((flags & Modifiers.STATIC) != 0){
2475                                 if ((flags & vao) != 0){
2476                                         Report.Error (112, mc.Location, "A static member `{0}' cannot be marked as override, virtual or abstract",
2477                                                 mc.GetSignatureForError ());
2478                                         ok = false;
2479                                 }
2480                         }
2481
2482                         if (Kind == Kind.Struct){
2483                                 if ((flags & va) != 0){
2484                                         Modifiers.Error_InvalidModifier (mc.Location, "virtual or abstract");
2485                                         ok = false;
2486                                 }
2487                         }
2488
2489                         if ((flags & Modifiers.OVERRIDE) != 0 && (flags & nv) != 0){
2490                                 Report.Error (113, mc.Location, "A member `{0}' marked as override cannot be marked as new or virtual",
2491                                         mc.GetSignatureForError ());
2492                                 ok = false;
2493                         }
2494
2495                         //
2496                         // If the declaration includes the abstract modifier, then the
2497                         // declaration does not include static, virtual or extern
2498                         //
2499                         if ((flags & Modifiers.ABSTRACT) != 0){
2500                                 if ((flags & Modifiers.EXTERN) != 0){
2501                                         Report.Error (
2502                                                 180, mc.Location, "`{0}' cannot be both extern and abstract", mc.GetSignatureForError ());
2503                                         ok = false;
2504                                 }
2505
2506                                 if ((flags & Modifiers.SEALED) != 0) {
2507                                         Report.Error (502, mc.Location, "`{0}' cannot be both abstract and sealed", mc.GetSignatureForError ());
2508                                         ok = false;
2509                                 }
2510
2511                                 if ((flags & Modifiers.VIRTUAL) != 0){
2512                                         Report.Error (503, mc.Location, "The abstract method `{0}' cannot be marked virtual", mc.GetSignatureForError ());
2513                                         ok = false;
2514                                 }
2515
2516                                 if ((ModFlags & Modifiers.ABSTRACT) == 0){
2517                                         Report.SymbolRelatedToPreviousError (this);
2518                                         Report.Error (513, mc.Location, "`{0}' is abstract but it is declared in the non-abstract class `{1}'",
2519                                                 mc.GetSignatureForError (), GetSignatureForError ());
2520                                         ok = false;
2521                                 }
2522                         }
2523
2524                         if ((flags & Modifiers.PRIVATE) != 0){
2525                                 if ((flags & vao) != 0){
2526                                         Report.Error (621, mc.Location, "`{0}': virtual or abstract members cannot be private", mc.GetSignatureForError ());
2527                                         ok = false;
2528                                 }
2529                         }
2530
2531                         if ((flags & Modifiers.SEALED) != 0){
2532                                 if ((flags & Modifiers.OVERRIDE) == 0){
2533                                         Report.Error (238, mc.Location, "`{0}' cannot be sealed because it is not an override", mc.GetSignatureForError ());
2534                                         ok = false;
2535                                 }
2536                         }
2537
2538                         return ok;
2539                 }
2540
2541                 public Constructor DefaultStaticConstructor {
2542                         get { return default_static_constructor; }
2543                 }
2544
2545                 protected override bool VerifyClsCompliance ()
2546                 {
2547                         if (!base.VerifyClsCompliance ())
2548                                 return false;
2549
2550                         VerifyClsName ();
2551
2552                         Type base_type = TypeBuilder.BaseType;
2553                         if (base_type != null && !AttributeTester.IsClsCompliant (base_type)) {
2554                                 Report.Error (3009, Location, "`{0}': base type `{1}' is not CLS-compliant", GetSignatureForError (), TypeManager.CSharpName (base_type));
2555                         }
2556                         return true;
2557                 }
2558
2559
2560                 /// <summary>
2561                 /// Checks whether container name is CLS Compliant
2562                 /// </summary>
2563                 void VerifyClsName ()
2564                 {
2565                         Hashtable base_members = base_cache == null ? 
2566                                 new Hashtable () :
2567                                 base_cache.GetPublicMembers ();
2568                         Hashtable this_members = new Hashtable ();
2569
2570                         foreach (DictionaryEntry entry in defined_names) {
2571                                 MemberCore mc = (MemberCore)entry.Value;
2572                                 if (!mc.IsClsComplianceRequired ())
2573                                         continue;
2574
2575                                 string name = (string) entry.Key;
2576                                 string basename = name.Substring (name.LastIndexOf ('.') + 1);
2577
2578                                 string lcase = basename.ToLower (System.Globalization.CultureInfo.InvariantCulture);
2579                                 object found = base_members [lcase];
2580                                 if (found == null) {
2581                                         found = this_members [lcase];
2582                                         if (found == null) {
2583                                                 this_members.Add (lcase, mc);
2584                                                 continue;
2585                                         }
2586                                 }
2587
2588                                 if ((mc.ModFlags & Modifiers.OVERRIDE) != 0)
2589                                         continue;                                       
2590
2591                                 if (found is MemberInfo) {
2592                                         if (basename == ((MemberInfo) found).Name)
2593                                                 continue;
2594                                         Report.SymbolRelatedToPreviousError ((MemberInfo) found);
2595                                 } else {
2596                                         Report.SymbolRelatedToPreviousError ((MemberCore) found);
2597                                 }
2598 #if GMCS_SOURCE
2599                                 Report.Warning (3005, 1, mc.Location, "Identifier `{0}' differing only in case is not CLS-compliant", mc.GetSignatureForError ());
2600 #else
2601                                 Report.Error (3005, mc.Location, "Identifier `{0}' differing only in case is not CLS-compliant", mc.GetSignatureForError ());
2602 #endif
2603                         }
2604                 }
2605
2606
2607                 /// <summary>
2608                 ///   Performs checks for an explicit interface implementation.  First it
2609                 ///   checks whether the `interface_type' is a base inteface implementation.
2610                 ///   Then it checks whether `name' exists in the interface type.
2611                 /// </summary>
2612                 public virtual bool VerifyImplements (InterfaceMemberBase mb)
2613                 {
2614                         if (ifaces != null) {
2615                                 foreach (Type t in ifaces){
2616                                         if (t == mb.InterfaceType)
2617                                                 return true;
2618                                 }
2619                         }
2620                         
2621                         Report.SymbolRelatedToPreviousError (mb.InterfaceType);
2622                         Report.Error (540, mb.Location, "`{0}': containing type does not implement interface `{1}'",
2623                                 mb.GetSignatureForError (), TypeManager.CSharpName (mb.InterfaceType));
2624                         return false;
2625                 }
2626
2627                 public override Type LookupAnyGeneric (string typeName)
2628                 {
2629                         if (types != null) {
2630                                 foreach (TypeContainer tc in types) {
2631                                         if (!tc.IsGeneric)
2632                                                 continue;
2633
2634                                         int pos = tc.Basename.LastIndexOf ('`');
2635                                         if (pos == typeName.Length && String.Compare (typeName, 0, tc.Basename, 0, pos) == 0)
2636                                                 return tc.TypeBuilder;
2637                                 }
2638                         }
2639
2640                         return base.LookupAnyGeneric (typeName);
2641                 }
2642
2643                 public void Mark_HasEquals ()
2644                 {
2645                         Methods.HasEquals = true;
2646                 }
2647
2648                 public void Mark_HasGetHashCode ()
2649                 {
2650                         Methods.HasGetHashCode = true;
2651                 }
2652
2653                 //
2654                 // IMemberContainer
2655                 //
2656
2657                 string IMemberContainer.Name {
2658                         get {
2659                                 return Name;
2660                         }
2661                 }
2662
2663                 Type IMemberContainer.Type {
2664                         get {
2665                                 return TypeBuilder;
2666                         }
2667                 }
2668
2669                 MemberCache IMemberContainer.MemberCache {
2670                         get {
2671                                 return member_cache;
2672                         }
2673                 }
2674
2675                 bool IMemberContainer.IsInterface {
2676                         get {
2677                                 return Kind == Kind.Interface;
2678                         }
2679                 }
2680
2681                 MemberList IMemberContainer.GetMembers (MemberTypes mt, BindingFlags bf)
2682                 {
2683                         BindingFlags new_bf = bf | BindingFlags.DeclaredOnly;
2684
2685                         if (GenericType != null)
2686                                 return TypeManager.FindMembers (GenericType, mt, new_bf,
2687                                                                 null, null);
2688                         else
2689                                 return FindMembers (mt, new_bf, null, null);
2690                 }
2691
2692                 //
2693                 // Generates xml doc comments (if any), and if required,
2694                 // handle warning report.
2695                 //
2696                 internal override void GenerateDocComment (DeclSpace ds)
2697                 {
2698                         DocUtil.GenerateTypeDocComment (this, ds);
2699                 }
2700
2701                 public override string DocCommentHeader {
2702                         get { return "T:"; }
2703                 }
2704
2705                 public virtual MemberCache BaseCache {
2706                         get {
2707                                 if (base_cache != null)
2708                                         return base_cache;
2709                                 if (TypeBuilder.BaseType != null)
2710                                         base_cache = TypeManager.LookupMemberCache (TypeBuilder.BaseType);
2711                                 if (TypeBuilder.IsInterface)
2712                                         base_cache = TypeManager.LookupBaseInterfacesCache (TypeBuilder);
2713                                 return base_cache;
2714                         }
2715                 }
2716         }
2717
2718         public abstract class ClassOrStruct : TypeContainer {
2719                 ListDictionary declarative_security;
2720
2721                 public ClassOrStruct (NamespaceEntry ns, DeclSpace parent,
2722                                       MemberName name, Attributes attrs, Kind kind)
2723                         : base (ns, parent, name, attrs, kind)
2724                 {
2725                 }
2726
2727                 protected override bool AddToContainer (MemberCore symbol, string name)
2728                 {
2729                         if (name == MemberName.Name) {
2730                                 if (symbol is TypeParameter) {
2731                                         Report.Error (694, symbol.Location,
2732                                                       "Type parameter `{0}' has same name as " +
2733                                                       "containing type, or method", name);
2734                                         return false;
2735                                 }
2736
2737                                 Report.SymbolRelatedToPreviousError (this);
2738                                 Report.Error (542, symbol.Location, "`{0}': member names cannot be the same as their enclosing type",
2739                                         symbol.GetSignatureForError ());
2740                                 return false;
2741                         }
2742
2743                         return base.AddToContainer (symbol, name);
2744                 }
2745
2746                 public override void VerifyMembers ()
2747                 {
2748                         base.VerifyMembers ();
2749
2750                         if ((events != null) && (RootContext.WarningLevel >= 3)) {
2751                                 foreach (Event e in events){
2752                                         if ((e.ModFlags & Modifiers.Accessibility) != Modifiers.PRIVATE)
2753                                                 continue;
2754
2755                                         if ((e.caching_flags & Flags.IsUsed) == 0)
2756                                                 Report.Warning (67, 3, e.Location, "The event `{0}' is never used", e.GetSignatureForError ());
2757                                 }
2758                         }
2759                 }
2760
2761                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
2762                 {
2763                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
2764                                 if (declarative_security == null)
2765                                         declarative_security = new ListDictionary ();
2766
2767                                 a.ExtractSecurityPermissionSet (declarative_security);
2768                                 return;
2769                         }
2770
2771                         if (a.Type == TypeManager.struct_layout_attribute_type && a.GetLayoutKindValue () == LayoutKind.Explicit) {
2772                                 HasExplicitLayout = true;
2773                         }
2774
2775                         base.ApplyAttributeBuilder (a, cb);
2776                 }
2777
2778                 /// <summary>
2779                 /// Defines the default constructors 
2780                 /// </summary>
2781                 protected void DefineDefaultConstructor (bool is_static)
2782                 {
2783                         // The default instance constructor is public
2784                         // If the class is abstract, the default constructor is protected
2785                         // The default static constructor is private
2786
2787                         int mods;
2788                         if (is_static) {
2789                                 mods = Modifiers.STATIC | Modifiers.PRIVATE;
2790                         } else {
2791                                 mods = ((ModFlags & Modifiers.ABSTRACT) != 0) ? Modifiers.PROTECTED : Modifiers.PUBLIC;
2792                         }
2793
2794                         Constructor c = new Constructor (this, MemberName.Name, mods,
2795                                 Parameters.EmptyReadOnlyParameters,
2796                                 new GeneratedBaseInitializer (Location),
2797                                 Location);
2798                         
2799                         AddConstructor (c);
2800                         c.Block = new ToplevelBlock (null, Location);
2801                 }
2802
2803                 void DefineFieldInitializers ()
2804                 {
2805                         if (initialized_fields != null) {
2806                                 for (int i = 0; i < initialized_fields.Count; ++i) {
2807                                         FieldInitializer fi = (FieldInitializer)initialized_fields[i];
2808
2809                                         EmitContext ec = new EmitContext (fi.TypeContainer, fi.TypeContainer,
2810                                                 Location, null, null, ModFlags);
2811                                         ec.IsFieldInitializer = true;
2812
2813                                         fi.ResolveStatement (ec);
2814                                         if (fi.IsDefaultInitializer && RootContext.Optimize) {
2815                                                 // Field is re-initialized to its default value => removed
2816                                                 initialized_fields.RemoveAt (i);
2817                                                 --i;
2818                                         }
2819                                 }
2820                         }
2821
2822                         if (initialized_static_fields != null) {
2823                                 bool has_complex_initializer = false;
2824
2825                                 foreach (FieldInitializer fi in initialized_static_fields) {
2826                                         EmitContext ec = new EmitContext (fi.TypeContainer, fi.TypeContainer,
2827                                                 Location, null, null, ModFlags);
2828                                         ec.IsStatic = true;
2829                                         ec.IsFieldInitializer = true;
2830
2831                                         fi.ResolveStatement (ec);
2832                                         if (!fi.IsComplexInitializer)
2833                                                 continue;
2834
2835                                         has_complex_initializer = true;
2836                                 }
2837
2838                                 // Need special check to not optimize code like this
2839                                 // static int a = b = 5;
2840                                 // static int b = 0;
2841                                 if (!has_complex_initializer && RootContext.Optimize) {
2842                                         for (int i = 0; i < initialized_static_fields.Count; ++i) {
2843                                                 FieldInitializer fi = (FieldInitializer)initialized_static_fields[i];
2844                                                 if (fi.IsDefaultInitializer) {
2845                                                         initialized_static_fields.RemoveAt (i);
2846                                                         --i;
2847                                                 }
2848                                         }
2849                                 }
2850
2851                                 if (default_static_constructor == null && initialized_static_fields.Count > 0) {
2852                                         DefineDefaultConstructor (true);
2853                                 }
2854                         }
2855
2856                 }
2857
2858                 public override bool Define ()
2859                 {
2860                         DefineFieldInitializers ();
2861
2862                         if (default_static_constructor != null)
2863                                 default_static_constructor.Define ();
2864
2865                         return base.Define ();
2866                 }
2867
2868                 public override void Emit ()
2869                 {
2870                         base.Emit ();
2871
2872                         if (declarative_security != null) {
2873                                 foreach (DictionaryEntry de in declarative_security) {
2874                                         TypeBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
2875                                 }
2876                         }
2877                 }
2878
2879                 public override ExtensionMethodGroupExpr LookupExtensionMethod (Type extensionType, string name)
2880                 {
2881                         return NamespaceEntry.LookupExtensionMethod (extensionType, true, name);
2882                 }
2883
2884                 protected override TypeAttributes TypeAttr {
2885                         get {
2886                                 if (default_static_constructor == null)
2887                                         return base.TypeAttr | TypeAttributes.BeforeFieldInit;
2888
2889                                 return base.TypeAttr;
2890                         }
2891                 }
2892         }
2893
2894
2895         // TODO: should be sealed
2896         public class Class : ClassOrStruct {
2897                 const int AllowedModifiers =
2898                         Modifiers.NEW |
2899                         Modifiers.PUBLIC |
2900                         Modifiers.PROTECTED |
2901                         Modifiers.INTERNAL |
2902                         Modifiers.PRIVATE |
2903                         Modifiers.ABSTRACT |
2904                         Modifiers.SEALED |
2905                         Modifiers.STATIC |
2906                         Modifiers.UNSAFE;
2907
2908                 public const TypeAttributes StaticClassAttribute = TypeAttributes.Abstract | TypeAttributes.Sealed;
2909
2910                 public Class (NamespaceEntry ns, DeclSpace parent, MemberName name, int mod,
2911                               Attributes attrs)
2912                         : base (ns, parent, name, attrs, Kind.Class)
2913                 {
2914                         int accmods = Parent.Parent == null ? Modifiers.INTERNAL : Modifiers.PRIVATE;
2915                         this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, Location);
2916
2917                         if (IsStatic && RootContext.Version == LanguageVersion.ISO_1) {
2918                                 Report.FeatureIsNotISO1 (Location, "static classes");
2919                         }
2920                 }
2921
2922                 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
2923                 {
2924                         if (a.Type == TypeManager.attribute_usage_type) {
2925                                 if (BaseType != TypeManager.attribute_type && !BaseType.IsSubclassOf (TypeManager.attribute_type) &&
2926                                         TypeBuilder.FullName != "System.Attribute") {
2927                                         Report.Error (641, a.Location, "Attribute `{0}' is only valid on classes derived from System.Attribute", a.GetSignatureForError ());
2928                                 }
2929                         }
2930
2931                         if (a.Type == TypeManager.conditional_attribute_type &&
2932                                 !(BaseType == TypeManager.attribute_type || BaseType.IsSubclassOf (TypeManager.attribute_type))) {
2933                                 Report.Error (1689, a.Location, "Attribute `System.Diagnostics.ConditionalAttribute' is only valid on methods or attribute classes");
2934                                 return;
2935                         }
2936
2937                         if (a.Type == TypeManager.comimport_attr_type &&
2938                                 !attributes.Contains (TypeManager.guid_attr_type)) {
2939                                         a.Error_MissingGuidAttribute ();
2940                                         return;
2941                         }
2942
2943                         if (a.Type == TypeManager.extension_attribute_type) {
2944                                 a.Error_MisusedExtensionAttribute ();
2945                                 return;
2946                         }
2947
2948                         if (AttributeTester.IsAttributeExcluded (a.Type))
2949                                 return;
2950
2951                         base.ApplyAttributeBuilder (a, cb);
2952                 }
2953
2954                 public override AttributeTargets AttributeTargets {
2955                         get {
2956                                 return AttributeTargets.Class;
2957                         }
2958                 }
2959
2960                 protected override void DefineContainerMembers (MemberCoreArrayList list)
2961                 {
2962                         if (list == null)
2963                                 return;
2964
2965                         if (!IsStatic) {
2966                                 base.DefineContainerMembers (list);
2967                                 return;
2968                         }
2969
2970                         foreach (MemberCore m in list) {
2971                                 if (m is Operator) {
2972                                         Report.Error (715, m.Location, "`{0}': Static classes cannot contain user-defined operators", m.GetSignatureForError ());
2973                                         continue;
2974                                 }
2975
2976                                 if (m is Destructor) {
2977                                         Report.Error (711, m.Location, "`{0}': Static classes cannot contain destructor", GetSignatureForError ());
2978                                         continue;
2979                                 }
2980
2981                                 if ((m.ModFlags & Modifiers.PROTECTED) != 0) {
2982                                         Report.Error (1057, m.Location, "`{0}': Static classes cannot contain protected members", m.GetSignatureForError ());
2983                                         continue;
2984                                 }
2985
2986                                 if (m is Indexer) {
2987                                         Report.Error (720, m.Location, "`{0}': cannot declare indexers in a static class", m.GetSignatureForError ());
2988                                         continue;
2989                                 }
2990
2991                                 if ((m.ModFlags & Modifiers.STATIC) != 0 || m is Enum || m is Delegate)
2992                                         continue;
2993
2994                                 if (m is Constructor) {
2995                                         Report.Error (710, m.Location, "`{0}': Static classes cannot have instance constructors", GetSignatureForError ());
2996                                         continue;
2997                                 }
2998
2999                                 Method method = m as Method;
3000                                 if (method != null && method.Parameters.HasExtensionMethodType) {
3001                                         Report.Error (1105, m.Location, "`{0}': Extension methods must be declared static", m.GetSignatureForError ());
3002                                         continue;
3003                                 }
3004
3005                                 Report.Error (708, m.Location, "`{0}': cannot declare instance members in a static class", m.GetSignatureForError ());
3006                         }
3007
3008                         base.DefineContainerMembers (list);
3009                 }
3010
3011                 public override TypeBuilder DefineType ()
3012                 {
3013                         if ((ModFlags & Modifiers.ABSTRACT) == Modifiers.ABSTRACT && (ModFlags & (Modifiers.SEALED | Modifiers.STATIC)) != 0) {
3014                                 Report.Error (418, Location, "`{0}': an abstract class cannot be sealed or static", GetSignatureForError ());
3015                                 return null;
3016                         }
3017
3018                         if ((ModFlags & (Modifiers.SEALED | Modifiers.STATIC)) == (Modifiers.SEALED | Modifiers.STATIC)) {
3019                                 Report.Error (441, Location, "`{0}': a class cannot be both static and sealed", GetSignatureForError ());
3020                                 return null;
3021                         }
3022
3023                         return base.DefineType ();
3024                 }
3025
3026                 protected override bool DoDefineMembers ()
3027                 {
3028                         if (InstanceConstructors == null && !IsStatic)
3029                                 DefineDefaultConstructor (false);
3030
3031                         return base.DoDefineMembers ();
3032                 }
3033
3034                 public override void Emit ()
3035                 {
3036                         base.Emit ();
3037
3038                         if ((ModFlags & Modifiers.METHOD_EXTENSION) != 0)
3039                                 TypeBuilder.SetCustomAttribute (TypeManager.extension_attribute_attr);
3040                 }
3041
3042                 public override TypeExpr[] GetClassBases (out TypeExpr base_class)
3043                 {
3044                         TypeExpr[] ifaces = base.GetClassBases (out base_class);
3045
3046                         if (base_class == null) {
3047                                 if (RootContext.StdLib)
3048                                         base_class = TypeManager.system_object_expr;
3049                                 else if (Name != "System.Object")
3050                                         base_class = TypeManager.system_object_expr;
3051                         } else {
3052                                 if (Kind == Kind.Class && base_class is TypeParameterExpr){
3053                                         Report.Error (
3054                                                 689, base_class.Location,
3055                                                 "Cannot derive from `{0}' because it is a type parameter",
3056                                                 base_class.GetSignatureForError ());
3057                                         return ifaces;
3058                                 }
3059
3060                                 if (base_class.Type.IsArray || base_class.Type.IsPointer) {
3061                                         Report.Error (1521, base_class.Location, "Invalid base type");
3062                                         return ifaces;
3063                                 }
3064
3065                                 if (base_class.IsSealed){
3066                                         Report.SymbolRelatedToPreviousError (base_class.Type);
3067                                         if (base_class.Type.IsAbstract) {
3068                                                 Report.Error (709, Location, "`{0}': Cannot derive from static class `{1}'",
3069                                                         GetSignatureForError (), TypeManager.CSharpName (base_class.Type));
3070                                         } else {
3071                                                 Report.Error (509, Location, "`{0}': cannot derive from sealed class `{1}'",
3072                                                         GetSignatureForError (), TypeManager.CSharpName (base_class.Type));
3073                                         }
3074                                         return ifaces;
3075                                 }
3076
3077                                 if (!base_class.CanInheritFrom ()){
3078                                         Report.Error (644, Location, "`{0}' cannot derive from special class `{1}'",
3079                                                 GetSignatureForError (), base_class.GetSignatureForError ());
3080                                         return ifaces;
3081                                 }
3082
3083                                 if (!base_class.AsAccessible (this, ModFlags)) {
3084                                         Report.SymbolRelatedToPreviousError (base_class.Type);
3085                                         Report.Error (60, Location, "Inconsistent accessibility: base class `{0}' is less accessible than class `{1}'", 
3086                                                 TypeManager.CSharpName (base_class.Type), GetSignatureForError ());
3087                                 }
3088                         }
3089
3090                         if (IsStatic) {
3091                                 if (base_class != TypeManager.system_object_expr) {
3092                                         Report.Error (713, Location, "Static class `{0}' cannot derive from type `{1}'. Static classes must derive from object",
3093                                                 GetSignatureForError (), base_class.GetSignatureForError ());
3094                                         return ifaces;
3095                                 }
3096
3097                                 if (ifaces != null) {
3098                                         foreach (TypeExpr t in ifaces)
3099                                                 Report.SymbolRelatedToPreviousError (t.Type);
3100                                         Report.Error (714, Location, "`{0}': static classes cannot implement interfaces", GetSignatureForError ());
3101                                 }
3102                         }
3103
3104                         return ifaces;
3105                 }
3106
3107                 /// Search for at least one defined condition in ConditionalAttribute of attribute class
3108                 /// Valid only for attribute classes.
3109                 public bool IsExcluded ()
3110                 {
3111                         if ((caching_flags & Flags.Excluded_Undetected) == 0)
3112                                 return (caching_flags & Flags.Excluded) != 0;
3113
3114                         caching_flags &= ~Flags.Excluded_Undetected;
3115
3116                         if (OptAttributes == null)
3117                                 return false;
3118
3119                         Attribute[] attrs = OptAttributes.SearchMulti (TypeManager.conditional_attribute_type);
3120
3121                         if (attrs == null)
3122                                 return false;
3123
3124                         foreach (Attribute a in attrs) {
3125                                 string condition = a.GetConditionalAttributeValue ();
3126                                 if (RootContext.AllDefines.Contains (condition))
3127                                         return false;
3128                         }
3129
3130                         caching_flags |= Flags.Excluded;
3131                         return true;
3132                 }
3133
3134                 bool IsStatic {
3135                         get {
3136                                 return (ModFlags & Modifiers.STATIC) != 0;
3137                         }
3138                 }
3139
3140                 //
3141                 // FIXME: How do we deal with the user specifying a different
3142                 // layout?
3143                 //
3144                 protected override TypeAttributes TypeAttr {
3145                         get {
3146                                 TypeAttributes ta = base.TypeAttr | TypeAttributes.AutoLayout | TypeAttributes.Class;
3147                                 if (IsStatic)
3148                                         ta |= StaticClassAttribute;
3149                                 return ta;
3150                         }
3151                 }
3152         }
3153
3154         public sealed class Struct : ClassOrStruct {
3155                 // <summary>
3156                 //   Modifiers allowed in a struct declaration
3157                 // </summary>
3158                 const int AllowedModifiers =
3159                         Modifiers.NEW       |
3160                         Modifiers.PUBLIC    |
3161                         Modifiers.PROTECTED |
3162                         Modifiers.INTERNAL  |
3163                         Modifiers.UNSAFE    |
3164                         Modifiers.PRIVATE;
3165
3166                 public Struct (NamespaceEntry ns, DeclSpace parent, MemberName name,
3167                                int mod, Attributes attrs)
3168                         : base (ns, parent, name, attrs, Kind.Struct)
3169                 {
3170                         int accmods;
3171                         
3172                         if (parent.Parent == null)
3173                                 accmods = Modifiers.INTERNAL;
3174                         else
3175                                 accmods = Modifiers.PRIVATE;
3176                         
3177                         this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, Location);
3178
3179                         this.ModFlags |= Modifiers.SEALED;
3180                 }
3181
3182                 public override AttributeTargets AttributeTargets {
3183                         get {
3184                                 return AttributeTargets.Struct;
3185                         }
3186                 }
3187
3188                 const TypeAttributes DefaultTypeAttributes =
3189                         TypeAttributes.SequentialLayout |
3190                         TypeAttributes.Sealed |
3191                         TypeAttributes.BeforeFieldInit;
3192
3193
3194                 public override TypeExpr[] GetClassBases (out TypeExpr base_class)
3195                 {
3196                         TypeExpr[] ifaces = base.GetClassBases (out base_class);
3197                         //
3198                         // If we are compiling our runtime,
3199                         // and we are defining ValueType, then our
3200                         // base is `System.Object'.
3201                         //
3202                         if (base_class == null) {
3203                                 if (!RootContext.StdLib && Name == "System.ValueType")
3204                                         base_class = TypeManager.system_object_expr;
3205                                 else
3206                                         base_class = TypeManager.system_valuetype_expr;
3207                         }
3208
3209                         return ifaces;
3210                 }
3211
3212                 //
3213                 // FIXME: Allow the user to specify a different set of attributes
3214                 // in some cases (Sealed for example is mandatory for a class,
3215                 // but what SequentialLayout can be changed
3216                 //
3217                 protected override TypeAttributes TypeAttr {
3218                         get {
3219                                 return base.TypeAttr | DefaultTypeAttributes;
3220                         }
3221                 }
3222
3223                 public override void RegisterFieldForInitialization (MemberCore field, FieldInitializer expression)
3224                 {
3225                         if ((field.ModFlags & Modifiers.STATIC) == 0) {
3226                                 Report.Error (573, field.Location, "`{0}': Structs cannot have instance field initializers",
3227                                         field.GetSignatureForError ());
3228                                 return;
3229                         }
3230                         base.RegisterFieldForInitialization (field, expression);
3231                 }
3232
3233         }
3234
3235         /// <summary>
3236         ///   Interfaces
3237         /// </summary>
3238         public sealed class Interface : TypeContainer, IMemberContainer {
3239
3240                 /// <summary>
3241                 ///   Modifiers allowed in a class declaration
3242                 /// </summary>
3243                 public const int AllowedModifiers =
3244                         Modifiers.NEW       |
3245                         Modifiers.PUBLIC    |
3246                         Modifiers.PROTECTED |
3247                         Modifiers.INTERNAL  |
3248                         Modifiers.UNSAFE    |
3249                         Modifiers.PRIVATE;
3250
3251                 public Interface (NamespaceEntry ns, DeclSpace parent, MemberName name, int mod,
3252                                   Attributes attrs)
3253                         : base (ns, parent, name, attrs, Kind.Interface)
3254                 {
3255                         int accmods;
3256
3257                         if (parent.Parent == null)
3258                                 accmods = Modifiers.INTERNAL;
3259                         else
3260                                 accmods = Modifiers.PRIVATE;
3261
3262                         this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, name.Location);
3263                 }
3264
3265                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
3266                 {
3267                         if (a.Type == TypeManager.comimport_attr_type &&
3268                                 !attributes.Contains (TypeManager.guid_attr_type)) {
3269                                         a.Error_MissingGuidAttribute ();
3270                                         return;
3271                         }
3272                         base.ApplyAttributeBuilder (a, cb);
3273                 }
3274
3275
3276                 public override AttributeTargets AttributeTargets {
3277                         get {
3278                                 return AttributeTargets.Interface;
3279                         }
3280                 }
3281
3282                 const TypeAttributes DefaultTypeAttributes =
3283                         TypeAttributes.AutoLayout |
3284                         TypeAttributes.Abstract |
3285                         TypeAttributes.Interface;
3286
3287                 protected override TypeAttributes TypeAttr {
3288                         get {
3289                                 return base.TypeAttr | DefaultTypeAttributes;
3290                         }
3291                 }
3292
3293                 protected override bool VerifyClsCompliance ()
3294                 {
3295                         if (!base.VerifyClsCompliance ())
3296                                 return false;
3297
3298                         if (ifaces != null) {
3299                                 foreach (Type t in ifaces) {
3300                                         if (AttributeTester.IsClsCompliant (t))
3301                                                 continue;
3302
3303                                         Report.SymbolRelatedToPreviousError (t);
3304                                         Report.Warning (3027, 1, Location, "`{0}' is not CLS-compliant because base interface `{1}' is not CLS-compliant",
3305                                                 GetSignatureForError (), TypeManager.CSharpName (t));
3306                                 }
3307                         }
3308
3309                         return true;
3310                 }
3311         }
3312
3313         // It is used as a base class for all property based members
3314         // This includes properties, indexers, and events
3315         public abstract class PropertyBasedMember : InterfaceMemberBase
3316         {
3317                 public PropertyBasedMember (DeclSpace parent, GenericMethod generic,
3318                         Expression type, int mod, int allowed_mod, bool is_iface,
3319                         MemberName name, Attributes attrs)
3320                         : base (parent, generic, type, mod, allowed_mod, is_iface, name, attrs)
3321                 {
3322                 }
3323
3324                 protected override bool CheckForDuplications ()
3325                 {
3326                         throw new NotSupportedException ();
3327                 }
3328
3329                 protected override bool VerifyClsCompliance ()
3330                 {
3331                         if (!base.VerifyClsCompliance ())
3332                                 return false;
3333
3334                         if (!AttributeTester.IsClsCompliant (MemberType)) {
3335                                 Report.Error (3003, Location, "Type of `{0}' is not CLS-compliant",
3336                                         GetSignatureForError ());
3337                         }
3338                         return true;
3339                 }
3340
3341         }
3342
3343
3344         public abstract class MethodCore : InterfaceMemberBase
3345         {
3346                 public readonly Parameters Parameters;
3347                 protected ToplevelBlock block;
3348
3349                 public MethodCore (DeclSpace parent, GenericMethod generic,
3350                         Expression type, int mod, int allowed_mod, bool is_iface,
3351                         MemberName name, Attributes attrs, Parameters parameters)
3352                         : base (parent, generic, type, mod, allowed_mod, is_iface, name, attrs)
3353                 {
3354                         Parameters = parameters;
3355                 }
3356
3357                 //
3358                 //  Returns the System.Type array for the parameters of this method
3359                 //
3360                 public Type [] ParameterTypes {
3361                         get {
3362                                 return Parameters.Types;
3363                         }
3364                 }
3365
3366                 public Parameters ParameterInfo
3367                 {
3368                         get {
3369                                 return Parameters;
3370                         }
3371                 }
3372                 
3373                 public ToplevelBlock Block {
3374                         get {
3375                                 return block;
3376                         }
3377
3378                         set {
3379                                 block = value;
3380                         }
3381                 }
3382
3383                 protected override bool CheckBase ()
3384                 {
3385                         // Check whether arguments were correct.
3386                         if (!DefineParameters (Parameters))
3387                                 return false;
3388
3389                         if (!base.CheckBase ())
3390                                 return false;
3391
3392                         return true;
3393                 }
3394
3395                 // TODO: create a special method for operators only to make code better
3396                 protected bool IsDuplicateImplementation (MethodCore method)
3397                 {
3398                         if (method == this)
3399                                 return false;
3400
3401                         Operator op2 = null;
3402                         Operator op1 = null;
3403
3404                         if (!(method.MemberName.Equals (MemberName)))
3405                         {
3406                                 op1 = this as Operator;
3407                                 if (op1 == null || !(op1.OperatorType == Operator.OpType.Explicit || op1.OperatorType == Operator.OpType.Implicit))
3408                                         return false;
3409
3410                                 op2 = method as Operator;
3411                                 if (op2 == null || !(op2.OperatorType == Operator.OpType.Explicit || op2.OperatorType == Operator.OpType.Implicit))
3412                                         return false;
3413                         } else {
3414                                 op1 = this as Operator;
3415                                 op2 = method as Operator;
3416                         }
3417
3418                         Type[] param_types = method.ParameterTypes;
3419                         // This never happen. Rewrite this as Equal
3420                         if (param_types == null && ParameterTypes == null)
3421                                 return true;
3422                         if (param_types == null || ParameterTypes == null)
3423                                 return false;
3424
3425                         if (param_types.Length != ParameterTypes.Length)
3426                                 return false;
3427
3428                         if (method.Parameters.HasArglist != Parameters.HasArglist)
3429                                 return false;
3430                         
3431                         bool equal = true;
3432
3433                         for (int i = 0; i < param_types.Length; i++) {
3434                                 if (param_types [i] != ParameterTypes [i])
3435                                         equal = false;
3436                         }
3437
3438                         if (IsExplicitImpl && (method.InterfaceType != InterfaceType))
3439                                 equal = false;
3440
3441                         // TODO: make operator compatible with MethodCore to avoid this
3442                         if (op1 != null && op2 != null) {
3443                                 if (MemberType != method.MemberType)
3444                                         equal = false;
3445                         }
3446
3447                         if (equal) {
3448                                 //
3449                                 // Try to report 663: method only differs on out/ref
3450                                 //
3451                                 Parameters info = ParameterInfo;
3452                                 Parameters other_info = method.ParameterInfo;
3453                                 for (int i = 0; i < info.Count; i++){
3454                                         if (info.ParameterModifier (i) != other_info.ParameterModifier (i)){
3455                                                 Report.SymbolRelatedToPreviousError (method);
3456                                                 Report.Error (663, Location, "`{0}': Methods cannot differ only on their use of ref and out on a parameters",
3457                                                               GetSignatureForError ());
3458                                                 return false;
3459                                         }
3460                                 }
3461
3462                                 Report.SymbolRelatedToPreviousError (method);
3463                                 if (this is Operator && method is Operator)
3464                                         Report.Error (557, Location, "Duplicate user-defined conversion in type `{0}'", Parent.Name);
3465                                 else
3466                                         Report.Error (111, Location, TypeContainer.Error111, GetSignatureForError ());
3467
3468                                 return true;
3469                         }
3470
3471                         return false;
3472                 }
3473
3474                 //
3475                 // Returns a string that represents the signature for this 
3476                 // member which should be used in XML documentation.
3477                 //
3478                 public override string GetDocCommentName (DeclSpace ds)
3479                 {
3480                         return DocUtil.GetMethodDocCommentName (this, Parameters, ds);
3481                 }
3482
3483                 //
3484                 // Raised (and passed an XmlElement that contains the comment)
3485                 // when GenerateDocComment is writing documentation expectedly.
3486                 //
3487                 // FIXME: with a few effort, it could be done with XmlReader,
3488                 // that means removal of DOM use.
3489                 //
3490                 internal override void OnGenerateDocComment (XmlElement el)
3491                 {
3492                         DocUtil.OnMethodGenerateDocComment (this, el);
3493                 }
3494
3495                 //
3496                 //   Represents header string for documentation comment.
3497                 //
3498                 public override string DocCommentHeader 
3499                 {
3500                         get { return "M:"; }
3501                 }
3502
3503                 public virtual void SetYields ()
3504                 {
3505                         ModFlags |= Modifiers.METHOD_YIELDS;
3506                 }
3507
3508                 protected override bool VerifyClsCompliance ()
3509                 {
3510                         if (!base.VerifyClsCompliance ())
3511                                 return false;
3512
3513                         if (Parameters.HasArglist) {
3514                                 Report.Error (3000, Location, "Methods with variable arguments are not CLS-compliant");
3515                         }
3516
3517                         if (!AttributeTester.IsClsCompliant (MemberType)) {
3518                                 Report.Error (3002, Location, "Return type of `{0}' is not CLS-compliant",
3519                                         GetSignatureForError ());
3520                         }
3521
3522                         Parameters.VerifyClsCompliance ();
3523                         return true;
3524                 }
3525
3526         }
3527
3528         public abstract class InterfaceMemberBase : MemberBase {
3529                 //
3530                 // Whether this is an interface member.
3531                 //
3532                 public bool IsInterface;
3533
3534                 //
3535                 // If true, this is an explicit interface implementation
3536                 //
3537                 public bool IsExplicitImpl;
3538
3539                 protected bool is_external_implementation;
3540
3541                 //
3542                 // The interface type we are explicitly implementing
3543                 //
3544                 public Type InterfaceType;
3545
3546                 //
3547                 // The method we're overriding if this is an override method.
3548                 //
3549                 protected MethodInfo base_method;
3550
3551                 readonly int explicit_mod_flags;
3552                 public MethodAttributes flags;
3553
3554                 public InterfaceMemberBase (DeclSpace parent, GenericMethod generic,
3555                                    Expression type, int mod, int allowed_mod, bool is_iface,
3556                                    MemberName name, Attributes attrs)
3557                         : base (parent, generic, type, mod, allowed_mod, Modifiers.PRIVATE,
3558                                 name, attrs)
3559                 {
3560                         IsInterface = is_iface;
3561                         IsExplicitImpl = (MemberName.Left != null);
3562                         explicit_mod_flags = mod;
3563                 }
3564                 
3565                 protected override bool CheckBase ()
3566                 {
3567                         if (!base.CheckBase ())
3568                                 return false;
3569                         
3570                         if ((caching_flags & Flags.TestMethodDuplication) != 0 && !CheckForDuplications ())
3571                                 return false;
3572
3573                         if (IsExplicitImpl)
3574                                 return true;
3575
3576                         // Is null for System.Object while compiling corlib and base interfaces
3577                         if (Parent.PartialContainer.BaseCache == null) {
3578                                 if ((ModFlags & Modifiers.NEW) != 0) {
3579                                         Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
3580                                 }
3581                                 return true;
3582                         }
3583
3584                         Type base_ret_type = null;
3585                         base_method = FindOutBaseMethod (ref base_ret_type);
3586
3587                         // method is override
3588                         if (base_method != null) {
3589                                 if (!CheckMethodAgainstBase (base_ret_type))
3590                                         return false;
3591
3592                                 if ((ModFlags & Modifiers.OVERRIDE) != 0) {
3593                                         ObsoleteAttribute oa = AttributeTester.GetMethodObsoleteAttribute (base_method);
3594                                         if (oa != null) {
3595                                                 if (OptAttributes == null || !OptAttributes.Contains (TypeManager.obsolete_attribute_type)) {
3596                                                         Report.SymbolRelatedToPreviousError (base_method);
3597                                                                 Report.Warning (672, 1, Location, "Member `{0}' overrides obsolete member `{1}'. Add the Obsolete attribute to `{0}'",
3598                                                                         GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3599                                                 }
3600                                         } else {
3601                                                 if (OptAttributes != null && OptAttributes.Contains (TypeManager.obsolete_attribute_type)) {
3602                                                         Report.Warning (809, 1, Location, "Obsolete member `{0}' overrides non-obsolete member `{1}'",
3603                                                                 GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3604                                                 }
3605                                         }
3606                                 }
3607                                 return true;
3608                         }
3609
3610                         MemberInfo conflict_symbol = Parent.PartialContainer.FindBaseMemberWithSameName (Name, !((this is Event) || (this is Property)));
3611                         if ((ModFlags & Modifiers.OVERRIDE) != 0) {
3612                                 if (conflict_symbol != null) {
3613                                         Report.SymbolRelatedToPreviousError (conflict_symbol);
3614                                         if (this is Event)
3615                                                 Report.Error (72, Location, "`{0}': cannot override because `{1}' is not an event", GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
3616                                         else if (this is PropertyBase)
3617                                                 Report.Error (544, Location, "`{0}': cannot override because `{1}' is not a property", GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
3618                                         else
3619                                                 Report.Error (505, Location, "`{0}': cannot override because `{1}' is not a method", GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
3620                                 } else {
3621                                         Report.Error (115, Location, "`{0}' is marked as an override but no suitable {1} found to override",
3622                                                 GetSignatureForError (), SimpleName.GetMemberType (this));
3623                                 }
3624                                 return false;
3625                         }
3626
3627                         if (conflict_symbol == null) {
3628                                 if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0)) {
3629                                         Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
3630                                 }
3631                                 return true;
3632                         }
3633
3634                         if ((ModFlags & Modifiers.NEW) == 0) {
3635                                 if (this is Method && conflict_symbol is MethodBase)
3636                                         return true;
3637
3638                                 Report.SymbolRelatedToPreviousError (conflict_symbol);
3639                                 Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
3640                                         GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
3641                         }
3642
3643                         return true;
3644                 }
3645
3646                 //
3647                 // Performs various checks on the MethodInfo `mb' regarding the modifier flags
3648                 // that have been defined.
3649                 //
3650                 // `name' is the user visible name for reporting errors (this is used to
3651                 // provide the right name regarding method names and properties)
3652                 //
3653                 bool CheckMethodAgainstBase (Type baseMethodType)
3654                 {
3655                         bool ok = true;
3656
3657                         if ((ModFlags & Modifiers.OVERRIDE) != 0){
3658                                 if (!(base_method.IsAbstract || base_method.IsVirtual)){
3659                                         Report.Error (506, Location,
3660                                                 "`{0}': cannot override inherited member `{1}' because it is not marked virtual, abstract or override",
3661                                                  GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3662                                         ok = false;
3663                                 }
3664                                 
3665                                 // Now we check that the overriden method is not final
3666                                 
3667                                 if (base_method.IsFinal) {
3668                                         Report.SymbolRelatedToPreviousError (base_method);
3669                                         Report.Error (239, Location, "`{0}': cannot override inherited member `{1}' because it is sealed",
3670                                                               GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3671                                         ok = false;
3672                                 }
3673                                 //
3674                                 // Check that the permissions are not being changed
3675                                 //
3676                                 MethodAttributes thisp = flags & MethodAttributes.MemberAccessMask;
3677                                 MethodAttributes base_classp = base_method.Attributes & MethodAttributes.MemberAccessMask;
3678
3679                                 if (!CheckAccessModifiers (thisp, base_classp, base_method)) {
3680                                         Error_CannotChangeAccessModifiers (base_method, base_classp, null);
3681                                         ok = false;
3682                                 }
3683
3684                                 if (!TypeManager.IsEqual (MemberType, TypeManager.TypeToCoreType (baseMethodType))) {
3685                                         Report.SymbolRelatedToPreviousError (base_method);
3686                                         if (this is PropertyBasedMember) {
3687                                                 Report.Error (1715, Location, "`{0}': type must be `{1}' to match overridden member `{2}'", 
3688                                                         GetSignatureForError (), TypeManager.CSharpName (baseMethodType), TypeManager.CSharpSignature (base_method));
3689                                         }
3690                                         else {
3691                                                 Report.Error (508, Location, "`{0}': return type must be `{1}' to match overridden member `{2}'",
3692                                                         GetSignatureForError (), TypeManager.CSharpName (baseMethodType), TypeManager.CSharpSignature (base_method));
3693                                         }
3694                                         ok = false;
3695                                 }
3696                         }
3697
3698                         if ((ModFlags & Modifiers.NEW) == 0) {
3699                                 if ((ModFlags & Modifiers.OVERRIDE) == 0 && Name != "Finalize") {
3700                                         ModFlags |= Modifiers.NEW;
3701                                         Report.SymbolRelatedToPreviousError (base_method);
3702                                         if (!IsInterface && (base_method.IsVirtual || base_method.IsAbstract)) {
3703                                                 Report.Warning (114, 2, Location, "`{0}' hides inherited member `{1}'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword",
3704                                                         GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3705                                         } else {
3706                                                 Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
3707                                                         GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3708                                         }
3709                                 }
3710                         } else {
3711                                 if (base_method.IsAbstract && !IsInterface) {
3712                                         Report.SymbolRelatedToPreviousError (base_method);
3713                                         Report.Error (533, Location, "`{0}' hides inherited abstract member `{1}'",
3714                                                 GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3715                                         return ok = false;
3716                                 }
3717                         }
3718
3719                         return ok;
3720                 }
3721                 
3722                 protected bool CheckAccessModifiers (MethodAttributes thisp, MethodAttributes base_classp, MethodInfo base_method)
3723                 {
3724                         if ((base_classp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
3725                                 //
3726                                 // when overriding protected internal, the method can be declared
3727                                 // protected internal only within the same assembly
3728                                 //
3729
3730                                 if ((thisp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
3731                                         if (Parent.TypeBuilder.Assembly != base_method.DeclaringType.Assembly){
3732                                                 //
3733                                                 // assemblies differ - report an error
3734                                                 //
3735                                                 
3736                                                 return false;
3737                                         } else if (thisp != base_classp) {
3738                                                 //
3739                                                 // same assembly, but other attributes differ - report an error
3740                                                 //
3741                                                 
3742                                                 return false;
3743                                         };
3744                                 } else if ((thisp & MethodAttributes.Family) != MethodAttributes.Family) {
3745                                         //
3746                                         // if it's not "protected internal", it must be "protected"
3747                                         //
3748
3749                                         return false;
3750                                 } else if (Parent.TypeBuilder.Assembly == base_method.DeclaringType.Assembly) {
3751                                         //
3752                                         // protected within the same assembly - an error
3753                                         //
3754                                         return false;
3755                                 } else if ((thisp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem)) != 
3756                                            (base_classp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem))) {
3757                                         //
3758                                         // protected ok, but other attributes differ - report an error
3759                                         //
3760                                         return false;
3761                                 }
3762                                 return true;
3763                         } else {
3764                                 return (thisp == base_classp);
3765                         }
3766                 }
3767
3768                 public bool CheckAbstractAndExtern (bool has_block)
3769                 {
3770                         if (Parent.PartialContainer.Kind == Kind.Interface)
3771                                 return true;
3772
3773                         if (has_block) {
3774                                 if ((ModFlags & Modifiers.EXTERN) != 0) {
3775                                         Report.Error (179, Location, "`{0}' cannot declare a body because it is marked extern",
3776                                                 GetSignatureForError ());
3777                                         return false;
3778                                 }
3779
3780                                 if ((ModFlags & Modifiers.ABSTRACT) != 0) {
3781                                         Report.Error (500, Location, "`{0}' cannot declare a body because it is marked abstract",
3782                                                 GetSignatureForError ());
3783                                         return false;
3784                                 }
3785                         } else {
3786                                 if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) == 0) {
3787                                         Report.Error (501, Location, "`{0}' must declare a body because it is not marked abstract or extern",
3788                                                 GetSignatureForError ());
3789                                         return false;
3790                                 }
3791                         }
3792
3793                         return true;
3794                 }
3795
3796                 protected bool DefineParameters (Parameters parameters)
3797                 {
3798                         IResolveContext rc = GenericMethod == null ? this : (IResolveContext)ds;
3799
3800                         if (!parameters.Resolve (rc))
3801                                 return false;
3802
3803                         bool error = false;
3804                         foreach (Parameter p in parameters.FixedParameters) {
3805                                 if (p.CheckAccessibility (this))
3806                                         continue;
3807
3808                                 Report.SymbolRelatedToPreviousError (p.ParameterType);
3809                                 if (this is Indexer)
3810                                         Report.Error (55, Location,
3811                                                 "Inconsistent accessibility: parameter type `" +
3812                                                 TypeManager.CSharpName (p.ParameterType) + "' is less " +
3813                                                 "accessible than indexer `" + GetSignatureForError () + "'");
3814                                 else if (this is Operator)
3815                                         Report.Error (57, Location,
3816                                                 "Inconsistent accessibility: parameter type `" +
3817                                                 TypeManager.CSharpName (p.ParameterType) + "' is less " +
3818                                                 "accessible than operator `" + GetSignatureForError () + "'");
3819                                 else
3820                                         Report.Error (51, Location,
3821                                                 "Inconsistent accessibility: parameter type `{0}' is less accessible than method `{1}'",
3822                                                 TypeManager.CSharpName (p.ParameterType), GetSignatureForError ());
3823                                 error = true;
3824                         }
3825                         return !error;
3826                 }
3827
3828                 protected override bool DoDefine()
3829                 {
3830                         if (!base.DoDefine ())
3831                                 return false;
3832
3833                         if (IsExplicitImpl) {
3834                                 Expression expr = MemberName.Left.GetTypeExpression ();
3835                                 TypeExpr texpr = expr.ResolveAsTypeTerminal (this, false);
3836                                 if (texpr == null)
3837                                         return false;
3838
3839                                 InterfaceType = texpr.Type;
3840
3841                                 if (!InterfaceType.IsInterface) {
3842                                         Report.Error (538, Location, "`{0}' in explicit interface declaration is not an interface", TypeManager.CSharpName (InterfaceType));
3843                                         return false;
3844                                 }
3845                                 
3846                                 if (!Parent.PartialContainer.VerifyImplements (this))
3847                                         return false;
3848                                 
3849                         }
3850                         return true;
3851                 }
3852
3853                 protected virtual bool DoDefineBase ()
3854                 {
3855                         if (Name == null)
3856                                 throw new InternalErrorException ();
3857
3858                         if (IsInterface) {
3859                                 ModFlags = Modifiers.PUBLIC |
3860                                         Modifiers.ABSTRACT |
3861                                         Modifiers.VIRTUAL | (ModFlags & Modifiers.UNSAFE) | (ModFlags & Modifiers.NEW);
3862
3863                                 flags = MethodAttributes.Public |
3864                                         MethodAttributes.Abstract |
3865                                         MethodAttributes.HideBySig |
3866                                         MethodAttributes.NewSlot |
3867                                         MethodAttributes.Virtual;
3868                         } else {
3869                                 if (!Parent.PartialContainer.MethodModifiersValid (this))
3870                                         return false;
3871
3872                                 flags = Modifiers.MethodAttr (ModFlags);
3873                         }
3874
3875                         if (IsExplicitImpl) {
3876                                 Expression expr = MemberName.Left.GetTypeExpression ();
3877                                 TypeExpr iface_texpr = expr.ResolveAsTypeTerminal (this, false);
3878                                 if (iface_texpr == null)
3879                                         return false;
3880
3881                                 InterfaceType = iface_texpr.Type;
3882
3883                                 if (!InterfaceType.IsInterface) {
3884                                         Report.Error (538, Location, "'{0}' in explicit interface declaration is not an interface", TypeManager.CSharpName (InterfaceType));
3885                                         return false;
3886                                 }
3887
3888                                 if (!Parent.PartialContainer.VerifyImplements (this))
3889                                         return false;
3890                                 
3891                                 Modifiers.Check (Modifiers.AllowedExplicitImplFlags, explicit_mod_flags, 0, Location);
3892                         }
3893
3894                         return true;
3895                 }
3896
3897                 public override void Emit()
3898                 {
3899                         // for extern static method must be specified either DllImport attribute or MethodImplAttribute.
3900                         // We are more strict than Microsoft and report CS0626 as error
3901                         if ((ModFlags & Modifiers.EXTERN) != 0 && !is_external_implementation) {
3902                                 Report.Error (626, Location,
3903                                         "`{0}' is marked as an external but has no DllImport attribute. Consider adding a DllImport attribute to specify the external implementation",
3904                                         GetSignatureForError ());
3905                         }
3906
3907                         base.Emit ();
3908                 }
3909
3910                 protected void Error_CannotChangeAccessModifiers (MemberInfo base_method, MethodAttributes ma, string suffix)
3911                 {
3912                         Report.SymbolRelatedToPreviousError (base_method);
3913                         string base_name = TypeManager.GetFullNameSignature (base_method);
3914                         string this_name = GetSignatureForError ();
3915                         if (suffix != null) {
3916                                 base_name += suffix;
3917                                 this_name += suffix;
3918                         }
3919
3920                         Report.Error (507, Location, "`{0}': cannot change access modifiers when overriding `{1}' inherited member `{2}'",
3921                                 this_name, Modifiers.GetDescription (ma), base_name);
3922                 }
3923
3924                 protected static string Error722 {
3925                         get {
3926                                 return "`{0}': static types cannot be used as return types";
3927                         }
3928                 }
3929
3930                 /// <summary>
3931                 /// For custom member duplication search in a container
3932                 /// </summary>
3933                 protected abstract bool CheckForDuplications ();
3934
3935                 /// <summary>
3936                 /// Gets base method and its return type
3937                 /// </summary>
3938                 protected abstract MethodInfo FindOutBaseMethod (ref Type base_ret_type);
3939
3940                 //
3941                 // The "short" name of this property / indexer / event.  This is the
3942                 // name without the explicit interface.
3943                 //
3944                 public string ShortName 
3945                 {
3946                         get { return MemberName.Name; }
3947                         set { SetMemberName (new MemberName (MemberName.Left, value, Location)); }
3948                 }
3949
3950                 protected override bool VerifyClsCompliance ()
3951                 {
3952                         if (!base.VerifyClsCompliance ()) {
3953                                 if (IsInterface && HasClsCompliantAttribute && Parent.IsClsComplianceRequired ()) {
3954                                         Report.Error (3010, Location, "`{0}': CLS-compliant interfaces must have only CLS-compliant members", GetSignatureForError ());
3955                                 }
3956
3957                                 if ((ModFlags & Modifiers.ABSTRACT) != 0 && Parent.TypeBuilder.IsClass && IsExposedFromAssembly () && Parent.IsClsComplianceRequired ()) {
3958                                         Report.Error (3011, Location, "`{0}': only CLS-compliant members can be abstract", GetSignatureForError ());
3959                                 }
3960                                 return false;
3961                         }
3962
3963                         if (GenericMethod != null)
3964                                 GenericMethod.VerifyClsCompliance ();
3965
3966                         return true;
3967                 }
3968
3969                 public override bool IsUsed 
3970                 {
3971                         get { return IsExplicitImpl || base.IsUsed; }
3972                 }
3973
3974         }
3975
3976         public abstract class MethodOrOperator : MethodCore, IMethodData
3977         {
3978                 public MethodBuilder MethodBuilder;
3979                 ReturnParameter return_attributes;
3980                 ListDictionary declarative_security;
3981                 protected MethodData MethodData;
3982
3983                 Iterator iterator;
3984                 ArrayList anonymous_methods;
3985
3986                 static string[] attribute_targets = new string [] { "method", "return" };
3987
3988                 protected MethodOrOperator (DeclSpace parent, GenericMethod generic, Expression type, int mod,
3989                                 int allowed_mod, bool is_interface, MemberName name,
3990                                 Attributes attrs, Parameters parameters)
3991                         : base (parent, generic, type, mod, allowed_mod, is_interface, name,
3992                                         attrs, parameters)
3993                 {
3994                 }
3995
3996                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
3997                 {
3998                         if (a.Target == AttributeTargets.ReturnValue) {
3999                                 if (return_attributes == null)
4000                                         return_attributes = new ReturnParameter (MethodBuilder, Location);
4001
4002                                 return_attributes.ApplyAttributeBuilder (a, cb);
4003                                 return;
4004                         }
4005
4006                         if (a.IsInternalMethodImplAttribute) {
4007                                 is_external_implementation = true;
4008                         }
4009
4010                         if (a.Type == TypeManager.dllimport_type) {
4011                                 const int extern_static = Modifiers.EXTERN | Modifiers.STATIC;
4012                                 if ((ModFlags & extern_static) != extern_static) {
4013                                         Report.Error (601, a.Location, "The DllImport attribute must be specified on a method marked `static' and `extern'");
4014                                 }
4015                                 is_external_implementation = true;
4016                         }
4017
4018                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
4019                                 if (declarative_security == null)
4020                                         declarative_security = new ListDictionary ();
4021                                 a.ExtractSecurityPermissionSet (declarative_security);
4022                                 return;
4023                         }
4024
4025                         MethodBuilder.SetCustomAttribute (cb);
4026                 }
4027
4028                 public override AttributeTargets AttributeTargets {
4029                         get {
4030                                 return AttributeTargets.Method; 
4031                         }
4032                 }
4033
4034                 public virtual EmitContext CreateEmitContext (DeclSpace tc, ILGenerator ig)
4035                 {
4036                         return new EmitContext (
4037                                 this, tc, this.ds, Location, ig, MemberType, ModFlags, false);
4038                 }
4039
4040                 public void AddAnonymousMethod (AnonymousMethodExpression anonymous)
4041                 {
4042                         if (anonymous_methods == null)
4043                                 anonymous_methods = new ArrayList ();
4044                         anonymous_methods.Add (anonymous);
4045                 }
4046
4047                 protected bool DefineGenericMethod ()
4048                 {
4049                         if (!DoDefineBase ())
4050                                 return false;
4051
4052 #if GMCS_SOURCE
4053                         if (GenericMethod != null) {
4054                                 string method_name = MemberName.Name;
4055
4056                                 if (IsExplicitImpl) {
4057                                         method_name = TypeManager.CSharpName (InterfaceType) +
4058                                                 '.' + method_name;
4059                                 }
4060
4061 #if MS_COMPATIBLE
4062                                 MethodBuilder = Parent.TypeBuilder.DefineMethod (method_name, flags, ReturnType, null);
4063 #else
4064                                 MethodBuilder = Parent.TypeBuilder.DefineMethod (method_name, flags);
4065 #endif
4066
4067                                 if (!GenericMethod.Define (MethodBuilder, block))
4068                                         return false;
4069                         }
4070 #endif
4071
4072                         return true;
4073                 }
4074
4075                 public bool ResolveMembers ()
4076                 {
4077                         if (!DefineGenericMethod ())
4078                                 return false;
4079
4080                         if ((ModFlags & Modifiers.METHOD_YIELDS) != 0) {
4081                                 iterator = Iterator.CreateIterator (this, Parent, GenericMethod, ModFlags);
4082                                 if (iterator == null)
4083                                         return false;
4084                         }
4085
4086                         if (anonymous_methods != null) {
4087                                 foreach (AnonymousMethodExpression ame in anonymous_methods) {
4088                                         if (!ame.CreateAnonymousHelpers ())
4089                                                 return false;
4090                                 }
4091                         }
4092
4093                         return true;
4094                 }
4095
4096                 public override bool Define ()
4097                 {
4098                         if (!DoDefine ())
4099                                 return false;
4100
4101                         if (!CheckAbstractAndExtern (block != null))
4102                                 return false;
4103
4104                         if (!CheckBase ())
4105                                 return false;
4106
4107                         MethodData = new MethodData (
4108                                 this, ModFlags, flags, this, MethodBuilder, GenericMethod, base_method);
4109
4110                         if (!MethodData.Define (Parent.PartialContainer))
4111                                 return false;
4112
4113                         MethodBuilder = MethodData.MethodBuilder;
4114
4115                         if (!TypeManager.IsGenericParameter (MemberType)) {
4116                                 if (MemberType.IsAbstract && MemberType.IsSealed) {
4117                                         Report.Error (722, Location, Error722, TypeManager.CSharpName (MemberType));
4118                                         return false;
4119                                 }
4120                         }
4121
4122                         return true;
4123                 }
4124
4125                 public override void Emit ()
4126                 {
4127                         if (OptAttributes != null)
4128                                 OptAttributes.Emit ();
4129
4130                         if (declarative_security != null) {
4131                                 foreach (DictionaryEntry de in declarative_security) {
4132                                         MethodBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
4133                                 }
4134                         }
4135
4136                         base.Emit ();
4137                 }
4138
4139                 protected void Error_ConditionalAttributeIsNotValid ()
4140                 {
4141                         Report.Error (577, Location,
4142                                 "Conditional not valid on `{0}' because it is a constructor, destructor, operator or explicit interface implementation",
4143                                 GetSignatureForError ());
4144                 }
4145
4146                 public override bool MarkForDuplicationCheck ()
4147                 {
4148                         caching_flags |= Flags.TestMethodDuplication;
4149                         return true;
4150                 }
4151
4152                 public override string[] ValidAttributeTargets {
4153                         get {
4154                                 return attribute_targets;
4155                         }
4156                 }
4157
4158                 #region IMethodData Members
4159
4160                 public CallingConventions CallingConventions {
4161                         get {
4162                                 CallingConventions cc = Parameters.CallingConvention;
4163                                 if (Parameters.HasArglist && block != null)
4164                                         block.HasVarargs = true;
4165
4166                                 if (!IsInterface)
4167                                         if ((ModFlags & Modifiers.STATIC) == 0)
4168                                                 cc |= CallingConventions.HasThis;
4169
4170                                 // FIXME: How is `ExplicitThis' used in C#?
4171                         
4172                                 return cc;
4173                         }
4174                 }
4175
4176                 public Type ReturnType {
4177                         get {
4178                                 return MemberType;
4179                         }
4180                 }
4181
4182                 public MemberName MethodName {
4183                         get {
4184                                 return MemberName;
4185                         }
4186                 }
4187
4188                 public Iterator Iterator {
4189                         get { return iterator; }
4190                 }
4191
4192                 public new Location Location {
4193                         get {
4194                                 return base.Location;
4195                         }
4196                 }
4197
4198                 protected override bool CheckBase ()
4199                 {
4200                         if (!base.CheckBase ())
4201                                 return false;
4202
4203                         // TODO: Destructor should derive from MethodCore
4204                         if (base_method != null && (ModFlags & Modifiers.OVERRIDE) != 0 && Name == "Finalize" &&
4205                                 base_method.DeclaringType == TypeManager.object_type && !(this is Destructor)) {
4206                                 Report.Error (249, Location, "Do not override object.Finalize. Instead, provide a destructor");
4207                                 return false;
4208                         }
4209
4210                         return true;
4211                 }
4212
4213                 /// <summary>
4214                 /// Returns true if method has conditional attribute and the conditions is not defined (method is excluded).
4215                 /// </summary>
4216                 public bool IsExcluded () {
4217                         if ((caching_flags & Flags.Excluded_Undetected) == 0)
4218                                 return (caching_flags & Flags.Excluded) != 0;
4219
4220                         caching_flags &= ~Flags.Excluded_Undetected;
4221
4222                         if (base_method == null) {
4223                                 if (OptAttributes == null)
4224                                         return false;
4225
4226                                 Attribute[] attrs = OptAttributes.SearchMulti (TypeManager.conditional_attribute_type);
4227
4228                                 if (attrs == null)
4229                                         return false;
4230
4231                                 foreach (Attribute a in attrs) {
4232                                         string condition = a.GetConditionalAttributeValue ();
4233                                         if (condition == null)
4234                                                 return false;
4235
4236                                         if (RootContext.AllDefines.Contains (condition))
4237                                                 return false;
4238                                 }
4239
4240                                 caching_flags |= Flags.Excluded;
4241                                 return true;
4242                         }
4243
4244                         IMethodData md = TypeManager.GetMethod (base_method);
4245                         if (md == null) {
4246                                 if (AttributeTester.IsConditionalMethodExcluded (base_method)) {
4247                                         caching_flags |= Flags.Excluded;
4248                                         return true;
4249                                 }
4250                                 return false;
4251                         }
4252
4253                         if (md.IsExcluded ()) {
4254                                 caching_flags |= Flags.Excluded;
4255                                 return true;
4256                         }
4257                         return false;
4258                 }
4259
4260                 GenericMethod IMethodData.GenericMethod {
4261                         get {
4262                                 return GenericMethod;
4263                         }
4264                 }
4265
4266                 #endregion
4267
4268         }
4269
4270         public class SourceMethod : ISourceMethod
4271         {
4272                 DeclSpace parent;
4273                 MethodBase builder;
4274
4275                 protected SourceMethod (DeclSpace parent, MethodBase builder,
4276                                         ISourceFile file, Location start, Location end)
4277                 {
4278                         this.parent = parent;
4279                         this.builder = builder;
4280                         
4281                         CodeGen.SymbolWriter.OpenMethod (file, this, start.Row, start.Column, end.Row, start.Column);
4282                 }
4283
4284                 public string Name {
4285                         get { return builder.Name; }
4286                 }
4287
4288                 public int NamespaceID {
4289                         get { return parent.NamespaceEntry.SymbolFileID; }
4290                 }
4291
4292                 public int Token {
4293                         get {
4294                                 if (builder is MethodBuilder)
4295                                         return ((MethodBuilder) builder).GetToken ().Token;
4296                                 else if (builder is ConstructorBuilder)
4297                                         return ((ConstructorBuilder) builder).GetToken ().Token;
4298                                 else
4299                                         throw new NotSupportedException ();
4300                         }
4301                 }
4302
4303                 public void CloseMethod ()
4304                 {
4305                         if (CodeGen.SymbolWriter != null)
4306                                 CodeGen.SymbolWriter.CloseMethod ();
4307                 }
4308
4309                 public static SourceMethod Create (DeclSpace parent, MethodBase builder, Block block)
4310                 {
4311                         if (CodeGen.SymbolWriter == null)
4312                                 return null;
4313                         if (block == null)
4314                                 return null;
4315
4316                         Location start_loc = block.StartLocation;
4317                         if (start_loc.IsNull)
4318                                 return null;
4319
4320                         Location end_loc = block.EndLocation;
4321                         if (end_loc.IsNull)
4322                                 return null;
4323
4324                         ISourceFile file = start_loc.SourceFile;
4325                         if (file == null)
4326                                 return null;
4327
4328                         return new SourceMethod (
4329                                 parent, builder, file, start_loc, end_loc);
4330                 }
4331         }
4332
4333         public class Method : MethodOrOperator, IAnonymousHost {
4334
4335                 /// <summary>
4336                 ///   Modifiers allowed in a class declaration
4337                 /// </summary>
4338                 const int AllowedModifiers =
4339                         Modifiers.NEW |
4340                         Modifiers.PUBLIC |
4341                         Modifiers.PROTECTED |
4342                         Modifiers.INTERNAL |
4343                         Modifiers.PRIVATE |
4344                         Modifiers.STATIC |
4345                         Modifiers.VIRTUAL |
4346                         Modifiers.SEALED |
4347                         Modifiers.OVERRIDE |
4348                         Modifiers.ABSTRACT |
4349                         Modifiers.UNSAFE |
4350                         Modifiers.METHOD_YIELDS | 
4351                         Modifiers.EXTERN;
4352
4353                 const int AllowedInterfaceModifiers =
4354                         Modifiers.NEW | Modifiers.UNSAFE;
4355
4356                 //
4357                 // return_type can be "null" for VOID values.
4358                 //
4359                 public Method (DeclSpace parent, GenericMethod generic,
4360                                Expression return_type, int mod, bool is_iface,
4361                                MemberName name, Parameters parameters, Attributes attrs)
4362                         : base (parent, generic, return_type, mod,
4363                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
4364                                 is_iface, name, attrs, parameters)
4365                 {
4366                 }
4367                 
4368                 public override string GetSignatureForError()
4369                 {
4370                         return base.GetSignatureForError () + Parameters.GetSignatureForError ();
4371                 }
4372
4373                 void Error_DuplicateEntryPoint (MethodInfo b, Location location)
4374                 {
4375                         Report.Error (17, location,
4376                                 "Program `{0}' has more than one entry point defined: `{1}'",
4377                                 CodeGen.FileName, TypeManager.CSharpSignature(b));
4378                 }
4379
4380                 bool IsEntryPoint ()
4381                 {
4382                         if (ReturnType != TypeManager.void_type &&
4383                                 ReturnType != TypeManager.int32_type)
4384                                 return false;
4385
4386                         if (Parameters.Count == 0)
4387                                 return true;
4388
4389                         if (Parameters.Count > 1)
4390                                 return false;
4391
4392                         Type t = Parameters.ParameterType (0);
4393                         return t.IsArray && t.GetArrayRank () == 1 &&
4394                                         TypeManager.GetElementType (t) == TypeManager.string_type &&
4395                                         (Parameters[0].ModFlags & ~Parameter.Modifier.PARAMS) == Parameter.Modifier.NONE;
4396                 }
4397
4398                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
4399                 {
4400                         if (a.Type == TypeManager.conditional_attribute_type) {
4401                                 if (IsExplicitImpl) {
4402                                         Error_ConditionalAttributeIsNotValid ();
4403                                         return;
4404                                 }
4405
4406                                 if (ReturnType != TypeManager.void_type) {
4407                                         Report.Error (578, Location, "Conditional not valid on `{0}' because its return type is not void", GetSignatureForError ());
4408                                         return;
4409                                 }
4410
4411                                 if ((ModFlags & Modifiers.OVERRIDE) != 0) {
4412                                         Report.Error (243, Location, "Conditional not valid on `{0}' because it is an override method", GetSignatureForError ());
4413                                         return;
4414                                 }
4415
4416                                 if (IsInterface) {
4417                                         Report.Error (582, Location, "Conditional not valid on interface members");
4418                                         return;
4419                                 }
4420
4421                                 if (MethodData.implementing != null) {
4422                                         Report.Error (629, Location, "Conditional member `{0}' cannot implement interface member `{1}'",
4423                                                 GetSignatureForError (), TypeManager.CSharpSignature (MethodData.implementing));
4424                                         return;
4425                                 }
4426
4427                                 for (int i = 0; i < Parameters.Count; ++i) {
4428                                         if ((Parameters.ParameterModifier (i) & Parameter.Modifier.OUTMASK) != 0) {
4429                                                 Report.Error (685, Location, "Conditional method `{0}' cannot have an out parameter", GetSignatureForError ());
4430                                                 return;
4431                                         }
4432                                 }
4433                         }
4434
4435                         if (a.Type == TypeManager.extension_attribute_type) {
4436                                 a.Error_MisusedExtensionAttribute ();
4437                                 return;
4438                         }
4439
4440                         base.ApplyAttributeBuilder (a, cb);
4441                 }
4442
4443                 protected override bool CheckForDuplications ()
4444                 {
4445                         ArrayList ar = Parent.PartialContainer.Methods;
4446                         if (ar != null) {
4447                                 int arLen = ar.Count;
4448                                         
4449                                 for (int i = 0; i < arLen; i++) {
4450                                         Method m = (Method) ar [i];
4451                                         if (IsDuplicateImplementation (m))
4452                                                 return false;
4453                                 }
4454                         }
4455
4456                         ar = Parent.PartialContainer.Properties;
4457                         if (ar != null) {
4458                                 for (int i = 0; i < ar.Count; ++i) {
4459                                         PropertyBase pb = (PropertyBase) ar [i];
4460                                         if (pb.AreAccessorsDuplicateImplementation (this))
4461                                                 return false;
4462                                 }
4463                         }
4464
4465                         ar = Parent.PartialContainer.Indexers;
4466                         if (ar != null) {
4467                                 for (int i = 0; i < ar.Count; ++i) {
4468                                         PropertyBase pb = (PropertyBase) ar [i];
4469                                         if (pb.AreAccessorsDuplicateImplementation (this))
4470                                                 return false;
4471                                 }
4472                         }
4473
4474                         ar = Parent.PartialContainer.Events;
4475                         if (ar != null) {
4476                                 for (int i = 0; i < ar.Count; ++i) {
4477                                         Event ev = (Event) ar [i];
4478                                         if (ev.AreAccessorsDuplicateImplementation (this))
4479                                                 return false;
4480                                 }
4481                         }
4482
4483                         return true;
4484                 }
4485
4486                 //
4487                 // Creates the type
4488                 //
4489                 public override bool Define ()
4490                 {
4491                         if (!base.Define ())
4492                                 return false;
4493
4494                         if (RootContext.StdLib && (ReturnType == TypeManager.arg_iterator_type || ReturnType == TypeManager.typed_reference_type)) {
4495                                 Error1599 (Location, ReturnType);
4496                                 return false;
4497                         }
4498
4499                         if (ReturnType == TypeManager.void_type && ParameterTypes.Length == 0 && 
4500                                 Name == "Finalize" && !(this is Destructor)) {
4501                                 Report.Warning (465, 1, Location, "Introducing a 'Finalize' method can interfere with destructor invocation. Did you intend to declare a destructor?");
4502                         }
4503
4504                         if (base_method != null && (ModFlags & Modifiers.NEW) == 0) {
4505                                 if (Parameters.Count == 1 && ParameterTypes [0] == TypeManager.object_type && Name == "Equals")
4506                                         Parent.PartialContainer.Mark_HasEquals ();
4507                                 else if (Parameters.Empty && Name == "GetHashCode")
4508                                         Parent.PartialContainer.Mark_HasGetHashCode ();
4509                         }
4510
4511                         if ((ModFlags & Modifiers.STATIC) == 0)
4512                                 return true;
4513
4514                         if (Parameters.HasExtensionMethodType) {
4515                                 if (Parent.IsStaticClass && !Parent.IsGeneric) {
4516                                         if (!Parent.IsTopLevel)
4517                                                 Report.Error (1109, Location, "`{0}': Extension methods cannot be defined in a nested class",
4518                                                         GetSignatureForError ());
4519
4520                                         if (TypeManager.extension_attribute_type == null)
4521                                                 Report.Error (1110, Location, 
4522                                                         "`{0}': Extension methods cannot be declared without a reference to System.Core.dll assembly. Add the assembly reference or remove `this' modifer from the first parameter",
4523                                                         GetSignatureForError ());
4524
4525                                         ModFlags |= Modifiers.METHOD_EXTENSION;
4526                                         Parent.ModFlags |= Modifiers.METHOD_EXTENSION;
4527                                         CodeGen.Assembly.HasExtensionMethods = true;
4528                                 } else {
4529                                         Report.Error (1106, Location, "`{0}': Extension methods must be defined in a non-generic static class",
4530                                                 GetSignatureForError ());
4531                                 }
4532                         }
4533
4534                         //
4535                         // This is used to track the Entry Point,
4536                         //
4537                         if (RootContext.NeedsEntryPoint &&
4538                                 Name == "Main" &&
4539                                 (RootContext.MainClass == null ||
4540                                 RootContext.MainClass == Parent.TypeBuilder.FullName)){
4541                                 if (IsEntryPoint ()) {
4542
4543                                         if (RootContext.EntryPoint == null) {
4544                                                 if (Parent.IsGeneric || MemberName.IsGeneric) {
4545                                                         Report.Warning (402, 4, Location, "`{0}': an entry point cannot be generic or in a generic type",
4546                                                                 GetSignatureForError ());
4547                                                 } else {
4548                                                         IMethodData md = TypeManager.GetMethod (MethodBuilder);
4549                                                         md.SetMemberIsUsed ();
4550
4551                                                         RootContext.EntryPoint = MethodBuilder;
4552                                                         RootContext.EntryPointLocation = Location;
4553                                                 }
4554                                         } else {
4555                                                 Error_DuplicateEntryPoint (RootContext.EntryPoint, RootContext.EntryPointLocation);
4556                                                 Error_DuplicateEntryPoint (MethodBuilder, Location);
4557                                         }
4558                                 } else {
4559                                         Report.Warning (28, 4, Location, "`{0}' has the wrong signature to be an entry point",
4560                                                 GetSignatureForError ());
4561                                 }
4562                         }
4563
4564                         return true;
4565                 }
4566
4567                 //
4568                 // Emits the code
4569                 // 
4570                 public override void Emit ()
4571                 {
4572                         Report.Debug (64, "METHOD EMIT", this, MethodBuilder, Location, Block, MethodData);
4573                         MethodData.Emit (Parent);
4574                         base.Emit ();
4575
4576                         if ((ModFlags & Modifiers.METHOD_EXTENSION) != 0)
4577                                 MethodBuilder.SetCustomAttribute (TypeManager.extension_attribute_attr);
4578
4579                         Block = null;
4580                         MethodData = null;
4581                 }
4582
4583                 public static void Error1599 (Location loc, Type t)
4584                 {
4585                         Report.Error (1599, loc, "Method or delegate cannot return type `{0}'", TypeManager.CSharpName (t));
4586                 }
4587
4588                 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
4589                 {
4590                         MethodInfo mi = (MethodInfo) Parent.PartialContainer.BaseCache.FindMemberToOverride (
4591                                 Parent.TypeBuilder, Name, ParameterTypes, GenericMethod, false);
4592
4593                         if (mi == null)
4594                                 return null;
4595
4596                         if (mi.IsSpecialName)
4597                                 return null;
4598
4599                         base_ret_type = mi.ReturnType;
4600                         return mi;
4601                 }
4602
4603                 protected override bool VerifyClsCompliance ()
4604                 {
4605                         if (!base.VerifyClsCompliance ())
4606                                 return false;
4607
4608                         if (ParameterInfo.Count > 0) {
4609                                 ArrayList al = (ArrayList)Parent.PartialContainer.MemberCache.Members [Name];
4610                                 if (al.Count > 1)
4611                                         MemberCache.VerifyClsParameterConflict (al, this, MethodBuilder);
4612                         }
4613
4614                         return true;
4615                 }
4616         }
4617
4618         public abstract class ConstructorInitializer {
4619                 ArrayList argument_list;
4620                 protected ConstructorInfo base_constructor;
4621                 Location loc;
4622                 
4623                 public ConstructorInitializer (ArrayList argument_list, Location loc)
4624                 {
4625                         this.argument_list = argument_list;
4626                         this.loc = loc;
4627                 }
4628
4629                 public ArrayList Arguments {
4630                         get {
4631                                 return argument_list;
4632                         }
4633                 }
4634
4635                 public bool Resolve (ConstructorBuilder caller_builder, Block block, EmitContext ec)
4636                 {
4637                         Expression base_constructor_group;
4638                         Type t;
4639                         bool error = false;
4640
4641                         ec.CurrentBlock = block;
4642
4643                         if (argument_list != null){
4644                                 foreach (Argument a in argument_list){
4645                                         if (!a.Resolve (ec, loc))
4646                                                 return false;
4647                                 }
4648                         }
4649                         ec.CurrentBlock = null;
4650
4651                         if (this is ConstructorBaseInitializer) {
4652                                 if (ec.ContainerType.BaseType == null)
4653                                         return true;
4654
4655                                 t = ec.ContainerType.BaseType;
4656                                 if (ec.ContainerType.IsValueType) {
4657                                         Report.Error (522, loc,
4658                                                 "`{0}': Struct constructors cannot call base constructors", TypeManager.CSharpSignature (caller_builder));
4659                                         return false;
4660                                 }
4661                         } else {
4662                                 //
4663                                 // It is legal to have "this" initializers that take no arguments
4664                                 // in structs, they are just no-ops.
4665                                 //
4666                                 // struct D { public D (int a) : this () {}
4667                                 //
4668                                 if (ec.ContainerType.IsValueType && argument_list == null)
4669                                         return true;
4670                                 
4671                                 t = ec.ContainerType;
4672                         }
4673
4674                         base_constructor_group = Expression.MemberLookup (
4675                                 ec.ContainerType, t, ".ctor", MemberTypes.Constructor,
4676                                 BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
4677                                 loc);
4678                         
4679                         if (base_constructor_group == null){
4680                                 error = true;
4681                                 base_constructor_group = Expression.MemberLookup (
4682                                         t, null, t, ".ctor", MemberTypes.Constructor,
4683                                         BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly,
4684                                         loc);
4685                         }
4686
4687                         int errors = Report.Errors;
4688                         if (base_constructor_group != null)
4689                                 base_constructor = (ConstructorInfo)
4690                                         ((MethodGroupExpr) base_constructor_group).OverloadResolve (
4691                                         ec, argument_list,
4692                                         false, loc);
4693                         
4694                         if (base_constructor == null) {
4695                                 if (errors == Report.Errors)
4696                                         Invocation.Error_WrongNumArguments (loc, TypeManager.CSharpSignature (caller_builder),
4697                                                 argument_list == null ? 0 : argument_list.Count);
4698                                 return false;
4699                         }
4700
4701                         if (error) {
4702                                 Report.SymbolRelatedToPreviousError (base_constructor);
4703                                 Expression.ErrorIsInaccesible (loc, TypeManager.CSharpSignature (base_constructor));
4704                                 base_constructor = null;
4705                                 return false;
4706                         }
4707                         
4708                         if (base_constructor == caller_builder){
4709                                 Report.Error (516, loc, "Constructor `{0}' cannot call itself", TypeManager.CSharpSignature (caller_builder));
4710                                 return false;
4711                         }
4712                         
4713                         return true;
4714                 }
4715
4716                 public virtual void Emit (EmitContext ec)
4717                 {
4718                         if (base_constructor != null){
4719                                 ec.Mark (loc, false);
4720                                 if (ec.IsStatic)
4721                                         Invocation.EmitCall (ec, true, true, null, base_constructor, argument_list, loc);
4722                                 else
4723                                         Invocation.EmitCall (ec, true, false, ec.GetThis (loc), base_constructor, argument_list, loc);
4724                         }
4725                 }
4726         }
4727
4728         public class ConstructorBaseInitializer : ConstructorInitializer {
4729                 public ConstructorBaseInitializer (ArrayList argument_list, Location l) :
4730                         base (argument_list, l)
4731                 {
4732                 }
4733         }
4734
4735         class GeneratedBaseInitializer: ConstructorBaseInitializer {
4736                 public GeneratedBaseInitializer (Location loc):
4737                         base (null, loc)
4738                 {
4739                 }
4740         }
4741
4742         public class ConstructorThisInitializer : ConstructorInitializer {
4743                 public ConstructorThisInitializer (ArrayList argument_list, Location l) :
4744                         base (argument_list, l)
4745                 {
4746                 }
4747         }
4748         
4749         public class Constructor : MethodCore, IMethodData, IAnonymousHost {
4750                 public ConstructorBuilder ConstructorBuilder;
4751                 public ConstructorInitializer Initializer;
4752                 ListDictionary declarative_security;
4753                 ArrayList anonymous_methods;
4754
4755                 // <summary>
4756                 //   Modifiers allowed for a constructor.
4757                 // </summary>
4758                 public const int AllowedModifiers =
4759                         Modifiers.PUBLIC |
4760                         Modifiers.PROTECTED |
4761                         Modifiers.INTERNAL |
4762                         Modifiers.STATIC |
4763                         Modifiers.UNSAFE |
4764                         Modifiers.EXTERN |              
4765                         Modifiers.PRIVATE;
4766
4767                 static string[] attribute_targets = new string [] { "method" };
4768
4769                 public Iterator Iterator {
4770                         get { return null; }
4771                 }
4772
4773                 bool has_compliant_args = false;
4774                 //
4775                 // The spec claims that static is not permitted, but
4776                 // my very own code has static constructors.
4777                 //
4778                 public Constructor (DeclSpace parent, string name, int mod, Parameters args,
4779                                     ConstructorInitializer init, Location loc)
4780                         : base (parent, null, null, mod, AllowedModifiers, false,
4781                                 new MemberName (name, loc), null, args)
4782                 {
4783                         Initializer = init;
4784                 }
4785
4786                 public bool HasCompliantArgs {
4787                         get { return has_compliant_args; }
4788                 }
4789
4790                 public override AttributeTargets AttributeTargets {
4791                         get { return AttributeTargets.Constructor; }
4792                 }
4793
4794
4795                 //
4796                 // Returns true if this is a default constructor
4797                 //
4798                 public bool IsDefault ()
4799                 {
4800                         if ((ModFlags & Modifiers.STATIC) != 0)
4801                                 return Parameters.Empty;
4802                         
4803                         return Parameters.Empty &&
4804                                         (Initializer is ConstructorBaseInitializer) &&
4805                                         (Initializer.Arguments == null);
4806                 }
4807
4808                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
4809                 {
4810                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
4811                                 if (declarative_security == null) {
4812                                         declarative_security = new ListDictionary ();
4813                                 }
4814                                 a.ExtractSecurityPermissionSet (declarative_security);
4815                                 return;
4816                         }
4817
4818                         if (a.IsInternalMethodImplAttribute) {
4819                                 is_external_implementation = true;
4820                         }
4821
4822                         ConstructorBuilder.SetCustomAttribute (cb);
4823                 }
4824
4825                 public void AddAnonymousMethod (AnonymousMethodExpression anonymous)
4826                 {
4827                         if (anonymous_methods == null)
4828                                 anonymous_methods = new ArrayList ();
4829                         anonymous_methods.Add (anonymous);
4830                 }
4831
4832                 public bool ResolveMembers ()
4833                 {
4834                         if (anonymous_methods != null) {
4835                                 foreach (AnonymousMethodExpression ame in anonymous_methods) {
4836                                         if (!ame.CreateAnonymousHelpers ())
4837                                                 return false;
4838                                 }
4839                         }
4840
4841                         return true;
4842                 }
4843
4844                 protected override bool CheckForDuplications ()
4845                 {
4846                         ArrayList ar = Parent.PartialContainer.InstanceConstructors;
4847                         if (ar != null) {
4848                                 int arLen = ar.Count;
4849                                         
4850                                 for (int i = 0; i < arLen; i++) {
4851                                         Constructor m = (Constructor) ar [i];
4852                                         if (IsDuplicateImplementation (m))
4853                                                 return false;
4854                                 }
4855                         }
4856                         return true;
4857                 }
4858
4859                 protected override bool CheckBase ()
4860                 {
4861                         if ((ModFlags & Modifiers.STATIC) != 0) {
4862                                 if (!Parameters.Empty) {
4863                                         Report.Error (132, Location, "`{0}': The static constructor must be parameterless",
4864                                                 GetSignatureForError ());
4865                                         return false;
4866                                 }
4867
4868                                 // the rest can be ignored
4869                                 return true;
4870                         }
4871
4872                         // Check whether arguments were correct.
4873                         if (!DefineParameters (Parameters))
4874                                 return false;
4875
4876                         if (!CheckForDuplications ())
4877                                 return false;
4878
4879                         if (Parent.PartialContainer.Kind == Kind.Struct) {
4880                                 if (ParameterTypes.Length == 0) {
4881                                         Report.Error (568, Location, 
4882                                                 "Structs cannot contain explicit parameterless constructors");
4883                                         return false;
4884                                 }
4885
4886                                 if ((ModFlags & Modifiers.PROTECTED) != 0) {
4887                                         Report.Error (666, Location, "`{0}': new protected member declared in struct", GetSignatureForError ());
4888                                         return false;
4889                                 }
4890                         }
4891
4892                         if ((RootContext.WarningLevel >= 4) && ((Parent.ModFlags & Modifiers.SEALED) != 0 && (ModFlags & Modifiers.PROTECTED) != 0)) {
4893                                 Report.Warning (628, 4, Location, "`{0}': new protected member declared in sealed class", GetSignatureForError ());
4894                         }
4895                         
4896                         return true;
4897                 }
4898                 
4899                 //
4900                 // Creates the ConstructorBuilder
4901                 //
4902                 public override bool Define ()
4903                 {
4904                         if (ConstructorBuilder != null)
4905                                 return true;
4906
4907                         MethodAttributes ca = (MethodAttributes.RTSpecialName |
4908                                                MethodAttributes.SpecialName);
4909                         
4910                         if ((ModFlags & Modifiers.STATIC) != 0) {
4911                                 ca |= MethodAttributes.Static | MethodAttributes.Private;
4912                         } else {
4913                                 ca |= MethodAttributes.HideBySig;
4914
4915                                 if ((ModFlags & Modifiers.PUBLIC) != 0)
4916                                         ca |= MethodAttributes.Public;
4917                                 else if ((ModFlags & Modifiers.PROTECTED) != 0){
4918                                         if ((ModFlags & Modifiers.INTERNAL) != 0)
4919                                                 ca |= MethodAttributes.FamORAssem;
4920                                         else 
4921                                                 ca |= MethodAttributes.Family;
4922                                 } else if ((ModFlags & Modifiers.INTERNAL) != 0)
4923                                         ca |= MethodAttributes.Assembly;
4924                                 else
4925                                         ca |= MethodAttributes.Private;
4926                         }
4927
4928                         if (!CheckAbstractAndExtern (block != null))
4929                                 return false;
4930                         
4931                         // Check if arguments were correct.
4932                         if (!CheckBase ())
4933                                 return false;
4934
4935                         ConstructorBuilder = Parent.TypeBuilder.DefineConstructor (
4936                                 ca, CallingConventions,
4937                                 ParameterTypes);
4938
4939                         if ((ModFlags & Modifiers.UNSAFE) != 0)
4940                                 ConstructorBuilder.InitLocals = false;
4941
4942                         if (Parent.PartialContainer.IsComImport) {
4943                                 if (!IsDefault ()) {
4944                                         Report.Error (669, Location, "`{0}': A class with the ComImport attribute cannot have a user-defined constructor",
4945                                                 Parent.GetSignatureForError ());
4946                                         return false;
4947                                 }
4948                                 ConstructorBuilder.SetImplementationFlags (MethodImplAttributes.InternalCall);
4949                         }
4950                         
4951                         TypeManager.AddMethod (ConstructorBuilder, this);
4952
4953                         return true;
4954                 }
4955
4956                 //
4957                 // Emits the code
4958                 //
4959                 public override void Emit ()
4960                 {
4961                         if (OptAttributes != null)
4962                                 OptAttributes.Emit ();
4963
4964                         EmitContext ec = CreateEmitContext (null, null);
4965
4966                         if (block != null) {
4967                                 // If this is a non-static `struct' constructor and doesn't have any
4968                                 // initializer, it must initialize all of the struct's fields.
4969                                 if ((Parent.PartialContainer.Kind == Kind.Struct) &&
4970                                         ((ModFlags & Modifiers.STATIC) == 0) && (Initializer == null))
4971                                         block.AddThisVariable (Parent, Location);
4972
4973                                 if (!block.ResolveMeta (ec, ParameterInfo))
4974                                         block = null;
4975                         }
4976
4977                         if ((ModFlags & Modifiers.STATIC) == 0){
4978                                 if (Parent.PartialContainer.Kind == Kind.Class && Initializer == null)
4979                                         Initializer = new GeneratedBaseInitializer (Location);
4980
4981
4982                                 //
4983                                 // Spec mandates that Initializers will not have
4984                                 // `this' access
4985                                 //
4986                                 ec.IsStatic = true;
4987                                 if ((Initializer != null) &&
4988                                     !Initializer.Resolve (ConstructorBuilder, block, ec))
4989                                         return;
4990                                 ec.IsStatic = false;
4991                         }
4992
4993                         Parameters.ApplyAttributes (ConstructorBuilder);
4994                         
4995                         SourceMethod source = SourceMethod.Create (
4996                                 Parent, ConstructorBuilder, block);
4997
4998                         //
4999                         // Classes can have base initializers and instance field initializers.
5000                         //
5001                         if (Parent.PartialContainer.Kind == Kind.Class){
5002                                 if ((ModFlags & Modifiers.STATIC) == 0){
5003
5004                                         //
5005                                         // If we use a "this (...)" constructor initializer, then
5006                                         // do not emit field initializers, they are initialized in the other constructor
5007                                         //
5008                                         if (!(Initializer != null && Initializer is ConstructorThisInitializer))
5009                                                 Parent.PartialContainer.EmitFieldInitializers (ec);
5010                                 }
5011                         }
5012
5013                         bool unreachable = false;
5014                         if (block != null) {
5015                                 if (!ec.ResolveTopBlock (null, block, ParameterInfo, this, out unreachable))
5016                                         return;
5017                                 ec.EmitMeta (block);
5018
5019                                 if (block.ScopeInfo != null) {
5020                                         ExpressionStatement init = block.ScopeInfo.GetScopeInitializer (ec);
5021                                         init.EmitStatement (ec);
5022                                 }
5023                         }
5024
5025                         if (Initializer != null) {
5026                                 Initializer.Emit (ec);
5027                         }
5028                         
5029                         if ((ModFlags & Modifiers.STATIC) != 0)
5030                                 Parent.PartialContainer.EmitFieldInitializers (ec);
5031
5032                         if (block != null)
5033                                 ec.EmitResolvedTopBlock (block, unreachable);
5034
5035                         if (source != null)
5036                                 source.CloseMethod ();
5037
5038                         base.Emit ();
5039
5040                         if (declarative_security != null) {
5041                                 foreach (DictionaryEntry de in declarative_security) {
5042                                         ConstructorBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
5043                                 }
5044                         }
5045
5046                         block = null;
5047                 }
5048
5049                 // Is never override
5050                 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
5051                 {
5052                         return null;
5053                 }
5054
5055                 public override string GetSignatureForError()
5056                 {
5057                         return base.GetSignatureForError () + Parameters.GetSignatureForError ();
5058                 }
5059
5060                 public override string[] ValidAttributeTargets {
5061                         get {
5062                                 return attribute_targets;
5063                         }
5064                 }
5065
5066                 protected override bool VerifyClsCompliance ()
5067                 {
5068                         if (!base.VerifyClsCompliance () || !IsExposedFromAssembly ()) {
5069                                 return false;
5070                         }
5071                         
5072                         if (ParameterInfo.Count > 0) {
5073                                 ArrayList al = (ArrayList)Parent.MemberCache.Members [".ctor"];
5074                                 if (al.Count > 3)
5075                                         MemberCache.VerifyClsParameterConflict (al, this, ConstructorBuilder);
5076  
5077                                 if (Parent.TypeBuilder.IsSubclassOf (TypeManager.attribute_type)) {
5078                                         foreach (Type param in ParameterTypes) {
5079                                                 if (param.IsArray) {
5080                                                         return true;
5081                                                 }
5082                                         }
5083                                 }
5084                         }
5085                         has_compliant_args = true;
5086                         return true;
5087                 }
5088
5089                 #region IMethodData Members
5090
5091                 public System.Reflection.CallingConventions CallingConventions {
5092                         get {
5093                                 CallingConventions cc = Parameters.CallingConvention;
5094
5095                                 if (Parent.PartialContainer.Kind == Kind.Class)
5096                                         if ((ModFlags & Modifiers.STATIC) == 0)
5097                                                 cc |= CallingConventions.HasThis;
5098
5099                                 // FIXME: How is `ExplicitThis' used in C#?
5100                         
5101                                 return cc;
5102                         }
5103                 }
5104
5105                 public new Location Location {
5106                         get {
5107                                 return base.Location;
5108                         }
5109                 }
5110
5111                 public MemberName MethodName {
5112                         get {
5113                                 return MemberName;
5114                         }
5115                 }
5116
5117                 public Type ReturnType {
5118                         get {
5119                                 return MemberType;
5120                         }
5121                 }
5122
5123                 public EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig)
5124                 {
5125                         ILGenerator ig_ = ConstructorBuilder.GetILGenerator ();
5126                         return new EmitContext (this, Parent, Location, ig_, null, ModFlags, true);
5127                 }
5128
5129                 public bool IsExcluded()
5130                 {
5131                         return false;
5132                 }
5133
5134                 GenericMethod IMethodData.GenericMethod {
5135                         get {
5136                                 return null;
5137                         }
5138                 }
5139
5140                 #endregion
5141         }
5142
5143         /// <summary>
5144         /// Interface for MethodData class. Holds links to parent members to avoid member duplication.
5145         /// </summary>
5146         public interface IMethodData
5147         {
5148                 CallingConventions CallingConventions { get; }
5149                 Location Location { get; }
5150                 MemberName MethodName { get; }
5151                 Type ReturnType { get; }
5152                 GenericMethod GenericMethod { get; }
5153                 Parameters ParameterInfo { get; }
5154
5155                 Iterator Iterator { get; }
5156
5157                 Attributes OptAttributes { get; }
5158                 ToplevelBlock Block { get; set; }
5159
5160                 EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig);
5161                 ObsoleteAttribute GetObsoleteAttribute ();
5162                 string GetSignatureForError ();
5163                 bool IsExcluded ();
5164                 bool IsClsComplianceRequired ();
5165                 void SetMemberIsUsed ();
5166         }
5167
5168         //
5169         // Encapsulates most of the Method's state
5170         //
5171         public class MethodData {
5172
5173                 readonly IMethodData method;
5174
5175                 public readonly GenericMethod GenericMethod;
5176
5177                 //
5178                 // Are we implementing an interface ?
5179                 //
5180                 public MethodInfo implementing;
5181
5182                 //
5183                 // Protected data.
5184                 //
5185                 protected InterfaceMemberBase member;
5186                 protected int modifiers;
5187                 protected MethodAttributes flags;
5188                 protected Type declaring_type;
5189                 protected MethodInfo parent_method;
5190
5191                 MethodBuilder builder = null;
5192                 public MethodBuilder MethodBuilder {
5193                         get {
5194                                 return builder;
5195                         }
5196                 }
5197
5198                 public Type DeclaringType {
5199                         get {
5200                                 return declaring_type;
5201                         }
5202                 }
5203
5204                 public MethodData (InterfaceMemberBase member,
5205                                    int modifiers, MethodAttributes flags, IMethodData method)
5206                 {
5207                         this.member = member;
5208                         this.modifiers = modifiers;
5209                         this.flags = flags;
5210
5211                         this.method = method;
5212                 }
5213
5214                 public MethodData (InterfaceMemberBase member, 
5215                                    int modifiers, MethodAttributes flags, 
5216                                    IMethodData method, MethodBuilder builder,
5217                                    GenericMethod generic, MethodInfo parent_method)
5218                         : this (member, modifiers, flags, method)
5219                 {
5220                         this.builder = builder;
5221                         this.GenericMethod = generic;
5222                         this.parent_method = parent_method;
5223                 }
5224
5225                 public bool Define (DeclSpace parent)
5226                 {
5227                         string name = method.MethodName.Basename;
5228                         string method_name = method.MethodName.FullName;
5229
5230                         TypeContainer container = parent.PartialContainer;
5231
5232                         PendingImplementation pending = container.PendingImplementations;
5233                         if (pending != null){
5234                                 if (member is Indexer) // TODO: test it, but it should work without this IF
5235                                         implementing = pending.IsInterfaceIndexer (
5236                                                 member.InterfaceType, method.ReturnType, method.ParameterInfo);
5237                                 else
5238                                         implementing = pending.IsInterfaceMethod (
5239                                                 member.InterfaceType, name, method.ReturnType, method.ParameterInfo);
5240
5241                                 if (member.InterfaceType != null){
5242                                         if (implementing == null){
5243                                                 if (member is PropertyBase) {
5244                                                         Report.Error (550, method.Location, "`{0}' is an accessor not found in interface member `{1}{2}'",
5245                                                                       method.GetSignatureForError (), TypeManager.CSharpName (member.InterfaceType),
5246                                                                       member.GetSignatureForError ().Substring (member.GetSignatureForError ().LastIndexOf ('.')));
5247
5248                                                 } else {
5249                                                         Report.Error (539, method.Location,
5250                                                                       "`{0}.{1}' in explicit interface declaration is not a member of interface",
5251                                                                       TypeManager.CSharpName (member.InterfaceType), member.ShortName);
5252                                                 }
5253                                                 return false;
5254                                         }
5255                                         if (implementing.IsSpecialName && !(method is AbstractPropertyEventMethod)) {
5256                                                 Report.SymbolRelatedToPreviousError (implementing);
5257                                                 Report.Error (683, method.Location, "`{0}' explicit method implementation cannot implement `{1}' because it is an accessor",
5258                                                         member.GetSignatureForError (), TypeManager.CSharpSignature (implementing));
5259                                                 return false;
5260                                         }
5261
5262                                         method_name = member.InterfaceType.FullName + 
5263                                                 '.' + method_name;
5264                                 } else {
5265                                         if (implementing != null) {
5266                                                 AbstractPropertyEventMethod prop_method = method as AbstractPropertyEventMethod;
5267                                                 if (prop_method == null) {
5268                                                         if (implementing.IsSpecialName) {
5269                                                                 Report.SymbolRelatedToPreviousError (implementing);
5270                                                                 Report.Error (470, method.Location, "Method `{0}' cannot implement interface accessor `{1}.{2}'",
5271                                                                         method.GetSignatureForError (), TypeManager.CSharpSignature (implementing),
5272                                                                         implementing.Name.StartsWith ("get_") ? "get" : "set");
5273                                                                 return false;
5274                                                         }
5275                                                 } else if (implementing.DeclaringType.IsInterface) {
5276                                                         if (!implementing.IsSpecialName) {
5277                                                                 Report.SymbolRelatedToPreviousError (implementing);
5278                                                                 Report.Error (686, method.Location, "Accessor `{0}' cannot implement interface member `{1}' for type `{2}'. Use an explicit interface implementation",
5279                                                                         method.GetSignatureForError (), TypeManager.CSharpSignature (implementing), container.GetSignatureForError ());
5280                                                                 return false;
5281                                                         }
5282                                                         PropertyBase.PropertyMethod pm = prop_method as PropertyBase.PropertyMethod;
5283                                                         if (pm != null && pm.HasCustomAccessModifier && (pm.ModFlags & Modifiers.PUBLIC) == 0) {
5284                                                                 Report.SymbolRelatedToPreviousError (implementing);
5285                                                                 Report.Error (277, method.Location, "Accessor `{0}' must be declared public to implement interface member `{1}'",
5286                                                                         method.GetSignatureForError (), TypeManager.CSharpSignature (implementing, true));
5287                                                                 return false;
5288                                                         }
5289                                                 }
5290                                         }
5291                                 }
5292                         }
5293
5294                         //
5295                         // For implicit implementations, make sure we are public, for
5296                         // explicit implementations, make sure we are private.
5297                         //
5298                         if (implementing != null){
5299                                 //
5300                                 // Setting null inside this block will trigger a more
5301                                 // verbose error reporting for missing interface implementations
5302                                 //
5303                                 // The "candidate" function has been flagged already
5304                                 // but it wont get cleared
5305                                 //
5306                                 if (member.IsExplicitImpl){
5307                                         if (method.ParameterInfo.HasParams && !TypeManager.GetParameterData (implementing).HasParams) {
5308                                                 Report.SymbolRelatedToPreviousError (implementing);
5309                                                 Report.Error (466, method.Location, "`{0}': the explicit interface implementation cannot introduce the params modifier",
5310                                                         method.GetSignatureForError ());
5311                                                 return false;
5312                                         }
5313                                 } else {
5314                                         if (implementing.DeclaringType.IsInterface) {
5315                                                 //
5316                                                 // If this is an interface method implementation,
5317                                                 // check for public accessibility
5318                                                 //
5319                                                 if ((flags & MethodAttributes.MemberAccessMask) != MethodAttributes.Public)
5320                                                 {
5321                                                         implementing = null;
5322                                                 }
5323                                         } else if ((flags & MethodAttributes.MemberAccessMask) == MethodAttributes.Private){
5324                                                 // We may never be private.
5325                                                 implementing = null;
5326
5327                                         } else if ((modifiers & Modifiers.OVERRIDE) == 0){
5328                                                 //
5329                                                 // We may be protected if we're overriding something.
5330                                                 //
5331                                                 implementing = null;
5332                                         }
5333                                 }
5334                                         
5335                                 //
5336                                 // Static is not allowed
5337                                 //
5338                                 if ((modifiers & Modifiers.STATIC) != 0){
5339                                         implementing = null;
5340                                 }
5341                         }
5342                         
5343                         //
5344                         // If implementing is still valid, set flags
5345                         //
5346                         if (implementing != null){
5347                                 //
5348                                 // When implementing interface methods, set NewSlot
5349                                 // unless, we are overwriting a method.
5350                                 //
5351                                 if (implementing.DeclaringType.IsInterface){
5352                                         if ((modifiers & Modifiers.OVERRIDE) == 0)
5353                                                 flags |= MethodAttributes.NewSlot;
5354                                 }
5355                                 flags |=
5356                                         MethodAttributes.Virtual |
5357                                         MethodAttributes.HideBySig;
5358
5359                                 // Set Final unless we're virtual, abstract or already overriding a method.
5360                                 if ((modifiers & (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE)) == 0)
5361                                         flags |= MethodAttributes.Final;
5362                         }
5363
5364                         EmitContext ec = method.CreateEmitContext (container, null);
5365
5366                         DefineMethodBuilder (container, method_name, method.ParameterInfo.Types);
5367
5368                         if (builder == null)
5369                                 return false;
5370
5371                         if (container.CurrentType != null)
5372                                 declaring_type = container.CurrentType;
5373                         else
5374                                 declaring_type = container.TypeBuilder;
5375
5376                         if ((modifiers & Modifiers.UNSAFE) != 0)
5377                                 builder.InitLocals = false;
5378
5379
5380                         if (implementing != null){
5381                                 //
5382                                 // clear the pending implemntation flag
5383                                 //
5384                                 if (member is Indexer) {
5385                                         pending.ImplementIndexer (
5386                                                 member.InterfaceType, builder, method.ReturnType,
5387                                                 method.ParameterInfo, member.IsExplicitImpl);
5388                                 } else
5389                                         pending.ImplementMethod (
5390                                                 member.InterfaceType, name, method.ReturnType,
5391                                                 method.ParameterInfo, member.IsExplicitImpl);
5392
5393                                 if (member.IsExplicitImpl)
5394                                         container.TypeBuilder.DefineMethodOverride (
5395                                                 builder, implementing);
5396                         }
5397
5398                         TypeManager.AddMethod (builder, method);
5399
5400                         if (GenericMethod != null) {
5401                                 bool is_override = member.IsExplicitImpl |
5402                                         ((modifiers & Modifiers.OVERRIDE) != 0);
5403
5404                                 if (implementing != null)
5405                                         parent_method = implementing;
5406
5407                                 if (!GenericMethod.DefineType (ec, builder, parent_method, is_override))
5408                                         return false;
5409                         }
5410
5411                         return true;
5412                 }
5413
5414
5415                 /// <summary>
5416                 /// Create the MethodBuilder for the method 
5417                 /// </summary>
5418                 void DefineMethodBuilder (TypeContainer container, string method_name, Type[] ParameterTypes)
5419                 {
5420                         if (builder == null) {
5421                                 builder = container.TypeBuilder.DefineMethod (
5422                                         method_name, flags, method.CallingConventions,
5423                                         method.ReturnType, ParameterTypes);
5424                                 return;
5425                         }
5426
5427 #if GMCS_SOURCE && !MS_COMPATIBLE
5428                         builder.SetGenericMethodSignature (
5429                                 flags, method.CallingConventions,
5430                                 method.ReturnType, ParameterTypes);
5431 #endif
5432                 }
5433
5434                 //
5435                 // Emits the code
5436                 // 
5437                 public void Emit (DeclSpace parent)
5438                 {
5439                         ToplevelBlock block = method.Block;
5440
5441                         EmitContext ec;
5442                         if (block != null)
5443                                 ec = method.CreateEmitContext (parent, builder.GetILGenerator ());
5444                         else
5445                                 ec = method.CreateEmitContext (parent, null);
5446
5447                         method.ParameterInfo.ApplyAttributes (MethodBuilder);
5448
5449                         if (GenericMethod != null)
5450                                 GenericMethod.EmitAttributes ();
5451                         
5452                         SourceMethod source = SourceMethod.Create (parent, MethodBuilder, method.Block);
5453
5454                         //
5455                         // Handle destructors specially
5456                         //
5457                         // FIXME: This code generates buggy code
5458                         //
5459                         if (member is Destructor)
5460                                 EmitDestructor (ec, block);
5461                         else
5462                                 ec.EmitTopBlock (method, block);
5463
5464                         if (source != null)
5465                                 source.CloseMethod ();
5466                 }
5467
5468                 void EmitDestructor (EmitContext ec, ToplevelBlock block)
5469                 {
5470                         ILGenerator ig = ec.ig;
5471                         
5472                         Label finish = ig.DefineLabel ();
5473
5474                         block.SetDestructor ();
5475                         
5476                         ig.BeginExceptionBlock ();
5477                         ec.ReturnLabel = finish;
5478                         ec.HasReturnLabel = true;
5479                         ec.EmitTopBlock (method, block);
5480                         
5481                         // ig.MarkLabel (finish);
5482                         ig.BeginFinallyBlock ();
5483                         
5484                         if (ec.ContainerType.BaseType != null) {
5485                                 Expression member_lookup = Expression.MemberLookup (
5486                                         ec.ContainerType.BaseType, null, ec.ContainerType.BaseType,
5487                                         "Finalize", MemberTypes.Method, Expression.AllBindingFlags, method.Location);
5488
5489                                 if (member_lookup != null){
5490                                         MethodGroupExpr base_destructor = ((MethodGroupExpr) member_lookup);
5491                                 
5492                                         ig.Emit (OpCodes.Ldarg_0);
5493                                         ig.Emit (OpCodes.Call, (MethodInfo) base_destructor.Methods [0]);
5494                                 }
5495                         }
5496                         
5497                         ig.EndExceptionBlock ();
5498                         //ig.MarkLabel (ec.ReturnLabel);
5499                         ig.Emit (OpCodes.Ret);
5500                 }
5501         }
5502
5503         // TODO: Should derive from MethodCore
5504         public class Destructor : Method {
5505
5506                 static string[] attribute_targets = new string [] { "method" };
5507
5508                 public Destructor (DeclSpace parent, Expression return_type, int mod,
5509                                    string name, Parameters parameters, Attributes attrs,
5510                                    Location l)
5511                         : base (parent, null, return_type, mod, false, new MemberName (name, l),
5512                                 parameters, attrs)
5513                 { }
5514
5515                 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
5516                 {
5517                         if (a.Type == TypeManager.conditional_attribute_type) {
5518                                 Error_ConditionalAttributeIsNotValid ();
5519                                 return;
5520                         }
5521
5522                         base.ApplyAttributeBuilder (a, cb);
5523                 }
5524
5525                 public override string GetSignatureForError ()
5526                 {
5527                         return Parent.GetSignatureForError () + ".~" + Parent.MemberName.Name + "()";
5528                 }
5529
5530                 public override string[] ValidAttributeTargets {
5531                         get {
5532                                 return attribute_targets;
5533                         }
5534                 }
5535         }
5536         
5537         abstract public class MemberBase : MemberCore {
5538                 public Expression Type;
5539                 public readonly DeclSpace ds;
5540                 public readonly GenericMethod GenericMethod;
5541
5542                 //
5543                 // The type of this property / indexer / event
5544                 //
5545                 protected Type member_type;
5546                 public Type MemberType {
5547                         get {
5548                                 if (member_type == null && Type != null) {
5549                                         IResolveContext rc = GenericMethod == null ? this : (IResolveContext)ds;
5550                                         Type = Type.ResolveAsTypeTerminal (rc, false);
5551                                         if (Type != null) {
5552                                                 member_type = Type.Type;
5553                                         }
5554                                 }
5555                                 return member_type;
5556                         }
5557                 }
5558
5559                 //
5560                 // The constructor is only exposed to our children
5561                 //
5562                 protected MemberBase (DeclSpace parent, GenericMethod generic,
5563                                       Expression type, int mod, int allowed_mod, int def_mod,
5564                                       MemberName name, Attributes attrs)
5565                         : base (parent, name, attrs)
5566                 {
5567                         this.ds = generic != null ? generic : (DeclSpace) parent;
5568                         Type = type;
5569                         ModFlags = Modifiers.Check (allowed_mod, mod, def_mod, Location);
5570                         GenericMethod = generic;
5571                         if (GenericMethod != null)
5572                                 GenericMethod.ModFlags = ModFlags;
5573                 }
5574
5575                 protected virtual bool CheckBase ()
5576                 {
5577                         if ((ModFlags & Modifiers.PROTECTED) != 0 && Parent.PartialContainer.Kind == Kind.Struct) {
5578                                 Report.Error (666, Location, "`{0}': new protected member declared in struct", GetSignatureForError ());
5579                                 return false;
5580                         }
5581    
5582                         if ((RootContext.WarningLevel >= 4) &&
5583                             ((Parent.ModFlags & Modifiers.SEALED) != 0) &&
5584                             ((ModFlags & Modifiers.PROTECTED) != 0) &&
5585                             ((ModFlags & Modifiers.OVERRIDE) == 0) && (Name != "Finalize")) {
5586                                 Report.Warning (628, 4, Location, "`{0}': new protected member declared in sealed class", GetSignatureForError ());
5587                         }
5588                                 return true;
5589                 }
5590
5591                 protected virtual bool DoDefine ()
5592                 {
5593                         if (MemberType == null)
5594                                 return false;
5595
5596                         if ((Parent.ModFlags & Modifiers.SEALED) != 0 && 
5597                                 (ModFlags & (Modifiers.VIRTUAL|Modifiers.ABSTRACT)) != 0) {
5598                                         Report.Error (549, Location, "New virtual member `{0}' is declared in a sealed class `{1}'",
5599                                                 GetSignatureForError (), Parent.GetSignatureForError ());
5600                                         return false;
5601                         }
5602                         
5603                         // verify accessibility
5604                         if (!Parent.AsAccessible (MemberType, ModFlags)) {
5605                                 Report.SymbolRelatedToPreviousError (MemberType);
5606                                 if (this is Property)
5607                                         Report.Error (53, Location,
5608                                                       "Inconsistent accessibility: property type `" +
5609                                                       TypeManager.CSharpName (MemberType) + "' is less " +
5610                                                       "accessible than property `" + GetSignatureForError () + "'");
5611                                 else if (this is Indexer)
5612                                         Report.Error (54, Location,
5613                                                       "Inconsistent accessibility: indexer return type `" +
5614                                                       TypeManager.CSharpName (MemberType) + "' is less " +
5615                                                       "accessible than indexer `" + GetSignatureForError () + "'");
5616                                 else if (this is MethodCore) {
5617                                         if (this is Operator)
5618                                                 Report.Error (56, Location,
5619                                                               "Inconsistent accessibility: return type `" +
5620                                                               TypeManager.CSharpName (MemberType) + "' is less " +
5621                                                               "accessible than operator `" + GetSignatureForError () + "'");
5622                                         else
5623                                                 Report.Error (50, Location,
5624                                                               "Inconsistent accessibility: return type `" +
5625                                                               TypeManager.CSharpName (MemberType) + "' is less " +
5626                                                               "accessible than method `" + GetSignatureForError () + "'");
5627                                 } else {
5628                                         Report.Error (52, Location,
5629                                                       "Inconsistent accessibility: field type `" +
5630                                                       TypeManager.CSharpName (MemberType) + "' is less " +
5631                                                       "accessible than field `" + GetSignatureForError () + "'");
5632                                 }
5633                                 return false;
5634                         }
5635
5636                         return true;
5637                 }
5638
5639                 protected bool IsTypePermitted ()
5640                 {
5641                         if (MemberType == TypeManager.arg_iterator_type || MemberType == TypeManager.typed_reference_type) {
5642                                 Report.Error (610, Location, "Field or property cannot be of type `{0}'", TypeManager.CSharpName (MemberType));
5643                                 return false;
5644                         }
5645                         return true;
5646                 }
5647         }
5648
5649         //
5650         // Abstract class for all fields
5651         //
5652         abstract public class FieldBase : MemberBase {
5653                 public FieldBuilder FieldBuilder;
5654                 public Status status;
5655                 protected Expression initializer;
5656
5657                 [Flags]
5658                 public enum Status : byte {
5659                         HAS_OFFSET = 4          // Used by FieldMember.
5660                 }
5661
5662                 static readonly string[] attribute_targets = new string [] { "field" };
5663
5664                 protected FieldBase (DeclSpace parent, Expression type, int mod,
5665                                      int allowed_mod, MemberName name, Attributes attrs)
5666                         : base (parent, null, type, mod, allowed_mod | Modifiers.ABSTRACT, Modifiers.PRIVATE,
5667                                 name, attrs)
5668                 {
5669                         if ((mod & Modifiers.ABSTRACT) != 0)
5670                                 Report.Error (681, Location, "The modifier 'abstract' is not valid on fields. Try using a property instead");
5671                 }
5672
5673                 public override AttributeTargets AttributeTargets {
5674                         get {
5675                                 return AttributeTargets.Field;
5676                         }
5677                 }
5678
5679                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
5680                 {
5681                         if (a.Type == TypeManager.field_offset_attribute_type) {
5682                                 status |= Status.HAS_OFFSET;
5683
5684                                 if (!Parent.PartialContainer.HasExplicitLayout) {
5685                                         Report.Error (636, Location, "The FieldOffset attribute can only be placed on members of types marked with the StructLayout(LayoutKind.Explicit)");
5686                                         return;
5687                                 }
5688
5689                                 if ((ModFlags & Modifiers.STATIC) != 0 || this is Const) {
5690                                         Report.Error (637, Location, "The FieldOffset attribute is not allowed on static or const fields");
5691                                         return;
5692                                 }
5693                         }
5694
5695 #if NET_2_0
5696                         if (a.Type == TypeManager.fixed_buffer_attr_type) {
5697                                 Report.Error (1716, Location, "Do not use 'System.Runtime.CompilerServices.FixedBuffer' attribute. Use the 'fixed' field modifier instead");
5698                                 return;
5699                         }
5700 #endif
5701
5702                         if (a.Type == TypeManager.marshal_as_attr_type) {
5703                                 UnmanagedMarshal marshal = a.GetMarshal (this);
5704                                 if (marshal != null) {
5705                                         FieldBuilder.SetMarshal (marshal);
5706                                 }
5707                                 return;
5708                         }
5709
5710                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
5711                                 a.Error_InvalidSecurityParent ();
5712                                 return;
5713                         }
5714
5715                         FieldBuilder.SetCustomAttribute (cb);
5716                 }
5717
5718                 protected override bool CheckBase ()
5719                 {
5720                         if (!base.CheckBase ())
5721                                 return false;
5722  
5723                         MemberInfo conflict_symbol = Parent.PartialContainer.FindBaseMemberWithSameName (Name, false);
5724                         if (conflict_symbol == null) {
5725                                 if ((ModFlags & Modifiers.NEW) != 0) {
5726                                         Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
5727                                 }
5728                                 return true;
5729                         }
5730  
5731                         if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE)) == 0) {
5732                                 Report.SymbolRelatedToPreviousError (conflict_symbol);
5733                                 Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
5734                                         GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
5735                         }
5736  
5737                         return true;
5738                 }
5739
5740                 public override bool Define()
5741                 {
5742                         if (MemberType == null || Type == null)
5743                                 return false;
5744
5745                         if (TypeManager.IsGenericParameter (MemberType))
5746                                 return true;
5747
5748                         if (MemberType == TypeManager.void_type) {
5749                                 // TODO: wrong location
5750                                 Expression.Error_VoidInvalidInTheContext (Location);
5751                                 return false;
5752                         }
5753
5754                         if (MemberType.IsSealed && MemberType.IsAbstract) {
5755                                 Error_VariableOfStaticClass (Location, GetSignatureForError (), MemberType);
5756                                 return false;
5757                         }
5758
5759                         if (!CheckBase ())
5760                                 return false;
5761                         
5762                         if (!Parent.AsAccessible (MemberType, ModFlags)) {
5763                                 Report.Error (52, Location,
5764                                         "Inconsistent accessibility: field type `" +
5765                                         TypeManager.CSharpName (MemberType) + "' is less " +
5766                                         "accessible than field `" + GetSignatureForError () + "'");
5767                                 return false;
5768                         }
5769
5770                         if (!IsTypePermitted ())
5771                                 return false;
5772
5773                         return true;
5774                 }
5775
5776                 //
5777                 //   Represents header string for documentation comment.
5778                 //
5779                 public override string DocCommentHeader {
5780                         get { return "F:"; }
5781                 }
5782
5783                 public override void Emit ()
5784                 {
5785                         if (OptAttributes != null) {
5786                                 OptAttributes.Emit ();
5787                         }
5788
5789                         if (((status & Status.HAS_OFFSET) == 0) && (ModFlags & Modifiers.STATIC) == 0 && Parent.PartialContainer.HasExplicitLayout) {
5790                                 Report.Error (625, Location, "`{0}': Instance field types marked with StructLayout(LayoutKind.Explicit) must have a FieldOffset attribute.", GetSignatureForError ());
5791                         }
5792
5793                         base.Emit ();
5794                 }
5795
5796                 public static void Error_VariableOfStaticClass (Location loc, string variableName, Type staticClass)
5797                 {
5798                         Report.SymbolRelatedToPreviousError (staticClass);
5799                         Report.Error (723, loc, "`{0}': cannot declare variables of static types",
5800                                 variableName);
5801                 }
5802
5803                 public Expression Initializer {
5804                         set {
5805                                 if (value != null) {
5806                                         this.initializer = value;
5807                                 }
5808                         }
5809                 }
5810
5811                 protected virtual bool IsFieldClsCompliant {
5812                         get {
5813                                 if (FieldBuilder == null)
5814                                         return true;
5815
5816                                 return AttributeTester.IsClsCompliant (FieldBuilder.FieldType);
5817                         }
5818                 }
5819
5820                 public override string[] ValidAttributeTargets 
5821                 {
5822                         get {
5823                                 return attribute_targets;
5824                         }
5825                 }
5826
5827                 protected override bool VerifyClsCompliance ()
5828                 {
5829                         if (!base.VerifyClsCompliance ())
5830                                 return false;
5831
5832                         if (!IsFieldClsCompliant) {
5833                                 Report.Error (3003, Location, "Type of `{0}' is not CLS-compliant", GetSignatureForError ());
5834                         }
5835                         return true;
5836                 }
5837
5838                 public void SetAssigned ()
5839                 {
5840                         caching_flags |= Flags.IsAssigned;
5841                 }
5842         }
5843
5844         interface IFixedBuffer
5845         {
5846                 FieldInfo Element { get; }
5847                 Type ElementType { get; }
5848         }
5849
5850         public class FixedFieldExternal: IFixedBuffer
5851         {
5852                 FieldInfo element_field;
5853
5854                 public FixedFieldExternal (FieldInfo fi)
5855                 {
5856                         element_field = fi.FieldType.GetField (FixedField.FixedElementName);
5857                 }
5858
5859                 #region IFixedField Members
5860
5861                 public FieldInfo Element {
5862                         get {
5863                                 return element_field;
5864                         }
5865                 }
5866
5867                 public Type ElementType {
5868                         get {
5869                                 return element_field.FieldType;
5870                         }
5871                 }
5872
5873                 #endregion
5874         }
5875
5876         /// <summary>
5877         /// Fixed buffer implementation
5878         /// </summary>
5879         public class FixedField : FieldBase, IFixedBuffer
5880         {
5881                 public const string FixedElementName = "FixedElementField";
5882                 static int GlobalCounter = 0;
5883                 static object[] ctor_args = new object[] { (short)LayoutKind.Sequential };
5884                 static FieldInfo[] fi;
5885
5886                 TypeBuilder fixed_buffer_type;
5887                 FieldBuilder element;
5888                 Expression size_expr;
5889                 int buffer_size;
5890
5891                 const int AllowedModifiers =
5892                         Modifiers.NEW |
5893                         Modifiers.PUBLIC |
5894                         Modifiers.PROTECTED |
5895                         Modifiers.INTERNAL |
5896                         Modifiers.PRIVATE;
5897
5898                 public FixedField (DeclSpace parent, Expression type, int mod, string name,
5899                         Expression size_expr, Attributes attrs, Location loc):
5900                         base (parent, type, mod, AllowedModifiers, new MemberName (name, loc), attrs)
5901                 {
5902                         if (RootContext.Version == LanguageVersion.ISO_1)
5903                                 Report.FeatureIsNotISO1 (loc, "fixed size buffers");
5904
5905                         this.size_expr = size_expr;
5906                 }
5907
5908                 public override bool Define()
5909                 {
5910 #if !NET_2_0
5911                         if ((ModFlags & (Modifiers.PUBLIC | Modifiers.PROTECTED)) != 0)
5912                                 Report.Warning (-23, 1, Location, "Only private or internal fixed sized buffers are supported by .NET 1.x");
5913 #endif
5914
5915                         if (Parent.PartialContainer.Kind != Kind.Struct) {
5916                                 Report.Error (1642, Location, "`{0}': Fixed size buffer fields may only be members of structs",
5917                                         GetSignatureForError ());
5918                                 return false;
5919                         }
5920
5921                         if (!base.Define ())
5922                                 return false;
5923
5924                         if (!TypeManager.IsPrimitiveType (MemberType)) {
5925                                 Report.Error (1663, Location, "`{0}': Fixed size buffers type must be one of the following: bool, byte, short, int, long, char, sbyte, ushort, uint, ulong, float or double",
5926                                         GetSignatureForError ());
5927                                 return false;
5928                         }
5929
5930                         EmitContext ec = new EmitContext (this, Parent, Location, null, null, ModFlags);
5931                         Constant c = size_expr.ResolveAsConstant (ec, this);
5932                         if (c == null)
5933                                 return false;
5934
5935                         IntConstant buffer_size_const = c.ImplicitConversionRequired (TypeManager.int32_type, Location) as IntConstant;
5936                         if (buffer_size_const == null)
5937                                 return false;
5938
5939                         buffer_size = buffer_size_const.Value;
5940
5941                         if (buffer_size <= 0) {
5942                                 Report.Error (1665, Location, "`{0}': Fixed size buffers must have a length greater than zero", GetSignatureForError ());
5943                                 return false;
5944                         }
5945
5946                         int type_size = Expression.GetTypeSize (MemberType);
5947
5948                         if (buffer_size > int.MaxValue / type_size) {
5949                                 Report.Error (1664, Location, "Fixed size buffer `{0}' of length `{1}' and type `{2}' exceeded 2^31 limit",
5950                                         GetSignatureForError (), buffer_size.ToString (), TypeManager.CSharpName (MemberType));
5951                                 return false;
5952                         }
5953
5954                         buffer_size *= type_size;
5955
5956                         // Define nested
5957                         string name = String.Format ("<{0}>__FixedBuffer{1}", Name, GlobalCounter++);
5958
5959                         fixed_buffer_type = Parent.TypeBuilder.DefineNestedType (name,
5960                                 TypeAttributes.NestedPublic | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit, TypeManager.value_type);
5961                         element = fixed_buffer_type.DefineField (FixedElementName, MemberType, FieldAttributes.Public);
5962                         RootContext.RegisterCompilerGeneratedType (fixed_buffer_type);
5963
5964                         FieldBuilder = Parent.TypeBuilder.DefineField (Name, fixed_buffer_type, Modifiers.FieldAttr (ModFlags));
5965                         TypeManager.RegisterFieldBase (FieldBuilder, this);
5966
5967                         return true;
5968                 }
5969
5970                 public override void Emit()
5971                 {
5972                         if (fi == null)
5973                                 fi = new FieldInfo [] { TypeManager.struct_layout_attribute_type.GetField ("Size") };
5974
5975                         object[] fi_val = new object[1];
5976                         fi_val [0] = buffer_size;
5977
5978                         CustomAttributeBuilder cab = new CustomAttributeBuilder (TypeManager.struct_layout_attribute_ctor, 
5979                                 ctor_args, fi, fi_val);
5980                         fixed_buffer_type.SetCustomAttribute (cab);
5981
5982 #if NET_2_0
5983                         cab = new CustomAttributeBuilder (TypeManager.fixed_buffer_attr_ctor, new object[] { MemberType, buffer_size } );
5984                         FieldBuilder.SetCustomAttribute (cab);
5985 #endif
5986                         base.Emit ();
5987                 }
5988
5989                 protected override bool IsFieldClsCompliant {
5990                         get {
5991                                 return false;
5992                         }
5993                 }
5994
5995                 #region IFixedField Members
5996
5997                 public FieldInfo Element {
5998                         get {
5999                                 return element;
6000                         }
6001                 }
6002
6003                 public Type ElementType {
6004                         get {
6005                                 return MemberType;
6006                         }
6007                 }
6008
6009                 #endregion
6010         }
6011
6012         //
6013         // The Field class is used to represents class/struct fields during parsing.
6014         //
6015         public class Field : FieldBase {
6016                 // <summary>
6017                 //   Modifiers allowed in a class declaration
6018                 // </summary>
6019                 const int AllowedModifiers =
6020                         Modifiers.NEW |
6021                         Modifiers.PUBLIC |
6022                         Modifiers.PROTECTED |
6023                         Modifiers.INTERNAL |
6024                         Modifiers.PRIVATE |
6025                         Modifiers.STATIC |
6026                         Modifiers.VOLATILE |
6027                         Modifiers.UNSAFE |
6028                         Modifiers.READONLY;
6029
6030                 public Field (DeclSpace parent, Expression type, int mod, string name,
6031                               Attributes attrs, Location loc)
6032                         : base (parent, type, mod, AllowedModifiers, new MemberName (name, loc),
6033                                 attrs)
6034                 {
6035                 }
6036
6037                 public override bool Define ()
6038                 {
6039                         if (!base.Define ())
6040                                 return false;
6041
6042                         if (RootContext.WarningLevel > 1){
6043                                 Type ptype = Parent.TypeBuilder.BaseType;
6044
6045                                 // ptype is only null for System.Object while compiling corlib.
6046                                 if (ptype != null){
6047                                         TypeContainer.FindMembers (
6048                                                 ptype, MemberTypes.Method,
6049                                                 BindingFlags.Public |
6050                                                 BindingFlags.Static | BindingFlags.Instance,
6051                                                 System.Type.FilterName, Name);
6052                                 }
6053                         }
6054
6055                         if ((ModFlags & Modifiers.VOLATILE) != 0){
6056                                 if (!MemberType.IsClass){
6057                                         Type vt = MemberType;
6058                                         
6059                                         if (TypeManager.IsEnumType (vt))
6060                                                 vt = TypeManager.EnumToUnderlying (MemberType);
6061
6062                                         if (!((vt == TypeManager.bool_type) ||
6063                                               (vt == TypeManager.sbyte_type) ||
6064                                               (vt == TypeManager.byte_type) ||
6065                                               (vt == TypeManager.short_type) ||
6066                                               (vt == TypeManager.ushort_type) ||
6067                                               (vt == TypeManager.int32_type) ||
6068                                               (vt == TypeManager.uint32_type) ||    
6069                                               (vt == TypeManager.char_type) ||
6070                                               (vt == TypeManager.float_type) ||
6071                                               (!vt.IsValueType))){
6072                                                 Report.Error (677, Location, "`{0}': A volatile field cannot be of the type `{1}'",
6073                                                         GetSignatureForError (), TypeManager.CSharpName (vt));
6074                                                 return false;
6075                                         }
6076                                 }
6077
6078                                 if ((ModFlags & Modifiers.READONLY) != 0){
6079                                         Report.Error (678, Location, "`{0}': A field cannot be both volatile and readonly",
6080                                                 GetSignatureForError ());
6081                                         return false;
6082                                 }
6083                         }
6084
6085                         FieldAttributes fa = Modifiers.FieldAttr (ModFlags);
6086
6087                         if (Parent.PartialContainer.Kind == Kind.Struct && 
6088                             ((fa & FieldAttributes.Static) == 0) &&
6089                             MemberType == Parent.TypeBuilder &&
6090                             !TypeManager.IsBuiltinType (MemberType)){
6091                                 Report.Error (523, Location, "Struct member `" + Parent.Name + "." + Name + 
6092                                               "' causes a cycle in the structure layout");
6093                                 return false;
6094                         }
6095
6096                         try {
6097                                 FieldBuilder = Parent.TypeBuilder.DefineField (
6098                                         Name, MemberType, Modifiers.FieldAttr (ModFlags));
6099
6100                                 TypeManager.RegisterFieldBase (FieldBuilder, this);
6101                         }
6102                         catch (ArgumentException) {
6103                                 Report.Warning (-24, 1, Location, "The Microsoft runtime is unable to use [void|void*] as a field type, try using the Mono runtime.");
6104                                 return false;
6105                         }
6106
6107                         if (initializer != null)
6108                                 Parent.PartialContainer.RegisterFieldForInitialization (this,
6109                                         new FieldInitializer (FieldBuilder, initializer, Parent));
6110
6111                         return true;
6112                 }
6113
6114                 protected override bool VerifyClsCompliance ()
6115                 {
6116                         if (!base.VerifyClsCompliance ())
6117                                 return false;
6118
6119                         if ((ModFlags & Modifiers.VOLATILE) != 0) {
6120                                 Report.Warning (3026, 1, Location, "CLS-compliant field `{0}' cannot be volatile", GetSignatureForError ());
6121                         }
6122
6123                         return true;
6124                 }
6125         }
6126
6127         //
6128         // `set' and `get' accessors are represented with an Accessor.
6129         // 
6130         public class Accessor : IAnonymousHost {
6131                 //
6132                 // Null if the accessor is empty, or a Block if not
6133                 //
6134                 public const int AllowedModifiers = 
6135                         Modifiers.PUBLIC |
6136                         Modifiers.PROTECTED |
6137                         Modifiers.INTERNAL |
6138                         Modifiers.PRIVATE;
6139                 
6140                 public ToplevelBlock Block;
6141                 public Attributes Attributes;
6142                 public Location Location;
6143                 public int ModFlags;
6144                 public bool Yields;
6145                 public ArrayList AnonymousMethods;
6146                 
6147                 public Accessor (ToplevelBlock b, int mod, Attributes attrs, Location loc)
6148                 {
6149                         Block = b;
6150                         Attributes = attrs;
6151                         Location = loc;
6152                         ModFlags = Modifiers.Check (AllowedModifiers, mod, 0, loc);
6153                 }
6154
6155                 public void SetYields ()
6156                 {
6157                         Yields = true;
6158                 }
6159
6160                 public void AddAnonymousMethod (AnonymousMethodExpression ame)
6161                 {
6162                         if (AnonymousMethods == null)
6163                                 AnonymousMethods = new ArrayList ();
6164                         AnonymousMethods.Add (ame);
6165                 }
6166         }
6167
6168         // Ooouh Martin, templates are missing here.
6169         // When it will be possible move here a lot of child code and template method type.
6170         public abstract class AbstractPropertyEventMethod : MemberCore, IMethodData {
6171                 protected MethodData method_data;
6172                 protected ToplevelBlock block;
6173                 protected ListDictionary declarative_security;
6174
6175                 // The accessor are created event if they are not wanted.
6176                 // But we need them because their names are reserved.
6177                 // Field says whether accessor will be emited or not
6178                 public readonly bool IsDummy;
6179
6180                 protected readonly string prefix;
6181
6182                 ReturnParameter return_attributes;
6183
6184                 public AbstractPropertyEventMethod (PropertyBasedMember member, string prefix)
6185                         : base (member.Parent, SetupName (prefix, member, member.Location), null)
6186                 {
6187                         this.prefix = prefix;
6188                         IsDummy = true;
6189                 }
6190
6191                 public AbstractPropertyEventMethod (InterfaceMemberBase member, Accessor accessor,
6192                                                     string prefix)
6193                         : base (member.Parent, SetupName (prefix, member, accessor.Location),
6194                                 accessor.Attributes)
6195                 {
6196                         this.prefix = prefix;
6197                         this.block = accessor.Block;
6198                 }
6199
6200                 static MemberName SetupName (string prefix, InterfaceMemberBase member, Location loc)
6201                 {
6202                         return new MemberName (member.MemberName.Left, prefix + member.ShortName, loc);
6203                 }
6204
6205                 public void UpdateName (InterfaceMemberBase member)
6206                 {
6207                         SetMemberName (SetupName (prefix, member, Location));
6208                 }
6209
6210                 #region IMethodData Members
6211
6212                 public abstract Iterator Iterator {
6213                         get;
6214                 }
6215
6216                 public ToplevelBlock Block {
6217                         get {
6218                                 return block;
6219                         }
6220
6221                         set {
6222                                 block = value;
6223                         }
6224                 }
6225
6226                 public CallingConventions CallingConventions {
6227                         get {
6228                                 return CallingConventions.Standard;
6229                         }
6230                 }
6231
6232                 public bool IsExcluded ()
6233                 {
6234                         return false;
6235                 }
6236
6237                 GenericMethod IMethodData.GenericMethod {
6238                         get {
6239                                 return null;
6240                         }
6241                 }
6242
6243                 public MemberName MethodName {
6244                         get {
6245                                 return MemberName;
6246                         }
6247                 }
6248
6249                 public Type[] ParameterTypes { 
6250                         get {
6251                                 return ParameterInfo.Types;
6252                         }
6253                 }
6254
6255                 public abstract Parameters ParameterInfo { get ; }
6256                 public abstract Type ReturnType { get; }
6257                 public abstract EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig);
6258
6259                 #endregion
6260
6261                 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
6262                 {
6263                         if (a.Type == TypeManager.cls_compliant_attribute_type || a.Type == TypeManager.obsolete_attribute_type ||
6264                                         a.Type == TypeManager.conditional_attribute_type) {
6265                                 Report.Error (1667, a.Location,
6266                                         "Attribute `{0}' is not valid on property or event accessors. It is valid on `{1}' declarations only",
6267                                         TypeManager.CSharpName (a.Type), a.GetValidTargets ());
6268                                 return;
6269                         }
6270
6271                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
6272                                 if (declarative_security == null)
6273                                         declarative_security = new ListDictionary ();
6274                                 a.ExtractSecurityPermissionSet (declarative_security);
6275                                 return;
6276                         }
6277
6278                         if (a.Target == AttributeTargets.Method) {
6279                                 method_data.MethodBuilder.SetCustomAttribute (cb);
6280                                 return;
6281                         }
6282
6283                         if (a.Target == AttributeTargets.ReturnValue) {
6284                                 if (return_attributes == null)
6285                                         return_attributes = new ReturnParameter (method_data.MethodBuilder, Location);
6286
6287                                 return_attributes.ApplyAttributeBuilder (a, cb);
6288                                 return;
6289                         }
6290
6291                         ApplyToExtraTarget (a, cb);
6292                 }
6293
6294                 virtual protected void ApplyToExtraTarget (Attribute a, CustomAttributeBuilder cb)
6295                 {
6296                         System.Diagnostics.Debug.Fail ("You forgot to define special attribute target handling");
6297                 }
6298
6299                 // It is not supported for the accessors
6300                 public sealed override bool Define()
6301                 {
6302                         throw new NotSupportedException ();
6303                 }
6304
6305                 public void Emit (DeclSpace parent)
6306                 {
6307                         EmitMethod (parent);
6308
6309                         if (OptAttributes != null)
6310                                 OptAttributes.Emit ();
6311
6312                         if (declarative_security != null) {
6313                                 foreach (DictionaryEntry de in declarative_security) {
6314                                         method_data.MethodBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
6315                                 }
6316                         }
6317
6318                         block = null;
6319                 }
6320
6321                 protected virtual void EmitMethod (DeclSpace parent)
6322                 {
6323                         method_data.Emit (parent);
6324                 }
6325
6326                 public override bool IsClsComplianceRequired()
6327                 {
6328                         return false;
6329                 }
6330
6331                 public bool IsDuplicateImplementation (MethodCore method)
6332                 {
6333                         if (!MemberName.Equals (method.MemberName))
6334                                 return false;
6335
6336                         Type[] param_types = method.ParameterTypes;
6337
6338                         if (param_types.Length != ParameterTypes.Length)
6339                                 return false;
6340
6341                         for (int i = 0; i < param_types.Length; i++)
6342                                 if (param_types [i] != ParameterTypes [i])
6343                                         return false;
6344
6345                         Report.SymbolRelatedToPreviousError (method);
6346                         Report.Error (111, Location, TypeContainer.Error111, method.GetSignatureForError ());
6347                         return true;
6348                 }
6349
6350                 public override bool IsUsed
6351                 {
6352                         get {
6353                                 if (IsDummy)
6354                                         return false;
6355
6356                                 return base.IsUsed;
6357                         }
6358                 }
6359
6360                 public new Location Location { 
6361                         get {
6362                                 return base.Location;
6363                         }
6364                 }
6365
6366                 public virtual bool ResolveMembers ()
6367                 {
6368                         return true;
6369                 }
6370
6371                 //
6372                 //   Represents header string for documentation comment.
6373                 //
6374                 public override string DocCommentHeader {
6375                         get { throw new InvalidOperationException ("Unexpected attempt to get doc comment from " + this.GetType () + "."); }
6376                 }
6377
6378         }
6379
6380         //
6381         // Properties and Indexers both generate PropertyBuilders, we use this to share 
6382         // their common bits.
6383         //
6384         abstract public class PropertyBase : PropertyBasedMember {
6385
6386                 public class GetMethod : PropertyMethod
6387                 {
6388                         static string[] attribute_targets = new string [] { "method", "return" };
6389
6390                         public GetMethod (PropertyBase method):
6391                                 base (method, "get_")
6392                         {
6393                         }
6394
6395                         public GetMethod (PropertyBase method, Accessor accessor):
6396                                 base (method, accessor, "get_")
6397                         {
6398                         }
6399
6400                         public override MethodBuilder Define (DeclSpace parent)
6401                         {
6402                                 base.Define (parent);
6403                                 
6404                                 method_data = new MethodData (method, ModFlags, flags, this);
6405
6406                                 if (!method_data.Define (parent))
6407                                         return null;
6408
6409                                 return method_data.MethodBuilder;
6410                         }
6411
6412                         public override Type ReturnType {
6413                                 get {
6414                                         return method.MemberType;
6415                                 }
6416                         }
6417
6418                         public override Parameters ParameterInfo {
6419                                 get {
6420                                         return Parameters.EmptyReadOnlyParameters;
6421                                 }
6422                         }
6423
6424                         public override string[] ValidAttributeTargets {
6425                                 get {
6426                                         return attribute_targets;
6427                                 }
6428                         }
6429                 }
6430
6431                 public class SetMethod : PropertyMethod {
6432
6433                         static string[] attribute_targets = new string [] { "method", "param", "return" };
6434                         ImplicitParameter param_attr;
6435                         protected Parameters parameters;
6436
6437                         public SetMethod (PropertyBase method):
6438                                 base (method, "set_")
6439                         {
6440                         }
6441
6442                         public SetMethod (PropertyBase method, Accessor accessor):
6443                                 base (method, accessor, "set_")
6444                         {
6445                         }
6446
6447                         protected override void ApplyToExtraTarget(Attribute a, CustomAttributeBuilder cb)
6448                         {
6449                                 if (a.Target == AttributeTargets.Parameter) {
6450                                         if (param_attr == null)
6451                                                 param_attr = new ImplicitParameter (method_data.MethodBuilder);
6452
6453                                         param_attr.ApplyAttributeBuilder (a, cb);
6454                                         return;
6455                                 }
6456
6457                                 base.ApplyAttributeBuilder (a, cb);
6458                         }
6459
6460                         public override Parameters ParameterInfo {
6461                                 get {
6462                                         if (parameters == null)
6463                                                 DefineParameters ();
6464                                         return parameters;
6465                                 }
6466                         }
6467
6468                         protected virtual void DefineParameters ()
6469                         {
6470                                 parameters = new Parameters (
6471                                         new Parameter[] { new Parameter (method.MemberType, "value", Parameter.Modifier.NONE, null, Location) },
6472                                         new Type[] { method.MemberType });
6473                         }
6474
6475                         public override MethodBuilder Define (DeclSpace parent)
6476                         {
6477                                 if (IsDummy)
6478                                         return null;
6479
6480                                 base.Define (parent);
6481
6482                                 method_data = new MethodData (method, ModFlags, flags, this);
6483
6484                                 if (!method_data.Define (parent))
6485                                         return null;
6486
6487                                 return method_data.MethodBuilder;
6488                         }
6489
6490                         public override Type ReturnType {
6491                                 get {
6492                                         return TypeManager.void_type;
6493                                 }
6494                         }
6495
6496                         public override string[] ValidAttributeTargets {
6497                                 get {
6498                                         return attribute_targets;
6499                                 }
6500                         }
6501                 }
6502
6503                 static string[] attribute_targets = new string [] { "property" };
6504
6505                 public abstract class PropertyMethod : AbstractPropertyEventMethod
6506                 {
6507                         protected readonly PropertyBase method;
6508                         protected MethodAttributes flags;
6509                         Iterator iterator;
6510                         ArrayList anonymous_methods;
6511                         bool yields;
6512
6513                         public PropertyMethod (PropertyBase method, string prefix)
6514                                 : base (method, prefix)
6515                         {
6516                                 this.method = method;
6517                         }
6518
6519                         public PropertyMethod (PropertyBase method, Accessor accessor,
6520                                                string prefix)
6521                                 : base (method, accessor, prefix)
6522                         {
6523                                 this.method = method;
6524                                 this.ModFlags = accessor.ModFlags;
6525                                 yields = accessor.Yields;
6526                                 anonymous_methods = accessor.AnonymousMethods;
6527
6528                                 if (accessor.ModFlags != 0 && RootContext.Version == LanguageVersion.ISO_1) {
6529                                         Report.FeatureIsNotISO1 (Location, "access modifiers on properties");
6530                                 }
6531                         }
6532
6533                         public override Iterator Iterator {
6534                                 get { return iterator; }
6535                         }
6536
6537                         public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
6538                         {
6539                                 if (a.IsInternalMethodImplAttribute) {
6540                                         method.is_external_implementation = true;
6541                                 }
6542
6543                                 base.ApplyAttributeBuilder (a, cb);
6544                         }
6545
6546                         public override AttributeTargets AttributeTargets {
6547                                 get {
6548                                         return AttributeTargets.Method;
6549                                 }
6550                         }
6551
6552                         public override bool IsClsComplianceRequired ()
6553                         {
6554                                 return method.IsClsComplianceRequired ();
6555                         }
6556
6557                         public override bool ResolveMembers ()
6558                         {
6559                                 if (yields) {
6560                                         iterator = Iterator.CreateIterator (this, Parent, null, ModFlags);
6561                                         if (iterator == null)
6562                                                 return false;
6563                                 }
6564
6565                                 if (anonymous_methods != null) {
6566                                         foreach (AnonymousMethodExpression ame in anonymous_methods) {
6567                                                 if (!ame.CreateAnonymousHelpers ())
6568                                                         return false;
6569                                         }
6570                                 }
6571
6572                                 return true;
6573                         }
6574
6575                         public virtual MethodBuilder Define (DeclSpace parent)
6576                         {
6577                                 if (!method.CheckAbstractAndExtern (block != null))
6578                                         return null;
6579
6580                                 TypeContainer container = parent.PartialContainer;
6581
6582                                 //
6583                                 // Check for custom access modifier
6584                                 //
6585                                 if (ModFlags == 0) {
6586                                         ModFlags = method.ModFlags;
6587                                         flags = method.flags;
6588                                 } else {
6589                                         if (container.Kind == Kind.Interface)
6590                                                 Report.Error (275, Location, "`{0}': accessibility modifiers may not be used on accessors in an interface",
6591                                                         GetSignatureForError ());
6592
6593                                         if ((method.ModFlags & Modifiers.ABSTRACT) != 0 && (ModFlags & Modifiers.PRIVATE) != 0) {
6594                                                 Report.Error (442, Location, "`{0}': abstract properties cannot have private accessors", GetSignatureForError ());
6595                                         }
6596
6597                                         CheckModifiers (ModFlags);
6598                                         ModFlags |= (method.ModFlags & (~Modifiers.Accessibility));
6599                                         ModFlags |= Modifiers.PROPERTY_CUSTOM;
6600                                         flags = Modifiers.MethodAttr (ModFlags);
6601                                         flags |= (method.flags & (~MethodAttributes.MemberAccessMask));
6602                                 }
6603
6604                                 return null;
6605                         }
6606
6607                         public bool HasCustomAccessModifier
6608                         {
6609                                 get {
6610                                         return (ModFlags & Modifiers.PROPERTY_CUSTOM) != 0;
6611                                 }
6612                         }
6613
6614                         public override EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig)
6615                         {
6616                                 return new EmitContext (method,
6617                                         ds, method.ds, method.Location, ig, ReturnType,
6618                                         method.ModFlags, false);
6619                         }
6620
6621                         public override ObsoleteAttribute GetObsoleteAttribute ()
6622                         {
6623                                 return method.GetObsoleteAttribute ();
6624                         }
6625
6626                         public override string GetSignatureForError()
6627                         {
6628                                 return method.GetSignatureForError () + '.' + prefix.Substring (0, 3);
6629                         }
6630                         
6631                         void CheckModifiers (int modflags)
6632                         {
6633                                 int flags = 0;
6634                                 int mflags = method.ModFlags & Modifiers.Accessibility;
6635
6636                                 if ((mflags & Modifiers.PUBLIC) != 0) {
6637                                         flags |= Modifiers.PROTECTED | Modifiers.INTERNAL | Modifiers.PRIVATE;
6638                                 }
6639                                 else if ((mflags & Modifiers.PROTECTED) != 0) {
6640                                         if ((mflags & Modifiers.INTERNAL) != 0)
6641                                                 flags |= Modifiers.PROTECTED | Modifiers.INTERNAL;
6642
6643                                         flags |= Modifiers.PRIVATE;
6644                                 }
6645                                 else if ((mflags & Modifiers.INTERNAL) != 0)
6646                                         flags |= Modifiers.PRIVATE;
6647
6648                                 if ((mflags == modflags) || (modflags & (~flags)) != 0) {
6649                                         Report.Error (273, Location,
6650                                                 "The accessibility modifier of the `{0}' accessor must be more restrictive than the modifier of the property or indexer `{1}'",
6651                                                 GetSignatureForError (), method.GetSignatureForError ());
6652                                 }
6653                         }
6654
6655                         public override bool MarkForDuplicationCheck ()
6656                         {
6657                                 caching_flags |= Flags.TestMethodDuplication;
6658                                 return true;
6659                         }
6660                 }
6661
6662                 public PropertyMethod Get, Set;
6663                 public PropertyBuilder PropertyBuilder;
6664                 public MethodBuilder GetBuilder, SetBuilder;
6665
6666                 protected bool define_set_first = false;
6667
6668                 public PropertyBase (DeclSpace parent, Expression type, int mod_flags,
6669                                      int allowed_mod, bool is_iface, MemberName name,
6670                                      Attributes attrs, bool define_set_first)
6671                         : base (parent, null, type, mod_flags, allowed_mod, is_iface, name,     attrs)
6672                 {
6673                          this.define_set_first = define_set_first;
6674                 }
6675
6676                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
6677                 {
6678                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
6679                                 a.Error_InvalidSecurityParent ();
6680                                 return;
6681                         }
6682
6683                         PropertyBuilder.SetCustomAttribute (cb);
6684                 }
6685
6686                 public override AttributeTargets AttributeTargets {
6687                         get {
6688                                 return AttributeTargets.Property;
6689                         }
6690                 }
6691
6692                 public override bool Define ()
6693                 {
6694                         if (!DoDefine ())
6695                                 return false;
6696
6697                         if (!IsTypePermitted ())
6698                                 return false;
6699
6700                         return true;
6701                 }
6702
6703                 protected override bool DoDefine ()
6704                 {
6705                         if (!base.DoDefine ())
6706                                 return false;
6707
6708                         //
6709                         // Accessors modifiers check
6710                         //
6711                         if (Get.ModFlags != 0 && Set.ModFlags != 0) {
6712                                 Report.Error (274, Location, "`{0}': Cannot specify accessibility modifiers for both accessors of the property or indexer",
6713                                                 GetSignatureForError ());
6714                                 return false;
6715                         }
6716
6717                         if ((Get.IsDummy || Set.IsDummy)
6718                                         && (Get.ModFlags != 0 || Set.ModFlags != 0) && (ModFlags & Modifiers.OVERRIDE) == 0) {
6719                                 Report.Error (276, Location, 
6720                                         "`{0}': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor",
6721                                         GetSignatureForError ());
6722                                 return false;
6723                         }
6724
6725                         if (MemberType.IsAbstract && MemberType.IsSealed) {
6726                                 Report.Error (722, Location, Error722, TypeManager.CSharpName (MemberType));
6727                                 return false;
6728                         }
6729
6730                         return true;
6731                 }
6732
6733                 bool DefineGet ()
6734                 {
6735                         if (Get.IsDummy)
6736                                 return true;
6737
6738                         GetBuilder = Get.Define (Parent);
6739                         return GetBuilder != null;
6740                 }
6741
6742                 bool DefineSet (bool define)
6743                 {
6744                         if (!define || Set.IsDummy)
6745                                 return true;
6746
6747                         SetBuilder = Set.Define (Parent);
6748                         return SetBuilder != null;
6749                 }
6750
6751                 protected bool DefineAccessors ()
6752                 {
6753                         return DefineSet (define_set_first) &&
6754                                 DefineGet () &&
6755                                 DefineSet (!define_set_first);
6756                 }
6757
6758                 protected abstract PropertyInfo ResolveBaseProperty ();
6759
6760                 // TODO: rename to Resolve......
6761                 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
6762                 {
6763                         PropertyInfo base_property = ResolveBaseProperty ();
6764                         if (base_property == null)
6765                                 return null;
6766   
6767                         base_ret_type = base_property.PropertyType;
6768                         MethodInfo get_accessor = base_property.GetGetMethod (true);
6769                         MethodInfo set_accessor = base_property.GetSetMethod (true);
6770                         MethodAttributes get_accessor_access, set_accessor_access;
6771
6772                         if ((ModFlags & Modifiers.OVERRIDE) != 0) {
6773                                 if (Get != null && !Get.IsDummy && get_accessor == null) {
6774                                         Report.SymbolRelatedToPreviousError (base_property);
6775                                         Report.Error (545, Location, "`{0}.get': cannot override because `{1}' does not have an overridable get accessor", GetSignatureForError (), TypeManager.GetFullNameSignature (base_property));
6776                                 }
6777
6778                                 if (Set != null && !Set.IsDummy && set_accessor == null) {
6779                                         Report.SymbolRelatedToPreviousError (base_property);
6780                                         Report.Error (546, Location, "`{0}.set': cannot override because `{1}' does not have an overridable set accessor", GetSignatureForError (), TypeManager.GetFullNameSignature (base_property));
6781                                 }
6782                         }
6783                         
6784                         //
6785                         // Check base class accessors access
6786                         //
6787
6788                         // TODO: rewrite to reuse Get|Set.CheckAccessModifiers and share code there
6789                         get_accessor_access = set_accessor_access = 0;
6790                         if ((ModFlags & Modifiers.NEW) == 0) {
6791                                 if (get_accessor != null) {
6792                                         MethodAttributes get_flags = Modifiers.MethodAttr (Get.ModFlags != 0 ? Get.ModFlags : ModFlags);
6793                                         get_accessor_access = (get_accessor.Attributes & MethodAttributes.MemberAccessMask);
6794
6795                                         if (!Get.IsDummy && !CheckAccessModifiers (get_flags & MethodAttributes.MemberAccessMask, get_accessor_access, get_accessor))
6796                                                 Error_CannotChangeAccessModifiers (get_accessor, get_accessor_access,  ".get");
6797                                 }
6798
6799                                 if (set_accessor != null)  {
6800                                         MethodAttributes set_flags = Modifiers.MethodAttr (Set.ModFlags != 0 ? Set.ModFlags : ModFlags);
6801                                         set_accessor_access = (set_accessor.Attributes & MethodAttributes.MemberAccessMask);
6802
6803                                         if (!Set.IsDummy && !CheckAccessModifiers (set_flags & MethodAttributes.MemberAccessMask, set_accessor_access, set_accessor))
6804                                                 Error_CannotChangeAccessModifiers (set_accessor, set_accessor_access, ".set");
6805                                 }
6806                         }
6807
6808                         // When one accessor does not exist and property hides base one
6809                         // we need to propagate this upwards
6810                         if (set_accessor == null)
6811                                 set_accessor = get_accessor;
6812
6813                         //
6814                         // Get the less restrictive access
6815                         //
6816                         return get_accessor_access > set_accessor_access ? get_accessor : set_accessor;
6817                 }
6818
6819                 public override void Emit ()
6820                 {
6821                         //
6822                         // The PropertyBuilder can be null for explicit implementations, in that
6823                         // case, we do not actually emit the ".property", so there is nowhere to
6824                         // put the attribute
6825                         //
6826                         if (PropertyBuilder != null && OptAttributes != null)
6827                                 OptAttributes.Emit ();
6828
6829                         if (!Get.IsDummy)
6830                                 Get.Emit (Parent);
6831
6832                         if (!Set.IsDummy)
6833                                 Set.Emit (Parent);
6834
6835                         base.Emit ();
6836                 }
6837
6838                 /// <summary>
6839                 /// Tests whether accessors are not in collision with some method (CS0111)
6840                 /// </summary>
6841                 public bool AreAccessorsDuplicateImplementation (MethodCore mc)
6842                 {
6843                         return Get.IsDuplicateImplementation (mc) || Set.IsDuplicateImplementation (mc);
6844                 }
6845
6846                 public override bool IsUsed
6847                 {
6848                         get {
6849                                 if (IsExplicitImpl)
6850                                         return true;
6851
6852                                 return Get.IsUsed | Set.IsUsed;
6853                         }
6854                 }
6855
6856                 protected override void SetMemberName (MemberName new_name)
6857                 {
6858                         base.SetMemberName (new_name);
6859
6860                         Get.UpdateName (this);
6861                         Set.UpdateName (this);
6862                 }
6863
6864                 public override string[] ValidAttributeTargets {
6865                         get {
6866                                 return attribute_targets;
6867                         }
6868                 }
6869
6870                 //
6871                 //   Represents header string for documentation comment.
6872                 //
6873                 public override string DocCommentHeader {
6874                         get { return "P:"; }
6875                 }
6876         }
6877                         
6878         public class Property : PropertyBase {
6879                 const int AllowedModifiers =
6880                         Modifiers.NEW |
6881                         Modifiers.PUBLIC |
6882                         Modifiers.PROTECTED |
6883                         Modifiers.INTERNAL |
6884                         Modifiers.PRIVATE |
6885                         Modifiers.STATIC |
6886                         Modifiers.SEALED |
6887                         Modifiers.OVERRIDE |
6888                         Modifiers.ABSTRACT |
6889                         Modifiers.UNSAFE |
6890                         Modifiers.EXTERN |
6891                         Modifiers.METHOD_YIELDS |
6892                         Modifiers.VIRTUAL;
6893
6894                 const int AllowedInterfaceModifiers =
6895                         Modifiers.NEW;
6896
6897                 public Property (DeclSpace parent, Expression type, int mod, bool is_iface,
6898                                  MemberName name, Attributes attrs, Accessor get_block,
6899                                  Accessor set_block, bool define_set_first)
6900                         : base (parent, type, mod,
6901                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
6902                                 is_iface, name, attrs, define_set_first)
6903                 {
6904                         if (get_block == null)
6905                                 Get = new GetMethod (this);
6906                         else
6907                                 Get = new GetMethod (this, get_block);
6908
6909                         if (set_block == null)
6910                                 Set = new SetMethod (this);
6911                         else
6912                                 Set = new SetMethod (this, set_block);
6913                 }
6914
6915                 public override bool Define ()
6916                 {
6917                         if (!DoDefineBase ())
6918                                 return false;
6919
6920                         if (!base.Define ())
6921                                 return false;
6922
6923                         if (!CheckBase ())
6924                                 return false;
6925
6926                         flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
6927
6928                         if (!DefineAccessors ())
6929                                 return false;
6930
6931                         // FIXME - PropertyAttributes.HasDefault ?
6932
6933                         PropertyBuilder = Parent.TypeBuilder.DefineProperty (
6934                                 MemberName.ToString (), PropertyAttributes.None, MemberType, null);
6935
6936                         if (!Get.IsDummy)
6937                                 PropertyBuilder.SetGetMethod (GetBuilder);
6938                                 
6939                         if (!Set.IsDummy)
6940                                 PropertyBuilder.SetSetMethod (SetBuilder);
6941                         
6942                         TypeManager.RegisterProperty (PropertyBuilder, this);
6943                         return true;
6944                 }
6945
6946                 protected override PropertyInfo ResolveBaseProperty ()
6947                 {
6948                         return Parent.PartialContainer.BaseCache.FindMemberToOverride (
6949                                 Parent.TypeBuilder, Name, Parameters.EmptyReadOnlyParameters.Types, null, true) as PropertyInfo;
6950                 }
6951         }
6952
6953         /// </summary>
6954         ///  Gigantic workaround  for lameness in SRE follows :
6955         ///  This class derives from EventInfo and attempts to basically
6956         ///  wrap around the EventBuilder so that FindMembers can quickly
6957         ///  return this in it search for members
6958         /// </summary>
6959         public class MyEventBuilder : EventInfo {
6960                 
6961                 //
6962                 // We use this to "point" to our Builder which is
6963                 // not really a MemberInfo
6964                 //
6965                 EventBuilder MyBuilder;
6966                 
6967                 //
6968                 // We "catch" and wrap these methods
6969                 //
6970                 MethodInfo raise, remove, add;
6971
6972                 EventAttributes attributes;
6973                 Type declaring_type, reflected_type, event_type;
6974                 string name;
6975
6976                 Event my_event;
6977
6978                 public MyEventBuilder (Event ev, TypeBuilder type_builder, string name, EventAttributes event_attr, Type event_type)
6979                 {
6980                         MyBuilder = type_builder.DefineEvent (name, event_attr, event_type);
6981
6982                         // And now store the values in our own fields.
6983                         
6984                         declaring_type = type_builder;
6985
6986                         reflected_type = type_builder;
6987                         
6988                         attributes = event_attr;
6989                         this.name = name;
6990                         my_event = ev;
6991                         this.event_type = event_type;
6992                 }
6993                 
6994                 //
6995                 // Methods that you have to override.  Note that you only need 
6996                 // to "implement" the variants that take the argument (those are
6997                 // the "abstract" methods, the others (GetAddMethod()) are 
6998                 // regular.
6999                 //
7000                 public override MethodInfo GetAddMethod (bool nonPublic)
7001                 {
7002                         return add;
7003                 }
7004                 
7005                 public override MethodInfo GetRemoveMethod (bool nonPublic)
7006                 {
7007                         return remove;
7008                 }
7009                 
7010                 public override MethodInfo GetRaiseMethod (bool nonPublic)
7011                 {
7012                         return raise;
7013                 }
7014                 
7015                 //
7016                 // These methods make "MyEventInfo" look like a Builder
7017                 //
7018                 public void SetRaiseMethod (MethodBuilder raiseMethod)
7019                 {
7020                         raise = raiseMethod;
7021                         MyBuilder.SetRaiseMethod (raiseMethod);
7022                 }
7023
7024                 public void SetRemoveOnMethod (MethodBuilder removeMethod)
7025                 {
7026                         remove = removeMethod;
7027                         MyBuilder.SetRemoveOnMethod (removeMethod);
7028                 }
7029
7030                 public void SetAddOnMethod (MethodBuilder addMethod)
7031                 {
7032                         add = addMethod;
7033                         MyBuilder.SetAddOnMethod (addMethod);
7034                 }
7035
7036                 public void SetCustomAttribute (CustomAttributeBuilder cb)
7037                 {
7038                         MyBuilder.SetCustomAttribute (cb);
7039                 }
7040                 
7041                 public override object [] GetCustomAttributes (bool inherit)
7042                 {
7043                         // FIXME : There's nothing which can be seemingly done here because
7044                         // we have no way of getting at the custom attribute objects of the
7045                         // EventBuilder !
7046                         return null;
7047                 }
7048
7049                 public override object [] GetCustomAttributes (Type t, bool inherit)
7050                 {
7051                         // FIXME : Same here !
7052                         return null;
7053                 }
7054
7055                 public override bool IsDefined (Type t, bool b)
7056                 {
7057                         return true;
7058                 }
7059
7060                 public override EventAttributes Attributes {
7061                         get {
7062                                 return attributes;
7063                         }
7064                 }
7065
7066                 public override string Name {
7067                         get {
7068                                 return name;
7069                         }
7070                 }
7071
7072                 public override Type DeclaringType {
7073                         get {
7074                                 return declaring_type;
7075                         }
7076                 }
7077
7078                 public override Type ReflectedType {
7079                         get {
7080                                 return reflected_type;
7081                         }
7082                 }
7083
7084                 public Type EventType {
7085                         get {
7086                                 return event_type;
7087                         }
7088                 }
7089                 
7090                 public void SetUsed ()
7091                 {
7092                         if (my_event != null) {
7093 //                              my_event.SetAssigned ();
7094                                 my_event.SetMemberIsUsed ();
7095                         }
7096                 }
7097         }
7098         
7099         /// <summary>
7100         /// For case when event is declared like property (with add and remove accessors).
7101         /// </summary>
7102         public class EventProperty: Event {
7103                 abstract class AEventPropertyAccessor : AEventAccessor
7104                 {
7105                         readonly ArrayList anonymous_methods;
7106
7107                         public AEventPropertyAccessor (Event method, Accessor accessor, string prefix):
7108                                 base (method, accessor, prefix)
7109                         {
7110                                 this.anonymous_methods = accessor.AnonymousMethods;
7111                         }
7112
7113                         public override MethodBuilder Define (DeclSpace ds)
7114                         {
7115                                 method.CheckAbstractAndExtern (block != null);
7116                                 return base.Define (ds);
7117                         }
7118
7119                         public override bool ResolveMembers ()
7120                         {
7121                                 if (anonymous_methods == null)
7122                                         return true;
7123
7124                                 foreach (AnonymousMethodExpression ame in anonymous_methods) {
7125                                         if (!ame.CreateAnonymousHelpers ())
7126                                                 return false;
7127                                 }
7128
7129                                 return true;
7130                         }
7131
7132                 }
7133
7134                 sealed class AddDelegateMethod: AEventPropertyAccessor
7135                 {
7136                         public AddDelegateMethod (Event method, Accessor accessor):
7137                                 base (method, accessor, "add_")
7138                         {
7139                         }
7140
7141                         protected override MethodInfo DelegateMethodInfo {
7142                                 get {
7143                                         return TypeManager.delegate_combine_delegate_delegate;
7144                                 }
7145                         }
7146                 }
7147
7148                 sealed class RemoveDelegateMethod: AEventPropertyAccessor
7149                 {
7150                         public RemoveDelegateMethod (Event method, Accessor accessor):
7151                                 base (method, accessor, "remove_")
7152                         {
7153                         }
7154
7155                         protected override MethodInfo DelegateMethodInfo {
7156                                 get {
7157                                         return TypeManager.delegate_remove_delegate_delegate;
7158                                 }
7159                         }
7160                 }
7161
7162
7163                 static readonly string[] attribute_targets = new string [] { "event" }; // "property" target was disabled for 2.0 version
7164
7165                 public EventProperty (DeclSpace parent, Expression type, int mod_flags,
7166                                       bool is_iface, MemberName name,
7167                                       Attributes attrs, Accessor add, Accessor remove)
7168                         : base (parent, type, mod_flags, is_iface, name, attrs)
7169                 {
7170                         Add = new AddDelegateMethod (this, add);
7171                         Remove = new RemoveDelegateMethod (this, remove);
7172                 }
7173
7174                 public override bool Define()
7175                 {
7176                         if (!base.Define ())
7177                                 return false;
7178
7179                         if (IsExplicitImpl)
7180                                 SetMemberIsUsed ();
7181
7182                         return true;
7183                 }
7184
7185                 public override string[] ValidAttributeTargets {
7186                         get {
7187                                 return attribute_targets;
7188                         }
7189                 }
7190         }
7191
7192         /// <summary>
7193         /// Event is declared like field.
7194         /// </summary>
7195         public class EventField : Event {
7196                 abstract class EventFieldAccessor : AEventAccessor
7197                 {
7198                         protected EventFieldAccessor (Event method, string prefix)
7199                                 : base (method, prefix)
7200                         {
7201                         }
7202
7203                         protected override void EmitMethod(DeclSpace parent)
7204                         {
7205                                 if ((method.ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
7206                                         return;
7207
7208                                 MethodBuilder mb = method_data.MethodBuilder;
7209                                 ILGenerator ig = mb.GetILGenerator ();
7210
7211                                 // TODO: because we cannot use generics yet
7212                                 FieldInfo field_info = ((EventField)method).FieldBuilder;
7213
7214                                 mb.SetImplementationFlags (mb.GetMethodImplementationFlags () | MethodImplAttributes.Synchronized);
7215                                 if ((method.ModFlags & Modifiers.STATIC) != 0) {
7216                                         ig.Emit (OpCodes.Ldsfld, field_info);
7217                                         ig.Emit (OpCodes.Ldarg_0);
7218                                         ig.Emit (OpCodes.Call, DelegateMethodInfo);
7219                                         ig.Emit (OpCodes.Castclass, method.MemberType);
7220                                         ig.Emit (OpCodes.Stsfld, field_info);
7221                                 } else {
7222                                         ig.Emit (OpCodes.Ldarg_0);
7223                                         ig.Emit (OpCodes.Ldarg_0);
7224                                         ig.Emit (OpCodes.Ldfld, field_info);
7225                                         ig.Emit (OpCodes.Ldarg_1);
7226                                         ig.Emit (OpCodes.Call, DelegateMethodInfo);
7227                                         ig.Emit (OpCodes.Castclass, method.MemberType);
7228                                         ig.Emit (OpCodes.Stfld, field_info);
7229                                 }
7230                                 ig.Emit (OpCodes.Ret);
7231                         }
7232                 }
7233
7234                 sealed class AddDelegateMethod: EventFieldAccessor
7235                 {
7236                         public AddDelegateMethod (Event method):
7237                                 base (method, "add_")
7238                         {
7239                         }
7240
7241                         protected override MethodInfo DelegateMethodInfo {
7242                                 get {
7243                                         return TypeManager.delegate_combine_delegate_delegate;
7244                                 }
7245                         }
7246                 }
7247
7248                 sealed class RemoveDelegateMethod: EventFieldAccessor
7249                 {
7250                         public RemoveDelegateMethod (Event method):
7251                                 base (method, "remove_")
7252                         {
7253                         }
7254
7255                         protected override MethodInfo DelegateMethodInfo {
7256                                 get {
7257                                         return TypeManager.delegate_remove_delegate_delegate;
7258                                 }
7259                         }
7260                 }
7261
7262
7263                 static readonly string[] attribute_targets = new string [] { "event", "field", "method" };
7264                 static readonly string[] attribute_targets_interface = new string[] { "event", "method" };
7265
7266                 public FieldBuilder FieldBuilder;
7267                 public Expression Initializer;
7268
7269                 public EventField (DeclSpace parent, Expression type, int mod_flags,
7270                                    bool is_iface, MemberName name,
7271                                    Attributes attrs)
7272                         : base (parent, type, mod_flags, is_iface, name, attrs)
7273                 {
7274                         Add = new AddDelegateMethod (this);
7275                         Remove = new RemoveDelegateMethod (this);
7276                 }
7277
7278                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
7279                 {
7280                         if (a.Target == AttributeTargets.Field) {
7281                                 FieldBuilder.SetCustomAttribute (cb);
7282                                 return;
7283                         }
7284
7285                         if (a.Target == AttributeTargets.Method) {
7286                                 int errors = Report.Errors;
7287                                 Add.ApplyAttributeBuilder (a, cb);
7288                                 if (errors == Report.Errors)
7289                                         Remove.ApplyAttributeBuilder (a, cb);
7290                                 return;
7291                         }
7292
7293                         base.ApplyAttributeBuilder (a, cb);
7294                 }
7295
7296                 public override bool Define()
7297                 {
7298                         if (!base.Define ())
7299                                 return false;
7300
7301                         if (IsInterface)
7302                                 return true;
7303
7304                         // FIXME: We are unable to detect whether generic event is used because
7305                         // we are using FieldExpr instead of EventExpr for event access in that
7306                         // case.  When this issue will be fixed this hack can be removed.
7307                         if (TypeManager.IsGenericType (MemberType))
7308                                 SetMemberIsUsed();
7309
7310                         FieldBuilder = Parent.TypeBuilder.DefineField (
7311                                 Name, MemberType,
7312                                 FieldAttributes.Private | ((ModFlags & Modifiers.STATIC) != 0 ? FieldAttributes.Static : 0));
7313                         TypeManager.RegisterEventField (EventBuilder, this);
7314
7315                         if (Initializer != null) {
7316                                 if (((ModFlags & Modifiers.ABSTRACT) != 0)) {
7317                                         Report.Error (74, Location, "`{0}': abstract event cannot have an initializer",
7318                                                 GetSignatureForError ());
7319                                         return false;
7320                                 }
7321
7322                                 Parent.PartialContainer.RegisterFieldForInitialization (this,
7323                                         new FieldInitializer (FieldBuilder, Initializer, Parent));
7324                         }
7325
7326                         return true;
7327                 }
7328
7329                 public override string[] ValidAttributeTargets 
7330                 {
7331                         get {
7332                                 return IsInterface ? attribute_targets_interface : attribute_targets;
7333                         }
7334                 }
7335         }
7336
7337         public abstract class Event : PropertyBasedMember {
7338                 public abstract class AEventAccessor : AbstractPropertyEventMethod
7339                 {
7340                         protected readonly Event method;
7341                         ImplicitParameter param_attr;
7342
7343                         static readonly string[] attribute_targets = new string [] { "method", "param", "return" };
7344
7345                         protected AEventAccessor (Event method, string prefix)
7346                                 : base (method, prefix)
7347                         {
7348                                 this.method = method;
7349                         }
7350
7351                         protected AEventAccessor (Event method, Accessor accessor, string prefix)
7352                                 : base (method, accessor, prefix)
7353                         {
7354                                 this.method = method;
7355                         }
7356
7357                         public override Iterator Iterator {
7358                                 get { return null; }
7359                         }
7360
7361                         public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
7362                         {
7363                                 if (a.IsInternalMethodImplAttribute) {
7364                                         method.is_external_implementation = true;
7365                                 }
7366
7367                                 base.ApplyAttributeBuilder (a, cb);
7368                         }
7369
7370                         protected override void ApplyToExtraTarget(Attribute a, CustomAttributeBuilder cb)
7371                         {
7372                                 if (a.Target == AttributeTargets.Parameter) {
7373                                         if (param_attr == null)
7374                                                 param_attr = new ImplicitParameter (method_data.MethodBuilder);
7375
7376                                         param_attr.ApplyAttributeBuilder (a, cb);
7377                                         return;
7378                                 }
7379
7380                                 base.ApplyAttributeBuilder (a, cb);
7381                         }
7382
7383                         public override AttributeTargets AttributeTargets {
7384                                 get {
7385                                         return AttributeTargets.Method;
7386                                 }
7387                         }
7388
7389                         public override bool IsClsComplianceRequired ()
7390                         {
7391                                 return method.IsClsComplianceRequired ();
7392                         }
7393
7394                         public virtual MethodBuilder Define (DeclSpace parent)
7395                         {
7396                                 method_data = new MethodData (method, method.ModFlags,
7397                                         method.flags | MethodAttributes.HideBySig | MethodAttributes.SpecialName, this);
7398
7399                                 if (!method_data.Define (parent))
7400                                         return null;
7401
7402                                 MethodBuilder mb = method_data.MethodBuilder;
7403                                 ParameterInfo.ApplyAttributes (mb);
7404                                 return mb;
7405                         }
7406
7407                         protected abstract MethodInfo DelegateMethodInfo { get; }
7408
7409                         public override Type ReturnType {
7410                                 get {
7411                                         return TypeManager.void_type;
7412                                 }
7413                         }
7414
7415                         public override EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig)
7416                         {
7417                                 return new EmitContext (
7418                                         ds, method.Parent, Location, ig, ReturnType,
7419                                         method.ModFlags, false);
7420                         }
7421
7422                         public override ObsoleteAttribute GetObsoleteAttribute ()
7423                         {
7424                                 return method.GetObsoleteAttribute ();
7425                         }
7426
7427                         public override string[] ValidAttributeTargets {
7428                                 get {
7429                                         return attribute_targets;
7430                                 }
7431                         }
7432
7433                         public override Parameters ParameterInfo {
7434                                 get {
7435                                         return method.parameters;
7436                                 }
7437                         }
7438                 }
7439
7440
7441                 const int AllowedModifiers =
7442                         Modifiers.NEW |
7443                         Modifiers.PUBLIC |
7444                         Modifiers.PROTECTED |
7445                         Modifiers.INTERNAL |
7446                         Modifiers.PRIVATE |
7447                         Modifiers.STATIC |
7448                         Modifiers.VIRTUAL |
7449                         Modifiers.SEALED |
7450                         Modifiers.OVERRIDE |
7451                         Modifiers.UNSAFE |
7452                         Modifiers.ABSTRACT |
7453                         Modifiers.EXTERN;
7454
7455                 const int AllowedInterfaceModifiers =
7456                         Modifiers.NEW;
7457
7458                 public AEventAccessor Add, Remove;
7459                 public MyEventBuilder     EventBuilder;
7460                 public MethodBuilder AddBuilder, RemoveBuilder;
7461
7462                 Parameters parameters;
7463
7464                 protected Event (DeclSpace parent, Expression type, int mod_flags,
7465                               bool is_iface, MemberName name, Attributes attrs)
7466                         : base (parent, null, type, mod_flags,
7467                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers, is_iface,
7468                                 name, attrs)
7469                 {
7470                 }
7471
7472                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
7473                 {
7474                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
7475                                 a.Error_InvalidSecurityParent ();
7476                                 return;
7477                         }
7478                         
7479                         EventBuilder.SetCustomAttribute (cb);
7480                 }
7481
7482                 public bool AreAccessorsDuplicateImplementation (MethodCore mc)
7483                 {
7484                         return Add.IsDuplicateImplementation (mc) || Remove.IsDuplicateImplementation (mc);
7485                 }
7486
7487                 public override AttributeTargets AttributeTargets {
7488                         get {
7489                                 return AttributeTargets.Event;
7490                         }
7491                 }
7492
7493                 public override bool Define ()
7494                 {
7495                         if (!DoDefineBase ())
7496                                 return false;
7497
7498                         if (!DoDefine ())
7499                                 return false;
7500
7501                         if (!TypeManager.IsDelegateType (MemberType)) {
7502                                 Report.Error (66, Location, "`{0}': event must be of a delegate type", GetSignatureForError ());
7503                                 return false;
7504                         }
7505
7506                         parameters = new Parameters (
7507                                 new Parameter[] { new Parameter (MemberType, "value", Parameter.Modifier.NONE, null, Location) },
7508                                 new Type[] { MemberType } );
7509
7510                         if (!CheckBase ())
7511                                 return false;
7512
7513                         //
7514                         // Now define the accessors
7515                         //
7516
7517                         AddBuilder = Add.Define (Parent);
7518                         if (AddBuilder == null)
7519                                 return false;
7520
7521                         RemoveBuilder = Remove.Define (Parent);
7522                         if (RemoveBuilder == null)
7523                                 return false;
7524
7525                         EventBuilder = new MyEventBuilder (this, Parent.TypeBuilder, Name, EventAttributes.None, MemberType);                                           
7526                         EventBuilder.SetAddOnMethod (AddBuilder);
7527                         EventBuilder.SetRemoveOnMethod (RemoveBuilder);
7528                         return true;
7529                 }
7530
7531                 public override void Emit ()
7532                 {
7533                         if (OptAttributes != null) {
7534                                 OptAttributes.Emit ();
7535                         }
7536
7537                         Add.Emit (Parent);
7538                         Remove.Emit (Parent);
7539
7540                         base.Emit ();
7541                 }
7542
7543                 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
7544                 {
7545                         MethodInfo mi = (MethodInfo) Parent.PartialContainer.BaseCache.FindBaseEvent (
7546                                 Parent.TypeBuilder, Name);
7547
7548                         if (mi == null)
7549                                 return null;
7550
7551                         ParameterData pd = TypeManager.GetParameterData (mi);
7552                         base_ret_type = pd.ParameterType (0);
7553                         return mi;
7554                 }
7555
7556                 //
7557                 //   Represents header string for documentation comment.
7558                 //
7559                 public override string DocCommentHeader {
7560                         get { return "E:"; }
7561                 }
7562         }
7563
7564  
7565         public class Indexer : PropertyBase {
7566
7567                 class GetIndexerMethod : GetMethod
7568                 {
7569                         public GetIndexerMethod (PropertyBase method):
7570                                 base (method)
7571                         {
7572                         }
7573
7574                         public GetIndexerMethod (PropertyBase method, Accessor accessor):
7575                                 base (method, accessor)
7576                         {
7577                         }
7578
7579                         public override Parameters ParameterInfo {
7580                                 get {
7581                                         return ((Indexer)method).parameters;
7582                                 }
7583                         }
7584                 }
7585
7586                 class SetIndexerMethod: SetMethod
7587                 {
7588                         public SetIndexerMethod (PropertyBase method):
7589                                 base (method)
7590                         {
7591                         }
7592
7593                         public SetIndexerMethod (PropertyBase method, Accessor accessor):
7594                                 base (method, accessor)
7595                         {
7596                         }
7597
7598                         protected override void DefineParameters ()
7599                         {
7600                                 parameters = Parameters.MergeGenerated (((Indexer)method).parameters,
7601                                         new Parameter (method.MemberType, "value", Parameter.Modifier.NONE, null, method.Location));
7602                         }
7603                 }
7604
7605                 const int AllowedModifiers =
7606                         Modifiers.NEW |
7607                         Modifiers.PUBLIC |
7608                         Modifiers.PROTECTED |
7609                         Modifiers.INTERNAL |
7610                         Modifiers.PRIVATE |
7611                         Modifiers.VIRTUAL |
7612                         Modifiers.SEALED |
7613                         Modifiers.OVERRIDE |
7614                         Modifiers.UNSAFE |
7615                         Modifiers.EXTERN |
7616                         Modifiers.ABSTRACT;
7617
7618                 const int AllowedInterfaceModifiers =
7619                         Modifiers.NEW;
7620
7621                 public readonly Parameters parameters;
7622
7623                 public Indexer (DeclSpace parent, Expression type, MemberName name, int mod,
7624                                 bool is_iface, Parameters parameters, Attributes attrs,
7625                                 Accessor get_block, Accessor set_block, bool define_set_first)
7626                         : base (parent, type, mod,
7627                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
7628                                 is_iface, name, attrs, define_set_first)
7629                 {
7630                         this.parameters = parameters;
7631
7632                         if (get_block == null)
7633                                 Get = new GetIndexerMethod (this);
7634                         else
7635                                 Get = new GetIndexerMethod (this, get_block);
7636
7637                         if (set_block == null)
7638                                 Set = new SetIndexerMethod (this);
7639                         else
7640                                 Set = new SetIndexerMethod (this, set_block);
7641                 }
7642                 
7643                 protected override bool CheckForDuplications ()
7644                 {
7645                         ArrayList ar = Parent.PartialContainer.Indexers;
7646                         if (ar != null) {
7647                                 int arLen = ar.Count;
7648                                         
7649                                 for (int i = 0; i < arLen; i++) {
7650                                         Indexer m = (Indexer) ar [i];
7651                                         if (IsDuplicateImplementation (m))
7652                                                 return false;
7653                                 }
7654                         }
7655
7656                         return true;
7657                 }
7658
7659                 bool IsDuplicateImplementation (Indexer indexer)
7660                 {
7661                         if (this == indexer)
7662                                 return false;
7663
7664                         if (!MemberName.Equals (indexer.MemberName))
7665                                 return false;
7666
7667                         Type[] param_types = indexer.parameters.Types;
7668
7669                         // When it is not yet defined
7670                         if (param_types == null)
7671                                 return false;
7672
7673                         if (param_types.Length != parameters.Count)
7674                                 return false;
7675
7676                         for (int i = 0; i < param_types.Length; i++)
7677                                 if (param_types [i] != parameters.Types [i])
7678                                         return false;
7679
7680                         Report.SymbolRelatedToPreviousError (indexer);
7681                         Report.Error (111, Location, TypeContainer.Error111, indexer.GetSignatureForError ());
7682                         return true;
7683                 }
7684
7685
7686                 public override bool Define ()
7687                 {
7688                         if (!DoDefineBase ())
7689                                 return false;
7690
7691                         if (!base.Define ())
7692                                 return false;
7693
7694                         if (!DefineParameters (parameters))
7695                                 return false;
7696
7697                         if (MemberType == TypeManager.void_type) {
7698                                 Report.Error (620, Location, "Indexers cannot have void type");
7699                                 return false;
7700                         }
7701
7702                         if (OptAttributes != null) {
7703                                 Attribute indexer_attr = OptAttributes.Search (TypeManager.indexer_name_type);
7704                                 if (indexer_attr != null) {
7705                                         // Remove the attribute from the list because it is not emitted
7706                                         OptAttributes.Attrs.Remove (indexer_attr);
7707
7708                                         string name = indexer_attr.GetIndexerAttributeValue ();
7709                                         if (name == null)
7710                                                 return false;
7711
7712                                         ShortName = name;
7713
7714                                         if (IsExplicitImpl) {
7715                                                 Report.Error (415, indexer_attr.Location,
7716                                                               "The `IndexerName' attribute is valid only on an " +
7717                                                               "indexer that is not an explicit interface member declaration");
7718                                                 return false;
7719                                         }
7720
7721                                         if ((ModFlags & Modifiers.OVERRIDE) != 0) {
7722                                                 Report.Error (609, indexer_attr.Location,
7723                                                               "Cannot set the `IndexerName' attribute on an indexer marked override");
7724                                                 return false;
7725                                         }
7726                                 }
7727                         }
7728
7729                         if (InterfaceType != null) {
7730                                 string base_IndexerName = TypeManager.IndexerPropertyName (InterfaceType);
7731                                 if (base_IndexerName != Name)
7732                                         ShortName = base_IndexerName;
7733                         }
7734
7735                         if (!Parent.PartialContainer.AddMember (this) ||
7736                                 !Parent.PartialContainer.AddMember (Get) || !Parent.PartialContainer.AddMember (Set))
7737                                 return false;
7738
7739                         if (!CheckBase ())
7740                                 return false;
7741
7742                         flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
7743                         
7744                         if (!DefineAccessors ())
7745                                 return false;
7746
7747                         if (!Get.IsDummy) {
7748                                 // Setup iterator if we are one
7749                                 if ((ModFlags & Modifiers.METHOD_YIELDS) != 0){
7750                                         Iterator iterator = Iterator.CreateIterator (Get, Parent, null, ModFlags);
7751                                         if (iterator == null)
7752                                                 return false;
7753                                 }
7754                         }
7755
7756                         //
7757                         // Now name the parameters
7758                         //
7759                         Parameter [] p = parameters.FixedParameters;
7760                         if (p != null) {
7761                                 // TODO: should be done in parser and it needs to do cycle
7762                                 if ((p [0].ModFlags & Parameter.Modifier.ISBYREF) != 0) {
7763                                         CSharpParser.Error_ParameterModifierNotValid (Location);
7764                                         return false;
7765                                 }
7766                         }
7767
7768                         PropertyBuilder = Parent.TypeBuilder.DefineProperty (
7769                                 Name, PropertyAttributes.None, MemberType, parameters.Types);
7770                         
7771                         if (!Get.IsDummy)
7772                                 PropertyBuilder.SetGetMethod (GetBuilder);
7773
7774                         if (!Set.IsDummy)
7775                                 PropertyBuilder.SetSetMethod (SetBuilder);
7776                                 
7777                         TypeManager.RegisterIndexer (PropertyBuilder, GetBuilder, SetBuilder, parameters.Types);
7778
7779                         return true;
7780                 }
7781
7782                 public override string GetDocCommentName (DeclSpace ds)
7783                 {
7784                         return DocUtil.GetMethodDocCommentName (this, parameters, ds);
7785                 }
7786
7787                 public override string GetSignatureForError ()
7788                 {
7789                         StringBuilder sb = new StringBuilder (Parent.GetSignatureForError ());
7790                         if (MemberName.Left != null) {
7791                                 sb.Append ('.');
7792                                 sb.Append (MemberName.Left);
7793                         }
7794
7795                         sb.Append (".this");
7796                         sb.Append (parameters.GetSignatureForError ().Replace ('(', '[').Replace (')', ']'));
7797                         return sb.ToString ();
7798                 }
7799
7800                 public override bool MarkForDuplicationCheck ()
7801                 {
7802                         caching_flags |= Flags.TestMethodDuplication;
7803                         return true;
7804                 }
7805
7806                 protected override PropertyInfo ResolveBaseProperty ()
7807                 {
7808                         return Parent.PartialContainer.BaseCache.FindMemberToOverride (
7809                                 Parent.TypeBuilder, Name, parameters.Types, null, true) as PropertyInfo;
7810                 }
7811
7812                 protected override bool VerifyClsCompliance ()
7813                 {
7814                         if (!base.VerifyClsCompliance ())
7815                                 return false;
7816
7817                         parameters.VerifyClsCompliance ();
7818                         return true;
7819                 }
7820         }
7821
7822         public class Operator : MethodOrOperator, IAnonymousHost {
7823
7824                 const int AllowedModifiers =
7825                         Modifiers.PUBLIC |
7826                         Modifiers.UNSAFE |
7827                         Modifiers.EXTERN |
7828                         Modifiers.STATIC;
7829
7830                 public enum OpType : byte {
7831
7832                         // Unary operators
7833                         LogicalNot,
7834                         OnesComplement,
7835                         Increment,
7836                         Decrement,
7837                         True,
7838                         False,
7839
7840                         // Unary and Binary operators
7841                         Addition,
7842                         Subtraction,
7843
7844                         UnaryPlus,
7845                         UnaryNegation,
7846                         
7847                         // Binary operators
7848                         Multiply,
7849                         Division,
7850                         Modulus,
7851                         BitwiseAnd,
7852                         BitwiseOr,
7853                         ExclusiveOr,
7854                         LeftShift,
7855                         RightShift,
7856                         Equality,
7857                         Inequality,
7858                         GreaterThan,
7859                         LessThan,
7860                         GreaterThanOrEqual,
7861                         LessThanOrEqual,
7862
7863                         // Implicit and Explicit
7864                         Implicit,
7865                         Explicit,
7866
7867                         // Just because of enum
7868                         TOP
7869                 };
7870
7871                 public readonly OpType OperatorType;
7872                 
7873                 public Operator (DeclSpace parent, OpType type, Expression ret_type,
7874                                  int mod_flags, Parameters parameters,
7875                                  ToplevelBlock block, Attributes attrs, Location loc)
7876                         : base (parent, null, ret_type, mod_flags, AllowedModifiers, false,
7877                                 new MemberName ("op_" + type.ToString(), loc), attrs, parameters)
7878                 {
7879                         OperatorType = type;
7880                         Block = block;
7881                 }
7882
7883                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb) 
7884                 {
7885                         if (a.Type == TypeManager.conditional_attribute_type) {
7886                                 Error_ConditionalAttributeIsNotValid ();
7887                                 return;
7888                         }
7889
7890                         base.ApplyAttributeBuilder (a, cb);
7891                 }
7892                 
7893                 protected override bool CheckForDuplications ()
7894                 {
7895                         ArrayList ar = Parent.PartialContainer.Operators;
7896                         if (ar != null) {
7897                                 int arLen = ar.Count;
7898                                         
7899                                 for (int i = 0; i < arLen; i++) {
7900                                         Operator o = (Operator) ar [i];
7901                                         if (IsDuplicateImplementation (o))
7902                                                 return false;
7903                                 }
7904                         }
7905
7906                         ar = Parent.PartialContainer.Methods;
7907                         if (ar != null) {
7908                                 int arLen = ar.Count;
7909                                         
7910                                 for (int i = 0; i < arLen; i++) {
7911                                         Method m = (Method) ar [i];
7912                                         if (IsDuplicateImplementation (m))
7913                                                 return false;
7914                                 }
7915                         }
7916
7917                         return true;
7918                 }
7919
7920                 public override bool Define ()
7921                 {
7922                         const int RequiredModifiers = Modifiers.PUBLIC | Modifiers.STATIC;
7923                         if ((ModFlags & RequiredModifiers) != RequiredModifiers){
7924                                 Report.Error (558, Location, "User-defined operator `{0}' must be declared static and public", GetSignatureForError ());
7925                                 return false;
7926                         }
7927
7928                         // imlicit and explicit operator of same types are not allowed
7929                         if (OperatorType == OpType.Explicit || OperatorType == OpType.Implicit)
7930                                 MarkForDuplicationCheck ();
7931
7932                         if (!base.Define ())
7933                                 return false;
7934
7935                         if (MemberType == TypeManager.void_type) {
7936                                 Report.Error (590, Location, "User-defined operators cannot return void");
7937                                 return false;
7938                         }
7939
7940                         Type declaring_type = MethodData.DeclaringType;
7941                         Type return_type = MemberType;
7942                         Type first_arg_type = ParameterTypes [0];
7943
7944                         // Rules for conversion operators
7945                         
7946                         if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
7947                                 if (first_arg_type == return_type && first_arg_type == declaring_type){
7948                                         Report.Error (555, Location,
7949                                                 "User-defined operator cannot take an object of the enclosing type and convert to an object of the enclosing type");
7950                                         return false;
7951                                 }
7952                                 
7953                                 if ((first_arg_type != declaring_type) && (return_type != declaring_type) &&
7954                                     !TypeManager.IsNullableTypeOf (first_arg_type, declaring_type) &&
7955                                     !TypeManager.IsNullableTypeOf (return_type, declaring_type)) {
7956                                         Report.Error (
7957                                                 556, Location, 
7958                                                 "User-defined conversion must convert to or from the " +
7959                                                 "enclosing type");
7960                                         return false;
7961                                 }
7962
7963                                 if (first_arg_type.IsInterface || return_type.IsInterface){
7964                                         Report.Error (552, Location, "User-defined conversion `{0}' cannot convert to or from an interface type",
7965                                                 GetSignatureForError ());
7966                                         return false;
7967                                 }
7968                                 
7969                                 if (first_arg_type.IsSubclassOf (return_type) || return_type.IsSubclassOf (first_arg_type)) {
7970                                         if (declaring_type.IsSubclassOf (return_type) || declaring_type.IsSubclassOf (first_arg_type)) {
7971                                                 Report.Error (553, Location, "User-defined conversion `{0}' cannot convert to or from base class",
7972                                                         GetSignatureForError ());
7973                                                 return false;
7974                                         }
7975                                         Report.Error (554, Location, "User-defined conversion `{0}' cannot convert to or from derived class",
7976                                                 GetSignatureForError ());
7977                                         return false;
7978                                 }
7979                         } else if (OperatorType == OpType.LeftShift || OperatorType == OpType.RightShift) {
7980                                 if (first_arg_type != declaring_type || ParameterTypes [1] != TypeManager.int32_type) {
7981                                         Report.Error (564, Location, "Overloaded shift operator must have the type of the first operand be the containing type, and the type of the second operand must be int");
7982                                         return false;
7983                                 }
7984                         } else if (Parameters.Count == 1) {
7985                                 // Checks for Unary operators
7986
7987                                 if (OperatorType == OpType.Increment || OperatorType == OpType.Decrement) {
7988                                         if (return_type != declaring_type && !TypeManager.IsSubclassOf (return_type, declaring_type)) {
7989                                                 Report.Error (448, Location,
7990                                                         "The return type for ++ or -- operator must be the containing type or derived from the containing type");
7991                                                 return false;
7992                                         }
7993                                         if (first_arg_type != declaring_type) {
7994                                                 Report.Error (
7995                                                         559, Location, "The parameter type for ++ or -- operator must be the containing type");
7996                                                 return false;
7997                                         }
7998                                 }
7999                                 
8000                                 if (first_arg_type != declaring_type){
8001                                         Report.Error (
8002                                                 562, Location,
8003                                                 "The parameter of a unary operator must be the " +
8004                                                 "containing type");
8005                                         return false;
8006                                 }
8007                                 
8008                                 if (OperatorType == OpType.True || OperatorType == OpType.False) {
8009                                         if (return_type != TypeManager.bool_type){
8010                                                 Report.Error (
8011                                                         215, Location,
8012                                                         "The return type of operator True or False " +
8013                                                         "must be bool");
8014                                                 return false;
8015                                         }
8016                                 }
8017                                 
8018                         } else {
8019                                 // Checks for Binary operators
8020                                 
8021                                 if (first_arg_type != declaring_type &&
8022                                     ParameterTypes [1] != declaring_type){
8023                                         Report.Error (
8024                                                 563, Location,
8025                                                 "One of the parameters of a binary operator must " +
8026                                                 "be the containing type");
8027                                         return false;
8028                                 }
8029                         }
8030
8031                         return true;
8032                 }
8033
8034                 protected override bool DoDefine ()
8035                 {
8036                         if (!base.DoDefine ())
8037                                 return false;
8038
8039                         flags |= MethodAttributes.SpecialName | MethodAttributes.HideBySig;
8040                         return true;
8041                 }
8042                 
8043                 public override void Emit ()
8044                 {
8045                         base.Emit ();
8046
8047                         Parameters.ApplyAttributes (MethodBuilder);
8048
8049                         //
8050                         // abstract or extern methods have no bodies
8051                         //
8052                         if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
8053                                 return;
8054                         
8055                         EmitContext ec;
8056                         if ((flags & MethodAttributes.PinvokeImpl) == 0)
8057                                 ec = CreateEmitContext (Parent, MethodBuilder.GetILGenerator ());
8058                         else
8059                                 ec = CreateEmitContext (Parent, null);
8060                         
8061                         SourceMethod source = SourceMethod.Create (Parent, MethodBuilder, Block);
8062                         ec.EmitTopBlock (this, Block);
8063
8064                         if (source != null)
8065                                 source.CloseMethod ();
8066
8067                         Block = null;
8068                 }
8069
8070                 // Operator cannot be override
8071                 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
8072                 {
8073                         return null;
8074                 }
8075
8076                 public static string GetName (OpType ot)
8077                 {
8078                         switch (ot){
8079                         case OpType.LogicalNot:
8080                                 return "!";
8081                         case OpType.OnesComplement:
8082                                 return "~";
8083                         case OpType.Increment:
8084                                 return "++";
8085                         case OpType.Decrement:
8086                                 return "--";
8087                         case OpType.True:
8088                                 return "true";
8089                         case OpType.False:
8090                                 return "false";
8091                         case OpType.Addition:
8092                                 return "+";
8093                         case OpType.Subtraction:
8094                                 return "-";
8095                         case OpType.UnaryPlus:
8096                                 return "+";
8097                         case OpType.UnaryNegation:
8098                                 return "-";
8099                         case OpType.Multiply:
8100                                 return "*";
8101                         case OpType.Division:
8102                                 return "/";
8103                         case OpType.Modulus:
8104                                 return "%";
8105                         case OpType.BitwiseAnd:
8106                                 return "&";
8107                         case OpType.BitwiseOr:
8108                                 return "|";
8109                         case OpType.ExclusiveOr:
8110                                 return "^";
8111                         case OpType.LeftShift:
8112                                 return "<<";
8113                         case OpType.RightShift:
8114                                 return ">>";
8115                         case OpType.Equality:
8116                                 return "==";
8117                         case OpType.Inequality:
8118                                 return "!=";
8119                         case OpType.GreaterThan:
8120                                 return ">";
8121                         case OpType.LessThan:
8122                                 return "<";
8123                         case OpType.GreaterThanOrEqual:
8124                                 return ">=";
8125                         case OpType.LessThanOrEqual:
8126                                 return "<=";
8127                         case OpType.Implicit:
8128                                 return "implicit";
8129                         case OpType.Explicit:
8130                                 return "explicit";
8131                         default: return "";
8132                         }
8133                 }
8134
8135                 public static OpType GetOperatorType (string name)
8136                 {
8137                         if (name.StartsWith ("op_")){
8138                                 for (int i = 0; i < Unary.oper_names.Length; ++i) {
8139                                         if (Unary.oper_names [i] == name)
8140                                                 return (OpType)i;
8141                                 }
8142
8143                                 for (int i = 0; i < Binary.oper_names.Length; ++i) {
8144                                         if (Binary.oper_names [i] == name)
8145                                                 return (OpType)i;
8146                                 }
8147                         }
8148                         return OpType.TOP;
8149                 }
8150
8151                 public override string GetSignatureForError ()
8152                 {
8153                         StringBuilder sb = new StringBuilder ();
8154                         if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
8155                                 sb.AppendFormat ("{0}.{1} operator {2}", Parent.GetSignatureForError (), GetName (OperatorType), Type.Type == null ? Type.ToString () : TypeManager.CSharpName (Type.Type));
8156                         }
8157                         else {
8158                                 sb.AppendFormat ("{0}.operator {1}", Parent.GetSignatureForError (), GetName (OperatorType));
8159                         }
8160
8161                         sb.Append (Parameters.GetSignatureForError ());
8162                         return sb.ToString ();
8163                 }
8164         }
8165
8166         //
8167         // This is used to compare method signatures
8168         //
8169         struct MethodSignature {
8170                 public string Name;
8171                 public Type RetType;
8172                 public Type [] Parameters;
8173                 
8174                 /// <summary>
8175                 ///    This delegate is used to extract methods which have the
8176                 ///    same signature as the argument
8177                 /// </summary>
8178                 public static MemberFilter method_signature_filter = new MemberFilter (MemberSignatureCompare);
8179                 
8180                 public MethodSignature (string name, Type ret_type, Type [] parameters)
8181                 {
8182                         Name = name;
8183                         RetType = ret_type;
8184
8185                         if (parameters == null)
8186                                 Parameters = Type.EmptyTypes;
8187                         else
8188                                 Parameters = parameters;
8189                 }
8190
8191                 public override string ToString ()
8192                 {
8193                         string pars = "";
8194                         if (Parameters.Length != 0){
8195                                 System.Text.StringBuilder sb = new System.Text.StringBuilder ();
8196                                 for (int i = 0; i < Parameters.Length; i++){
8197                                         sb.Append (Parameters [i]);
8198                                         if (i+1 < Parameters.Length)
8199                                                 sb.Append (", ");
8200                                 }
8201                                 pars = sb.ToString ();
8202                         }
8203
8204                         return String.Format ("{0} {1} ({2})", RetType, Name, pars);
8205                 }
8206                 
8207                 public override int GetHashCode ()
8208                 {
8209                         return Name.GetHashCode ();
8210                 }
8211
8212                 public override bool Equals (Object o)
8213                 {
8214                         MethodSignature other = (MethodSignature) o;
8215
8216                         if (other.Name != Name)
8217                                 return false;
8218
8219                         if (other.RetType != RetType)
8220                                 return false;
8221                         
8222                         if (Parameters == null){
8223                                 if (other.Parameters == null)
8224                                         return true;
8225                                 return false;
8226                         }
8227
8228                         if (other.Parameters == null)
8229                                 return false;
8230                         
8231                         int c = Parameters.Length;
8232                         if (other.Parameters.Length != c)
8233                                 return false;
8234
8235                         for (int i = 0; i < c; i++)
8236                                 if (other.Parameters [i] != Parameters [i])
8237                                         return false;
8238
8239                         return true;
8240                 }
8241
8242                 static bool MemberSignatureCompare (MemberInfo m, object filter_criteria)
8243                 {
8244                         MethodSignature sig = (MethodSignature) filter_criteria;
8245
8246                         if (m.Name != sig.Name)
8247                                 return false;
8248
8249                         Type ReturnType;
8250                         MethodInfo mi = m as MethodInfo;
8251                         PropertyInfo pi = m as PropertyInfo;
8252
8253                         if (mi != null)
8254                                 ReturnType = mi.ReturnType;
8255                         else if (pi != null)
8256                                 ReturnType = pi.PropertyType;
8257                         else
8258                                 return false;
8259                         
8260                         //
8261                         // we use sig.RetType == null to mean `do not check the
8262                         // method return value.  
8263                         //
8264                         if (sig.RetType != null)
8265                                 if (ReturnType != sig.RetType)
8266                                         return false;
8267
8268                         Type [] args;
8269                         if (mi != null)
8270                                 args = TypeManager.GetParameterData (mi).Types;
8271                         else
8272                                 args = TypeManager.GetArgumentTypes (pi);
8273                         Type [] sigp = sig.Parameters;
8274
8275                         if (args.Length != sigp.Length)
8276                                 return false;
8277
8278                         for (int i = args.Length; i > 0; ){
8279                                 i--;
8280                                 if (args [i] != sigp [i])
8281                                         return false;
8282                         }
8283                         return true;
8284                 }
8285         }
8286 }