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