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