2005-08-02 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / mcs / class.cs
1 //
2 // class.cs: Class and Struct handlers
3 //
4 // Authors: Miguel de Icaza (miguel@gnu.org)
5 //          Martin Baulig (martin@ximian.com)
6 //          Marek Safar (marek.safar@seznam.cz)
7 //
8 // Licensed under the terms of the GNU GPL
9 //
10 // (C) 2001, 2002, 2003 Ximian, Inc (http://www.ximian.com)
11 // (C) 2004 Novell, Inc
12 //
13 //
14 //  2002-10-11  Miguel de Icaza  <miguel@ximian.com>
15 //
16 //      * class.cs: Following the comment from 2002-09-26 to AddMethod, I
17 //      have fixed a remaining problem: not every AddXXXX was adding a
18 //      fully qualified name.  
19 //
20 //      Now everyone registers a fully qualified name in the DeclSpace as
21 //      being defined instead of the partial name.  
22 //
23 //      Downsides: we are slower than we need to be due to the excess
24 //      copies and the names being registered this way.  
25 //
26 //      The reason for this is that we currently depend (on the corlib
27 //      bootstrap for instance) that types are fully qualified, because
28 //      we dump all the types in the namespace, and we should really have
29 //      types inserted into the proper namespace, so we can only store the
30 //      basenames in the defined_names array.
31 //
32 //
33 #define CACHE
34 using System;
35 using System.Collections;
36 using System.Collections.Specialized;
37 using System.Reflection;
38 using System.Reflection.Emit;
39 using System.Runtime.CompilerServices;
40 using System.Runtime.InteropServices;
41 using System.Security;
42 using System.Security.Permissions;
43 using System.Text;
44
45 #if BOOTSTRAP_WITH_OLDLIB
46 using XmlElement = System.Object;
47 #else
48 using System.Xml;
49 #endif
50
51 using Mono.CompilerServices.SymbolWriter;
52
53 namespace Mono.CSharp {
54
55         public enum Kind {
56                 Root,
57                 Struct,
58                 Class,
59                 Interface
60         }
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                         Expression e = size_expr.Resolve (Parent.EmitContext);
5466                         if (e == null)
5467                                 return false;
5468
5469                         Constant c = e as Constant;
5470                         if (c == null) {
5471                                 Const.Error_ExpressionMustBeConstant (e.Location, GetSignatureForError ());
5472                                 return false;
5473                         }
5474
5475                         IntConstant buffer_size_const = c.ToInt (Location);
5476                         if (buffer_size_const == null)
5477                                 return false;
5478
5479                         buffer_size = buffer_size_const.Value;
5480
5481                         if (buffer_size <= 0) {
5482                                 Report.Error (1665, Location, "`{0}': Fixed size buffers must have a length greater than zero", GetSignatureForError ());
5483                                 return false;
5484                         }
5485
5486                         int type_size = Expression.GetTypeSize (MemberType);
5487
5488                         if (buffer_size > int.MaxValue / type_size) {
5489                                 Report.Error (1664, Location, "Fixed size buffer `{0}' of length `{1}' and type `{2}' exceeded 2^31 limit",
5490                                         GetSignatureForError (), buffer_size.ToString (), TypeManager.CSharpName (MemberType));
5491                                 return false;
5492                         }
5493
5494                         buffer_size *= type_size;
5495
5496                         // Define nested
5497                         string name = String.Format ("<{0}>__FixedBuffer{1}", Name, GlobalCounter++);
5498
5499                         fixed_buffer_type = Parent.TypeBuilder.DefineNestedType (name,
5500                                 TypeAttributes.NestedPublic | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit, TypeManager.value_type);
5501                         element = fixed_buffer_type.DefineField (FixedElementName, MemberType, FieldAttributes.Public);
5502                         RootContext.RegisterCompilerGeneratedType (fixed_buffer_type);
5503
5504                         FieldBuilder = Parent.TypeBuilder.DefineField (Name, fixed_buffer_type, Modifiers.FieldAttr (ModFlags));
5505                         TypeManager.RegisterFieldBase (FieldBuilder, this);
5506
5507                         return true;
5508                 }
5509
5510                 public override void Emit()
5511                 {
5512                         if (fi == null)
5513                                 fi = new FieldInfo [] { TypeManager.struct_layout_attribute_type.GetField ("Size") };
5514
5515                         object[] fi_val = new object[1];
5516                         fi_val [0] = buffer_size;
5517
5518                         CustomAttributeBuilder cab = new CustomAttributeBuilder (TypeManager.struct_layout_attribute_ctor, 
5519                                 ctor_args, fi, fi_val);
5520                         fixed_buffer_type.SetCustomAttribute (cab);
5521
5522 #if NET_2_0
5523                         cab = new CustomAttributeBuilder (TypeManager.fixed_buffer_attr_ctor, new object[] { MemberType, buffer_size } );
5524                         FieldBuilder.SetCustomAttribute (cab);
5525 #endif
5526                         base.Emit ();
5527                 }
5528
5529                 protected override bool IsFieldClsCompliant {
5530                         get {
5531                                 return false;
5532                         }
5533                 }
5534
5535                 #region IFixedField Members
5536
5537                 public FieldInfo Element {
5538                         get {
5539                                 return element;
5540                         }
5541                 }
5542
5543                 public Type ElementType {
5544                         get {
5545                                 return MemberType;
5546                         }
5547                 }
5548
5549                 #endregion
5550         }
5551
5552         //
5553         // The Field class is used to represents class/struct fields during parsing.
5554         //
5555         public class Field : FieldMember {
5556                 // <summary>
5557                 //   Modifiers allowed in a class declaration
5558                 // </summary>
5559                 const int AllowedModifiers =
5560                         Modifiers.NEW |
5561                         Modifiers.PUBLIC |
5562                         Modifiers.PROTECTED |
5563                         Modifiers.INTERNAL |
5564                         Modifiers.PRIVATE |
5565                         Modifiers.STATIC |
5566                         Modifiers.VOLATILE |
5567                         Modifiers.UNSAFE |
5568                         Modifiers.READONLY;
5569
5570                 public Field (TypeContainer parent, Expression type, int mod, string name,
5571                               Object expr_or_array_init, Attributes attrs, Location loc)
5572                         : base (parent, type, mod, AllowedModifiers, new MemberName (name, loc),
5573                                 expr_or_array_init, attrs)
5574                 {
5575                 }
5576
5577                 public override bool Define ()
5578                 {
5579                         if (!base.Define ())
5580                                 return false;
5581
5582                         if (RootContext.WarningLevel > 1){
5583                                 Type ptype = Parent.TypeBuilder.BaseType;
5584
5585                                 // ptype is only null for System.Object while compiling corlib.
5586                                 if (ptype != null){
5587                                         TypeContainer.FindMembers (
5588                                                 ptype, MemberTypes.Method,
5589                                                 BindingFlags.Public |
5590                                                 BindingFlags.Static | BindingFlags.Instance,
5591                                                 System.Type.FilterName, Name);
5592                                 }
5593                         }
5594
5595                         if ((ModFlags & Modifiers.VOLATILE) != 0){
5596                                 if (!MemberType.IsClass){
5597                                         Type vt = MemberType;
5598                                         
5599                                         if (TypeManager.IsEnumType (vt))
5600                                                 vt = TypeManager.EnumToUnderlying (MemberType);
5601
5602                                         if (!((vt == TypeManager.bool_type) ||
5603                                               (vt == TypeManager.sbyte_type) ||
5604                                               (vt == TypeManager.byte_type) ||
5605                                               (vt == TypeManager.short_type) ||
5606                                               (vt == TypeManager.ushort_type) ||
5607                                               (vt == TypeManager.int32_type) ||
5608                                               (vt == TypeManager.uint32_type) ||    
5609                                               (vt == TypeManager.char_type) ||
5610                                               (vt == TypeManager.float_type) ||
5611                                               (!vt.IsValueType))){
5612                                                 Report.Error (677, Location, "`{0}': A volatile field cannot be of the type `{1}'",
5613                                                         GetSignatureForError (), TypeManager.CSharpName (vt));
5614                                                 return false;
5615                                         }
5616                                 }
5617
5618                                 if ((ModFlags & Modifiers.READONLY) != 0){
5619                                         Report.Error (678, Location, "`{0}': A field cannot be both volatile and readonly",
5620                                                 GetSignatureForError ());
5621                                         return false;
5622                                 }
5623                         }
5624
5625                         FieldAttributes fa = Modifiers.FieldAttr (ModFlags);
5626
5627                         if (Parent.Kind == Kind.Struct && 
5628                             ((fa & FieldAttributes.Static) == 0) &&
5629                             MemberType == Parent.TypeBuilder &&
5630                             !TypeManager.IsBuiltinType (MemberType)){
5631                                 Report.Error (523, Location, "Struct member `" + Parent.Name + "." + Name + 
5632                                               "' causes a cycle in the structure layout");
5633                                 return false;
5634                         }
5635
5636                         try {
5637                                 FieldBuilder = Parent.TypeBuilder.DefineField (
5638                                         Name, MemberType, Modifiers.FieldAttr (ModFlags));
5639
5640                                 TypeManager.RegisterFieldBase (FieldBuilder, this);
5641                         }
5642                         catch (ArgumentException) {
5643                                 Report.Warning (-24, Location, "The Microsoft runtime is unable to use [void|void*] as a field type, try using the Mono runtime.");
5644                                 return false;
5645                         }
5646
5647                         return true;
5648                 }
5649
5650                 protected override bool VerifyClsCompliance (DeclSpace ds)
5651                 {
5652                         if (!base.VerifyClsCompliance (ds))
5653                                 return false;
5654
5655                         if ((ModFlags & Modifiers.VOLATILE) != 0) {
5656                                 Report.Warning (3026, 1, Location, "CLS-compliant field `{0}' cannot be volatile", GetSignatureForError ());
5657                         }
5658
5659                         return true;
5660                 }
5661         }
5662
5663         //
5664         // `set' and `get' accessors are represented with an Accessor.
5665         // 
5666         public class Accessor : IIteratorContainer {
5667                 //
5668                 // Null if the accessor is empty, or a Block if not
5669                 //
5670                 public const int AllowedModifiers = 
5671                         Modifiers.PUBLIC |
5672                         Modifiers.PROTECTED |
5673                         Modifiers.INTERNAL |
5674                         Modifiers.PRIVATE;
5675                 
5676                 public ToplevelBlock Block;
5677                 public Attributes Attributes;
5678                 public Location Location;
5679                 public int ModFlags;
5680                 public bool Yields;
5681                 
5682                 public Accessor (ToplevelBlock b, int mod, Attributes attrs, Location loc)
5683                 {
5684                         Block = b;
5685                         Attributes = attrs;
5686                         Location = loc;
5687                         ModFlags = Modifiers.Check (AllowedModifiers, mod, 0, loc);
5688                 }
5689
5690                 public void SetYields ()
5691                 {
5692                         Yields = true;
5693                 }
5694         }
5695
5696         // Ooouh Martin, templates are missing here.
5697         // When it will be possible move here a lot of child code and template method type.
5698         public abstract class AbstractPropertyEventMethod: MemberCore, IMethodData {
5699                 protected MethodData method_data;
5700                 protected ToplevelBlock block;
5701                 protected ListDictionary declarative_security;
5702
5703                 // The accessor are created event if they are not wanted.
5704                 // But we need them because their names are reserved.
5705                 // Field says whether accessor will be emited or not
5706                 public readonly bool IsDummy;
5707
5708                 protected readonly string prefix;
5709
5710                 ReturnParameter return_attributes;
5711
5712                 public AbstractPropertyEventMethod (MemberBase member, string prefix)
5713                         : base (null, SetupName (prefix, member), null)
5714                 {
5715                         this.prefix = prefix;
5716                         IsDummy = true;
5717                 }
5718
5719                 public AbstractPropertyEventMethod (MemberBase member, Accessor accessor,
5720                                                     string prefix)
5721                         : base (null, SetupName (prefix, member),
5722                                 accessor.Attributes)
5723                 {
5724                         this.prefix = prefix;
5725                         this.block = accessor.Block;
5726                 }
5727
5728                 static MemberName SetupName (string prefix, MemberBase member)
5729                 {
5730                         return new MemberName (member.MemberName.Left, prefix + member.ShortName);
5731                 }
5732
5733                 public void UpdateName (MemberBase member)
5734                 {
5735                         SetMemberName (SetupName (prefix, member));
5736                 }
5737
5738                 #region IMethodData Members
5739
5740                 public ToplevelBlock Block {
5741                         get {
5742                                 return block;
5743                         }
5744
5745                         set {
5746                                 block = value;
5747                         }
5748                 }
5749
5750                 public CallingConventions CallingConventions {
5751                         get {
5752                                 return CallingConventions.Standard;
5753                         }
5754                 }
5755
5756                 public bool IsExcluded (EmitContext ec)
5757                 {
5758                         return false;
5759                 }
5760
5761                 public MemberName MethodName {
5762                         get {
5763                                 return MemberName;
5764                         }
5765                 }
5766
5767                 public abstract ObsoleteAttribute GetObsoleteAttribute ();
5768                 public abstract Type[] ParameterTypes { get; }
5769                 public abstract Type ReturnType { get; }
5770                 public abstract EmitContext CreateEmitContext(TypeContainer tc, ILGenerator ig);
5771
5772                 #endregion
5773
5774                 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
5775                 {
5776                         if (a.Type == TypeManager.cls_compliant_attribute_type || a.Type == TypeManager.obsolete_attribute_type ||
5777                                         a.Type == TypeManager.conditional_attribute_type) {
5778                                 Report.Error (1667, a.Location,
5779                                         "Attribute `{0}' is not valid on property or event accessors. It is valid on `{1}' declarations only",
5780                                         TypeManager.CSharpName (a.Type), a.GetValidTargets ());
5781                                 return;
5782                         }
5783
5784                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
5785                                 if (declarative_security == null)
5786                                         declarative_security = new ListDictionary ();
5787                                 a.ExtractSecurityPermissionSet (declarative_security);
5788                                 return;
5789                         }
5790
5791                         if (a.Target == AttributeTargets.Method) {
5792                                 method_data.MethodBuilder.SetCustomAttribute (cb);
5793                                 return;
5794                         }
5795
5796                         if (a.Target == AttributeTargets.ReturnValue) {
5797                                 if (return_attributes == null)
5798                                         return_attributes = new ReturnParameter (method_data.MethodBuilder, Location);
5799
5800                                 return_attributes.ApplyAttributeBuilder (a, cb);
5801                                 return;
5802                         }
5803
5804                         ApplyToExtraTarget (a, cb);
5805                 }
5806
5807                 virtual protected void ApplyToExtraTarget (Attribute a, CustomAttributeBuilder cb)
5808                 {
5809                         System.Diagnostics.Debug.Fail ("You forgot to define special attribute target handling");
5810                 }
5811
5812                 public override bool Define()
5813                 {
5814                         throw new NotSupportedException ();
5815                 }
5816
5817                 public virtual void Emit (TypeContainer container)
5818                 {
5819                         EmitMethod (container);
5820
5821                         if (declarative_security != null) {
5822                                 foreach (DictionaryEntry de in declarative_security) {
5823                                         method_data.MethodBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
5824                                 }
5825                         }
5826
5827                         block = null;
5828                 }
5829
5830                 protected virtual void EmitMethod (TypeContainer container)
5831                 {
5832                         method_data.Emit (container, this);
5833                 }
5834
5835                 public override bool IsClsCompliaceRequired(DeclSpace ds)
5836                 {
5837                         return false;
5838                 }
5839
5840                 public bool IsDuplicateImplementation (MethodCore method)
5841                 {
5842                         if (!MemberName.Equals (method.MemberName))
5843                                 return false;
5844
5845                         Type[] param_types = method.ParameterTypes;
5846
5847                         if (param_types.Length != ParameterTypes.Length)
5848                                 return false;
5849
5850                         for (int i = 0; i < param_types.Length; i++)
5851                                 if (param_types [i] != ParameterTypes [i])
5852                                         return false;
5853
5854                         Report.SymbolRelatedToPreviousError (method);
5855                         Report.Error (111, Location, TypeContainer.Error111, method.GetSignatureForError ());
5856                         return true;
5857                 }
5858
5859                 public override bool IsUsed
5860                 {
5861                         get {
5862                                 if (IsDummy)
5863                                         return false;
5864
5865                                 return base.IsUsed;
5866                         }
5867                 }
5868
5869                 public new Location Location { 
5870                         get {
5871                                 return base.Location;
5872                         }
5873                 }
5874
5875                 //
5876                 //   Represents header string for documentation comment.
5877                 //
5878                 public override string DocCommentHeader {
5879                         get { throw new InvalidOperationException ("Unexpected attempt to get doc comment from " + this.GetType () + "."); }
5880                 }
5881
5882                 protected override void VerifyObsoleteAttribute()
5883                 {
5884                 }
5885
5886         }
5887
5888         //
5889         // Properties and Indexers both generate PropertyBuilders, we use this to share 
5890         // their common bits.
5891         //
5892         abstract public class PropertyBase : MethodCore {
5893
5894                 public class GetMethod: PropertyMethod
5895                 {
5896                         static string[] attribute_targets = new string [] { "method", "return" };
5897
5898                         public GetMethod (MethodCore method):
5899                                 base (method, "get_")
5900                         {
5901                         }
5902
5903                         public GetMethod (MethodCore method, Accessor accessor):
5904                                 base (method, accessor, "get_")
5905                         {
5906                         }
5907
5908                         public override MethodBuilder Define(TypeContainer container)
5909                         {
5910                                 base.Define (container);
5911                                 
5912                                 method_data = new MethodData (method, method.ParameterInfo, ModFlags, flags, this);
5913
5914                                 if (!method_data.Define (container))
5915                                         return null;
5916
5917                                 return method_data.MethodBuilder;
5918                         }
5919
5920                         public override Type ReturnType {
5921                                 get {
5922                                         return method.MemberType;
5923                                 }
5924                         }
5925
5926                         public override string[] ValidAttributeTargets {
5927                                 get {
5928                                         return attribute_targets;
5929                                 }
5930                         }
5931                 }
5932
5933                 public class SetMethod: PropertyMethod {
5934
5935                         static string[] attribute_targets = new string [] { "method", "param", "return" };
5936                         ImplicitParameter param_attr;
5937
5938                         public SetMethod (MethodCore method):
5939                                 base (method, "set_")
5940                         {
5941                         }
5942
5943                         public SetMethod (MethodCore method, Accessor accessor):
5944                                 base (method, accessor, "set_")
5945                         {
5946                         }
5947
5948                         protected override void ApplyToExtraTarget(Attribute a, CustomAttributeBuilder cb)
5949                         {
5950                                 if (a.Target == AttributeTargets.Parameter) {
5951                                         if (param_attr == null)
5952                                                 param_attr = new ImplicitParameter (method_data.MethodBuilder, method.Location);
5953
5954                                         param_attr.ApplyAttributeBuilder (a, cb);
5955                                         return;
5956                                 }
5957
5958                                 base.ApplyAttributeBuilder (a, cb);
5959                         }
5960
5961                         protected virtual InternalParameters GetParameterInfo (EmitContext ec)
5962                         {
5963                                 Parameter [] parms = new Parameter [1];
5964                                 parms [0] = new Parameter (method.Type, "value", Parameter.Modifier.NONE, null, method.Location);
5965                                 Parameters parameters = new Parameters (parms, null);
5966
5967                                 bool old_unsafe = ec.InUnsafe;
5968                                 ec.InUnsafe = InUnsafe;
5969                                 Type [] types = parameters.GetParameterInfo (ec);
5970                                 ec.InUnsafe = old_unsafe;
5971
5972                                 return new InternalParameters (types, parameters);
5973                         }
5974
5975                         public override MethodBuilder Define (TypeContainer container)
5976                         {
5977                                 if (container.EmitContext == null)
5978                                         throw new InternalErrorException ("SetMethod.Define called too early");
5979                                         
5980                                 base.Define (container);
5981                                 
5982                                 method_data = new MethodData (method, GetParameterInfo (container.EmitContext), ModFlags, flags, this);
5983
5984                                 if (!method_data.Define (container))
5985                                         return null;
5986
5987                                 return method_data.MethodBuilder;
5988                         }
5989
5990                         public override Type[] ParameterTypes {
5991                                 get {
5992                                         return new Type[] { method.MemberType };
5993                                 }
5994                         }
5995
5996                         public override Type ReturnType {
5997                                 get {
5998                                         return TypeManager.void_type;
5999                                 }
6000                         }
6001
6002                         public override string[] ValidAttributeTargets {
6003                                 get {
6004                                         return attribute_targets;
6005                                 }
6006                         }
6007                 }
6008
6009                 static string[] attribute_targets = new string [] { "property" };
6010
6011                 public abstract class PropertyMethod: AbstractPropertyEventMethod
6012                 {
6013                         protected readonly MethodCore method;
6014                         protected MethodAttributes flags;
6015                         bool yields;
6016
6017                         public PropertyMethod (MethodCore method, string prefix)
6018                                 : base (method, prefix)
6019                         {
6020                                 this.method = method;
6021                                 Parent = method.Parent;
6022                         }
6023
6024                         public PropertyMethod (MethodCore method, Accessor accessor,
6025                                                string prefix)
6026                                 : base (method, accessor, prefix)
6027                         {
6028                                 this.method = method;
6029                                 Parent = method.Parent;
6030                                 this.ModFlags = accessor.ModFlags;
6031                                 yields = accessor.Yields;
6032
6033                                 if (accessor.ModFlags != 0 && RootContext.Version == LanguageVersion.ISO_1) {
6034                                         Report.FeatureIsNotStandardized (Location, "access modifiers on properties");
6035                                 }
6036                         }
6037
6038                         public override AttributeTargets AttributeTargets {
6039                                 get {
6040                                         return AttributeTargets.Method;
6041                                 }
6042                         }
6043
6044                         public override bool IsClsCompliaceRequired(DeclSpace ds)
6045                         {
6046                                 return method.IsClsCompliaceRequired (ds);
6047                         }
6048
6049                         public InternalParameters ParameterInfo 
6050                         {
6051                                 get {
6052                                         return method_data.ParameterInfo;
6053                                 }
6054                         }
6055
6056                         public virtual MethodBuilder Define (TypeContainer container)
6057                         {
6058                                 if (!method.CheckAbstractAndExtern (block != null))
6059                                         return null;
6060
6061                                 //
6062                                 // Check for custom access modifier
6063                                 //
6064                                 if (ModFlags == 0) {
6065                                         ModFlags = method.ModFlags;
6066                                         flags = method.flags;
6067                                 } else {
6068                                         if (container.Kind == Kind.Interface)
6069                                                 Report.Error (275, Location, "`{0}': accessibility modifiers may not be used on accessors in an interface",
6070                                                         GetSignatureForError ());
6071
6072                                         if ((method.ModFlags & Modifiers.ABSTRACT) != 0 && (ModFlags & Modifiers.PRIVATE) != 0) {
6073                                                 Report.Error (442, Location, "`{0}': abstract properties cannot have private accessors", GetSignatureForError ());
6074                                         }
6075
6076                                         CheckModifiers (container, ModFlags);
6077                                         ModFlags |= (method.ModFlags & (~Modifiers.Accessibility));
6078                                         ModFlags |= Modifiers.PROPERTY_CUSTOM;
6079                                         flags = Modifiers.MethodAttr (ModFlags);
6080                                         flags |= (method.flags & (~MethodAttributes.MemberAccessMask));
6081                                 }
6082
6083                                 //
6084                                 // Setup iterator if we are one
6085                                 //
6086                                 if (yields) {
6087                                         Iterator iterator = new Iterator (this,
6088                                                 Parent, method.ParameterInfo, ModFlags);
6089                                         
6090                                         if (!iterator.DefineIterator ())
6091                                                 return null;
6092                                 }
6093
6094                                 return null;
6095                         }
6096
6097                         public bool HasCustomAccessModifier
6098                         {
6099                                 get {
6100                                         return (ModFlags & Modifiers.PROPERTY_CUSTOM) != 0;
6101                                 }
6102                         }
6103
6104                         public override Type[] ParameterTypes {
6105                                 get {
6106                                         return TypeManager.NoTypes;
6107                                 }
6108                         }
6109
6110                         public override EmitContext CreateEmitContext (TypeContainer tc,
6111                                                                        ILGenerator ig)
6112                         {
6113                                 return new EmitContext (
6114                                         tc, method.Parent, method.Location, ig, ReturnType,
6115                                         method.ModFlags, false);
6116                         }
6117
6118                         public override ObsoleteAttribute GetObsoleteAttribute ()
6119                         {
6120                                 return method.GetObsoleteAttribute (method.Parent);
6121                         }
6122
6123                         public override string GetSignatureForError()
6124                         {
6125                                 return method.GetSignatureForError () + '.' + prefix.Substring (0, 3);
6126                         }
6127                         
6128                         void CheckModifiers (TypeContainer container, int modflags)
6129                         {
6130                                 int flags = 0;
6131                                 int mflags = method.ModFlags & Modifiers.Accessibility;
6132
6133                                 if ((mflags & Modifiers.PUBLIC) != 0) {
6134                                         flags |= Modifiers.PROTECTED | Modifiers.INTERNAL | Modifiers.PRIVATE;
6135                                 }
6136                                 else if ((mflags & Modifiers.PROTECTED) != 0) {
6137                                         if ((mflags & Modifiers.INTERNAL) != 0)
6138                                                 flags |= Modifiers.PROTECTED | Modifiers.INTERNAL;
6139
6140                                         flags |= Modifiers.PRIVATE;
6141                                 }
6142                                 else if ((mflags & Modifiers.INTERNAL) != 0)
6143                                         flags |= Modifiers.PRIVATE;
6144
6145                                 if ((mflags == modflags) || (modflags & (~flags)) != 0) {
6146                                         Report.Error (273, Location,
6147                                                 "The accessibility modifier of the `{0}' accessor must be more restrictive than the modifier of the property or indexer `{1}'",
6148                                                 GetSignatureForError (), method.GetSignatureForError ());
6149                                 }
6150                         }
6151
6152                         public override bool MarkForDuplicationCheck ()
6153                         {
6154                                 caching_flags |= Flags.TestMethodDuplication;
6155                                 return true;
6156                         }
6157                 }
6158
6159
6160                 public PropertyMethod Get, Set;
6161                 public PropertyBuilder PropertyBuilder;
6162                 public MethodBuilder GetBuilder, SetBuilder;
6163
6164                 protected EmitContext ec;
6165
6166                 public PropertyBase (TypeContainer ds, Expression type, int mod_flags,
6167                                      int allowed_mod, bool is_iface, MemberName name,
6168                                      Parameters parameters, Attributes attrs)
6169                         : base (ds, type, mod_flags, allowed_mod, is_iface, name,
6170                                 attrs, parameters)
6171                 {
6172                 }
6173
6174                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
6175                 {
6176                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
6177                                 a.Error_InvalidSecurityParent ();
6178                                 return;
6179                         }
6180
6181                         PropertyBuilder.SetCustomAttribute (cb);
6182                 }
6183
6184                 public override AttributeTargets AttributeTargets {
6185                         get {
6186                                 return AttributeTargets.Property;
6187                         }
6188                 }
6189
6190                 public override bool Define ()
6191                 {
6192                         if (!DoDefine ())
6193                                 return false;
6194
6195                         if (!IsTypePermitted ())
6196                                 return false;
6197
6198                         return true;
6199                 }
6200
6201                 protected override bool DoDefine ()
6202                 {
6203                         if (!base.DoDefine ())
6204                                 return false;
6205
6206                         //
6207                         // Accessors modifiers check
6208                         //
6209                         if (Get.ModFlags != 0 && Set.ModFlags != 0) {
6210                                 Report.Error (274, Location, "`{0}': Cannot specify accessibility modifiers for both accessors of the property or indexer",
6211                                                 GetSignatureForError ());
6212                                 return false;
6213                         }
6214
6215                         if ((Get.IsDummy || Set.IsDummy)
6216                                         && (Get.ModFlags != 0 || Set.ModFlags != 0) && (ModFlags & Modifiers.OVERRIDE) == 0) {
6217                                 Report.Error (276, Location, 
6218                                         "`{0}': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor",
6219                                         GetSignatureForError ());
6220                                 return false;
6221                         }
6222
6223                         if (MemberType.IsAbstract && MemberType.IsSealed) {
6224                                 Report.Error (722, Location, Error722, TypeManager.CSharpName (MemberType));
6225                                 return false;
6226                         }
6227
6228                         ec = new EmitContext (Parent, Location, null, MemberType, ModFlags);
6229                         return true;
6230                 }
6231
6232                 protected override bool CheckForDuplications ()
6233                 {
6234                         ArrayList ar = Parent.Indexers;
6235                         if (ar != null) {
6236                                 int arLen = ar.Count;
6237                                         
6238                                 for (int i = 0; i < arLen; i++) {
6239                                         Indexer m = (Indexer) ar [i];
6240                                         if (IsDuplicateImplementation (m))
6241                                                 return false;
6242                                 }
6243                         }
6244
6245                         ar = Parent.Properties;
6246                         if (ar != null) {
6247                                 int arLen = ar.Count;
6248                                         
6249                                 for (int i = 0; i < arLen; i++) {
6250                                         Property m = (Property) ar [i];
6251                                         if (IsDuplicateImplementation (m))
6252                                                 return false;
6253                                 }
6254                         }
6255
6256                         return true;
6257                 }
6258
6259                 // TODO: rename to Resolve......
6260                 protected override MethodInfo FindOutBaseMethod (TypeContainer container, ref Type base_ret_type)
6261                 {
6262                         PropertyInfo base_property = container.BaseCache.FindMemberToOverride (
6263                                 container.TypeBuilder, Name, ParameterTypes, true) as PropertyInfo;
6264   
6265                         if (base_property == null)
6266                                 return null;
6267   
6268                         base_ret_type = base_property.PropertyType;
6269                         MethodInfo get_accessor = base_property.GetGetMethod (true);
6270                         MethodInfo set_accessor = base_property.GetSetMethod (true);
6271                         MethodAttributes get_accessor_access, set_accessor_access;
6272
6273                         if ((ModFlags & Modifiers.OVERRIDE) != 0) {
6274                                 if (Get != null && !Get.IsDummy && get_accessor == null) {
6275                                         Report.SymbolRelatedToPreviousError (base_property);
6276                                         Report.Error (545, Location, "`{0}.get': cannot override because `{1}' does not have an overridable get accessor", GetSignatureForError (), TypeManager.GetFullNameSignature (base_property));
6277                                 }
6278
6279                                 if (Set != null && !Set.IsDummy && set_accessor == null) {
6280                                         Report.SymbolRelatedToPreviousError (base_property);
6281                                         Report.Error (546, Location, "`{0}.set': cannot override because `{1}' does not have an overridable set accessor", GetSignatureForError (), TypeManager.GetFullNameSignature (base_property));
6282                                 }
6283                         }
6284                         
6285                         //
6286                         // Check base class accessors access
6287                         //
6288
6289                         // TODO: rewrite to reuse Get|Set.CheckAccessModifiers and share code there
6290                         get_accessor_access = set_accessor_access = 0;
6291                         if ((ModFlags & Modifiers.NEW) == 0) {
6292                                 if (get_accessor != null) {
6293                                         MethodAttributes get_flags = Modifiers.MethodAttr (Get.ModFlags != 0 ? Get.ModFlags : ModFlags);
6294                                         get_accessor_access = (get_accessor.Attributes & MethodAttributes.MemberAccessMask);
6295
6296                                         if (!Get.IsDummy && !CheckAccessModifiers (get_flags & MethodAttributes.MemberAccessMask, get_accessor_access, get_accessor))
6297                                                 Error_CannotChangeAccessModifiers (get_accessor, get_accessor_access,  ".get");
6298                                 }
6299
6300                                 if (set_accessor != null)  {
6301                                         MethodAttributes set_flags = Modifiers.MethodAttr (Set.ModFlags != 0 ? Set.ModFlags : ModFlags);
6302                                         set_accessor_access = (set_accessor.Attributes & MethodAttributes.MemberAccessMask);
6303
6304                                         if (!Set.IsDummy && !CheckAccessModifiers (set_flags & MethodAttributes.MemberAccessMask, set_accessor_access, set_accessor))
6305                                                 Error_CannotChangeAccessModifiers (set_accessor, set_accessor_access, ".set");
6306                                 }
6307                         }
6308
6309                         //
6310                         // Get the less restrictive access
6311                         //
6312                         return get_accessor_access > set_accessor_access ? get_accessor : set_accessor;
6313                 }
6314
6315                 public override void Emit ()
6316                 {
6317                         //
6318                         // The PropertyBuilder can be null for explicit implementations, in that
6319                         // case, we do not actually emit the ".property", so there is nowhere to
6320                         // put the attribute
6321                         //
6322                         if (PropertyBuilder != null && OptAttributes != null)
6323                                 OptAttributes.Emit (ec, this);
6324
6325                         if (!Get.IsDummy)
6326                                 Get.Emit (Parent);
6327
6328                         if (!Set.IsDummy)
6329                                 Set.Emit (Parent);
6330
6331                         base.Emit ();
6332                 }
6333
6334                 /// <summary>
6335                 /// Tests whether accessors are not in collision with some method (CS0111)
6336                 /// </summary>
6337                 public bool AreAccessorsDuplicateImplementation (MethodCore mc)
6338                 {
6339                         return Get.IsDuplicateImplementation (mc) || Set.IsDuplicateImplementation (mc);
6340                 }
6341
6342                 public override bool IsUsed
6343                 {
6344                         get {
6345                                 if (IsExplicitImpl)
6346                                         return true;
6347
6348                                 return Get.IsUsed | Set.IsUsed;
6349                         }
6350                 }
6351
6352                 protected override void SetMemberName (MemberName new_name)
6353                 {
6354                         base.SetMemberName (new_name);
6355
6356                         Get.UpdateName (this);
6357                         Set.UpdateName (this);
6358                 }
6359
6360                 public override string[] ValidAttributeTargets {
6361                         get {
6362                                 return attribute_targets;
6363                         }
6364                 }
6365
6366                 //
6367                 //   Represents header string for documentation comment.
6368                 //
6369                 public override string DocCommentHeader {
6370                         get { return "P:"; }
6371                 }
6372         }
6373                         
6374         public class Property : PropertyBase {
6375                 const int AllowedModifiers =
6376                         Modifiers.NEW |
6377                         Modifiers.PUBLIC |
6378                         Modifiers.PROTECTED |
6379                         Modifiers.INTERNAL |
6380                         Modifiers.PRIVATE |
6381                         Modifiers.STATIC |
6382                         Modifiers.SEALED |
6383                         Modifiers.OVERRIDE |
6384                         Modifiers.ABSTRACT |
6385                         Modifiers.UNSAFE |
6386                         Modifiers.EXTERN |
6387                         Modifiers.METHOD_YIELDS |
6388                         Modifiers.VIRTUAL;
6389
6390                 const int AllowedInterfaceModifiers =
6391                         Modifiers.NEW;
6392
6393                 public Property (TypeContainer ds, Expression type, int mod, bool is_iface,
6394                                  MemberName name, Attributes attrs, Accessor get_block,
6395                                  Accessor set_block)
6396                         : base (ds, type, mod,
6397                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
6398                                 is_iface, name, Parameters.EmptyReadOnlyParameters, attrs)
6399                 {
6400                         if (get_block == null)
6401                                 Get = new GetMethod (this);
6402                         else
6403                                 Get = new GetMethod (this, get_block);
6404
6405                         if (set_block == null)
6406                                 Set = new SetMethod (this);
6407                         else
6408                                 Set = new SetMethod (this, set_block);
6409                 }
6410
6411                 public override bool Define ()
6412                 {
6413                         if (!base.Define ())
6414                                 return false;
6415
6416                         if (!CheckBase ())
6417                                 return false;
6418
6419                         flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
6420
6421                         if (!Get.IsDummy) {
6422                                 GetBuilder = Get.Define (Parent);
6423                                 if (GetBuilder == null)
6424                                         return false;
6425                         }
6426
6427                         if (!Set.IsDummy) {
6428                                 SetBuilder = Set.Define (Parent);
6429                                 if (SetBuilder == null)
6430                                         return false;
6431
6432                                 SetBuilder.DefineParameter (1, ParameterAttributes.None, "value"); 
6433                         }
6434
6435                         // FIXME - PropertyAttributes.HasDefault ?
6436                         
6437                         PropertyAttributes prop_attr = PropertyAttributes.None;
6438                         if (!IsInterface)
6439                                 prop_attr |= PropertyAttributes.RTSpecialName |
6440                                         PropertyAttributes.SpecialName;
6441
6442                         PropertyBuilder = Parent.TypeBuilder.DefineProperty (
6443                              Name, prop_attr, MemberType, null);
6444                         
6445                         if (!Get.IsDummy)
6446                                 PropertyBuilder.SetGetMethod (GetBuilder);
6447                                 
6448                         if (!Set.IsDummy)
6449                                 PropertyBuilder.SetSetMethod (SetBuilder);
6450                         
6451                         TypeManager.RegisterProperty (PropertyBuilder, GetBuilder, SetBuilder);
6452                         return true;
6453                 }
6454         }
6455
6456         /// </summary>
6457         ///  Gigantic workaround  for lameness in SRE follows :
6458         ///  This class derives from EventInfo and attempts to basically
6459         ///  wrap around the EventBuilder so that FindMembers can quickly
6460         ///  return this in it search for members
6461         /// </summary>
6462         public class MyEventBuilder : EventInfo {
6463                 
6464                 //
6465                 // We use this to "point" to our Builder which is
6466                 // not really a MemberInfo
6467                 //
6468                 EventBuilder MyBuilder;
6469                 
6470                 //
6471                 // We "catch" and wrap these methods
6472                 //
6473                 MethodInfo raise, remove, add;
6474
6475                 EventAttributes attributes;
6476                 Type declaring_type, reflected_type, event_type;
6477                 string name;
6478
6479                 Event my_event;
6480
6481                 public MyEventBuilder (Event ev, TypeBuilder type_builder, string name, EventAttributes event_attr, Type event_type)
6482                 {
6483                         MyBuilder = type_builder.DefineEvent (name, event_attr, event_type);
6484
6485                         // And now store the values in our own fields.
6486                         
6487                         declaring_type = type_builder;
6488
6489                         reflected_type = type_builder;
6490                         
6491                         attributes = event_attr;
6492                         this.name = name;
6493                         my_event = ev;
6494                         this.event_type = event_type;
6495                 }
6496                 
6497                 //
6498                 // Methods that you have to override.  Note that you only need 
6499                 // to "implement" the variants that take the argument (those are
6500                 // the "abstract" methods, the others (GetAddMethod()) are 
6501                 // regular.
6502                 //
6503                 public override MethodInfo GetAddMethod (bool nonPublic)
6504                 {
6505                         return add;
6506                 }
6507                 
6508                 public override MethodInfo GetRemoveMethod (bool nonPublic)
6509                 {
6510                         return remove;
6511                 }
6512                 
6513                 public override MethodInfo GetRaiseMethod (bool nonPublic)
6514                 {
6515                         return raise;
6516                 }
6517                 
6518                 //
6519                 // These methods make "MyEventInfo" look like a Builder
6520                 //
6521                 public void SetRaiseMethod (MethodBuilder raiseMethod)
6522                 {
6523                         raise = raiseMethod;
6524                         MyBuilder.SetRaiseMethod (raiseMethod);
6525                 }
6526
6527                 public void SetRemoveOnMethod (MethodBuilder removeMethod)
6528                 {
6529                         remove = removeMethod;
6530                         MyBuilder.SetRemoveOnMethod (removeMethod);
6531                 }
6532
6533                 public void SetAddOnMethod (MethodBuilder addMethod)
6534                 {
6535                         add = addMethod;
6536                         MyBuilder.SetAddOnMethod (addMethod);
6537                 }
6538
6539                 public void SetCustomAttribute (CustomAttributeBuilder cb)
6540                 {
6541                         MyBuilder.SetCustomAttribute (cb);
6542                 }
6543                 
6544                 public override object [] GetCustomAttributes (bool inherit)
6545                 {
6546                         // FIXME : There's nothing which can be seemingly done here because
6547                         // we have no way of getting at the custom attribute objects of the
6548                         // EventBuilder !
6549                         return null;
6550                 }
6551
6552                 public override object [] GetCustomAttributes (Type t, bool inherit)
6553                 {
6554                         // FIXME : Same here !
6555                         return null;
6556                 }
6557
6558                 public override bool IsDefined (Type t, bool b)
6559                 {
6560                         return true;
6561                 }
6562
6563                 public override EventAttributes Attributes {
6564                         get {
6565                                 return attributes;
6566                         }
6567                 }
6568
6569                 public override string Name {
6570                         get {
6571                                 return name;
6572                         }
6573                 }
6574
6575                 public override Type DeclaringType {
6576                         get {
6577                                 return declaring_type;
6578                         }
6579                 }
6580
6581                 public override Type ReflectedType {
6582                         get {
6583                                 return reflected_type;
6584                         }
6585                 }
6586
6587                 public Type EventType {
6588                         get {
6589                                 return event_type;
6590                         }
6591                 }
6592                 
6593                 public void SetUsed ()
6594                 {
6595                         if (my_event != null) {
6596                                 my_event.SetAssigned ();
6597                                 my_event.SetMemberIsUsed ();
6598                         }
6599                 }
6600         }
6601         
6602         /// <summary>
6603         /// For case when event is declared like property (with add and remove accessors).
6604         /// </summary>
6605         public class EventProperty: Event {
6606
6607                 static string[] attribute_targets = new string [] { "event" }; // "property" target was disabled for 2.0 version
6608
6609                 public EventProperty (TypeContainer parent, Expression type, int mod_flags,
6610                                       bool is_iface, MemberName name, Object init,
6611                                       Attributes attrs, Accessor add, Accessor remove)
6612                         : base (parent, type, mod_flags, is_iface, name, init, attrs)
6613                 {
6614                         Add = new AddDelegateMethod (this, add);
6615                         Remove = new RemoveDelegateMethod (this, remove);
6616
6617                         // For this event syntax we don't report error CS0067
6618                         // because it is hard to do it.
6619                         SetAssigned ();
6620                 }
6621
6622                 public override string[] ValidAttributeTargets {
6623                         get {
6624                                 return attribute_targets;
6625                         }
6626                 }
6627         }
6628
6629         /// <summary>
6630         /// Event is declared like field.
6631         /// </summary>
6632         public class EventField: Event {
6633
6634                 static string[] attribute_targets = new string [] { "event", "field", "method" };
6635                 static string[] attribute_targets_interface = new string[] { "event", "method" };
6636
6637                 public EventField (TypeContainer parent, Expression type, int mod_flags,
6638                                    bool is_iface, MemberName name, Object init,
6639                                    Attributes attrs)
6640                         : base (parent, type, mod_flags, is_iface, name, init, attrs)
6641                 {
6642                         Add = new AddDelegateMethod (this);
6643                         Remove = new RemoveDelegateMethod (this);
6644                 }
6645
6646                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
6647                 {
6648                         if (a.Target == AttributeTargets.Field) {
6649                                 FieldBuilder.SetCustomAttribute (cb);
6650                                 return;
6651                         }
6652
6653                         if (a.Target == AttributeTargets.Method) {
6654                                 Add.ApplyAttributeBuilder (a, cb);
6655                                 Remove.ApplyAttributeBuilder (a, cb);
6656                                 return;
6657                         }
6658
6659                         base.ApplyAttributeBuilder (a, cb);
6660                 }
6661
6662                 public override string[] ValidAttributeTargets {
6663                         get {
6664                                 return IsInterface ? attribute_targets_interface : attribute_targets;
6665                         }
6666                 }
6667         }
6668
6669         public abstract class Event : FieldBase {
6670
6671                 protected sealed class AddDelegateMethod: DelegateMethod
6672                 {
6673
6674                         public AddDelegateMethod (Event method):
6675                                 base (method, "add_")
6676                         {
6677                         }
6678
6679                         public AddDelegateMethod (Event method, Accessor accessor):
6680                                 base (method, accessor, "add_")
6681                         {
6682                         }
6683
6684                         protected override MethodInfo DelegateMethodInfo {
6685                                 get {
6686                                         return TypeManager.delegate_combine_delegate_delegate;
6687                                 }
6688                         }
6689
6690                 }
6691
6692                 protected sealed class RemoveDelegateMethod: DelegateMethod
6693                 {
6694                         public RemoveDelegateMethod (Event method):
6695                                 base (method, "remove_")
6696                         {
6697                         }
6698
6699                         public RemoveDelegateMethod (Event method, Accessor accessor):
6700                                 base (method, accessor, "remove_")
6701                         {
6702                         }
6703
6704                         protected override MethodInfo DelegateMethodInfo {
6705                                 get {
6706                                         return TypeManager.delegate_remove_delegate_delegate;
6707                                 }
6708                         }
6709
6710                 }
6711
6712                 public abstract class DelegateMethod: AbstractPropertyEventMethod
6713                 {
6714                         protected readonly Event method;
6715                         ImplicitParameter param_attr;
6716
6717                         static string[] attribute_targets = new string [] { "method", "param", "return" };
6718
6719                         public DelegateMethod (Event method, string prefix)
6720                                 : base (method, prefix)
6721                         {
6722                                 this.method = method;
6723                         }
6724
6725                         public DelegateMethod (Event method, Accessor accessor, string prefix)
6726                                 : base (method, accessor, prefix)
6727                         {
6728                                 this.method = method;
6729                         }
6730
6731                         protected override void ApplyToExtraTarget(Attribute a, CustomAttributeBuilder cb)
6732                         {
6733                                 if (a.Target == AttributeTargets.Parameter) {
6734                                         if (param_attr == null)
6735                                                 param_attr = new ImplicitParameter (method_data.MethodBuilder, method.Location);
6736
6737                                         param_attr.ApplyAttributeBuilder (a, cb);
6738                                         return;
6739                                 }
6740
6741                                 base.ApplyAttributeBuilder (a, cb);
6742                         }
6743
6744                         public override AttributeTargets AttributeTargets {
6745                                 get {
6746                                         return AttributeTargets.Method;
6747                                 }
6748                         }
6749
6750                         public override bool IsClsCompliaceRequired(DeclSpace ds)
6751                         {
6752                                 return method.IsClsCompliaceRequired (ds);
6753                         }
6754
6755                         public MethodBuilder Define (TypeContainer container, InternalParameters ip)
6756                         {
6757                                 method_data = new MethodData (method, ip, method.ModFlags,
6758                                         method.flags | MethodAttributes.HideBySig | MethodAttributes.SpecialName, this);
6759
6760                                 if (!method_data.Define (container))
6761                                         return null;
6762
6763                                 MethodBuilder mb = method_data.MethodBuilder;
6764                                 mb.DefineParameter (1, ParameterAttributes.None, "value");
6765                                 return mb;
6766                         }
6767
6768
6769                         protected override void EmitMethod (TypeContainer tc)
6770                         {
6771                                 if (block != null) {
6772                                         base.EmitMethod (tc);
6773                                         return;
6774                                 }
6775
6776                                 if ((method.ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
6777                                         return;
6778
6779                                 ILGenerator ig = method_data.MethodBuilder.GetILGenerator ();
6780                                 FieldInfo field_info = (FieldInfo)method.FieldBuilder;
6781
6782                                 method_data.MethodBuilder.SetImplementationFlags (MethodImplAttributes.Synchronized);
6783                                 if ((method.ModFlags & Modifiers.STATIC) != 0) {
6784                                         ig.Emit (OpCodes.Ldsfld, field_info);
6785                                         ig.Emit (OpCodes.Ldarg_0);
6786                                         ig.Emit (OpCodes.Call, DelegateMethodInfo);
6787                                         ig.Emit (OpCodes.Castclass, method.MemberType);
6788                                         ig.Emit (OpCodes.Stsfld, field_info);
6789                                 } else {
6790                                         ig.Emit (OpCodes.Ldarg_0);
6791                                         ig.Emit (OpCodes.Ldarg_0);
6792                                         ig.Emit (OpCodes.Ldfld, field_info);
6793                                         ig.Emit (OpCodes.Ldarg_1);
6794                                         ig.Emit (OpCodes.Call, DelegateMethodInfo);
6795                                         ig.Emit (OpCodes.Castclass, method.MemberType);
6796                                         ig.Emit (OpCodes.Stfld, field_info);
6797                                 }
6798                                 ig.Emit (OpCodes.Ret);
6799                         }
6800
6801                         protected abstract MethodInfo DelegateMethodInfo { get; }
6802
6803                         public override Type[] ParameterTypes {
6804                                 get {
6805                                         return new Type[] { method.MemberType };
6806                                 }
6807                         }
6808
6809                         public override Type ReturnType {
6810                                 get {
6811                                         return TypeManager.void_type;
6812                                 }
6813                         }
6814
6815                         public override EmitContext CreateEmitContext (TypeContainer tc,
6816                                                                        ILGenerator ig)
6817                         {
6818                                 return new EmitContext (
6819                                         tc, method.Parent, Location, ig, ReturnType,
6820                                         method.ModFlags, false);
6821                         }
6822
6823                         public override ObsoleteAttribute GetObsoleteAttribute ()
6824                         {
6825                                 return method.GetObsoleteAttribute (method.Parent);
6826                         }
6827
6828                         public override string[] ValidAttributeTargets {
6829                                 get {
6830                                         return attribute_targets;
6831                                 }
6832                         }
6833                 }
6834
6835
6836                 const int AllowedModifiers =
6837                         Modifiers.NEW |
6838                         Modifiers.PUBLIC |
6839                         Modifiers.PROTECTED |
6840                         Modifiers.INTERNAL |
6841                         Modifiers.PRIVATE |
6842                         Modifiers.STATIC |
6843                         Modifiers.VIRTUAL |
6844                         Modifiers.SEALED |
6845                         Modifiers.OVERRIDE |
6846                         Modifiers.UNSAFE |
6847                         Modifiers.ABSTRACT;
6848
6849                 const int AllowedInterfaceModifiers =
6850                         Modifiers.NEW;
6851
6852                 public DelegateMethod Add, Remove;
6853                 public MyEventBuilder     EventBuilder;
6854                 public MethodBuilder AddBuilder, RemoveBuilder;
6855
6856                 public Event (TypeContainer parent, Expression type, int mod_flags,
6857                               bool is_iface, MemberName name, Object init, Attributes attrs)
6858                         : base (parent, type, mod_flags,
6859                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
6860                                 name, init, attrs)
6861                 {
6862                         IsInterface = is_iface;
6863                 }
6864
6865                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
6866                 {
6867                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
6868                                 a.Error_InvalidSecurityParent ();
6869                                 return;
6870                         }
6871                         
6872                         EventBuilder.SetCustomAttribute (cb);
6873                 }
6874
6875                 public bool AreAccessorsDuplicateImplementation (MethodCore mc)
6876                 {
6877                         return Add.IsDuplicateImplementation (mc) || Remove.IsDuplicateImplementation (mc);
6878                 }
6879
6880                 public override AttributeTargets AttributeTargets {
6881                         get {
6882                                 return AttributeTargets.Event;
6883                         }
6884                 }
6885
6886                 public override bool Define ()
6887                 {
6888                         EventAttributes e_attr;
6889                         e_attr = EventAttributes.None;
6890
6891                         if (!DoDefine ())
6892                                 return false;
6893
6894                         if (init != null && ((ModFlags & Modifiers.ABSTRACT) != 0)){
6895                                 Report.Error (74, Location, "`" + GetSignatureForError () +
6896                                               "': abstract event cannot have an initializer");
6897                                 return false;
6898                         }
6899                         
6900                         if (!MemberType.IsSubclassOf (TypeManager.delegate_type)) {
6901                                 Report.Error (66, Location, "`{0}': event must be of a delegate type", GetSignatureForError ());
6902                                 return false;
6903                         }
6904
6905                         EmitContext ec = Parent.EmitContext;
6906                         if (ec == null)
6907                                 throw new InternalErrorException ("Event.Define called too early?");
6908                         bool old_unsafe = ec.InUnsafe;
6909                         ec.InUnsafe = InUnsafe;
6910
6911                         Parameter [] parms = new Parameter [1];
6912                         parms [0] = new Parameter (Type, "value", Parameter.Modifier.NONE, null, Location);
6913                         Parameters parameters = new Parameters (parms, null);
6914                         Type [] types = parameters.GetParameterInfo (ec);
6915                         InternalParameters ip = new InternalParameters (types, parameters);
6916
6917                         ec.InUnsafe = old_unsafe;
6918
6919                         if (!CheckBase ())
6920                                 return false;
6921
6922                         //
6923                         // Now define the accessors
6924                         //
6925
6926                         AddBuilder = Add.Define (Parent, ip);
6927                         if (AddBuilder == null)
6928                                 return false;
6929
6930                         RemoveBuilder = Remove.Define (Parent, ip);
6931                         if (RemoveBuilder == null)
6932                                 return false;
6933
6934                         EventBuilder = new MyEventBuilder (this, Parent.TypeBuilder, Name, e_attr, MemberType);
6935                         
6936                         if (Add.Block == null && Remove.Block == null && !IsInterface) {
6937                                 FieldBuilder = Parent.TypeBuilder.DefineField (
6938                                         Name, MemberType,
6939                                         FieldAttributes.Private | ((ModFlags & Modifiers.STATIC) != 0 ? FieldAttributes.Static : 0));
6940                                 TypeManager.RegisterPrivateFieldOfEvent (
6941                                         (EventInfo) EventBuilder, FieldBuilder);
6942                                 TypeManager.RegisterFieldBase (FieldBuilder, this);
6943                         }
6944                         
6945                         EventBuilder.SetAddOnMethod (AddBuilder);
6946                         EventBuilder.SetRemoveOnMethod (RemoveBuilder);
6947
6948                         TypeManager.RegisterEvent (EventBuilder, AddBuilder, RemoveBuilder);
6949                         return true;
6950                 }
6951
6952                 protected override bool CheckBase ()
6953                 {
6954                         if (!base.CheckBase ())
6955                                 return false;
6956  
6957                         if (conflict_symbol != null && (ModFlags & Modifiers.NEW) == 0) {
6958                                 if (!(conflict_symbol is EventInfo)) {
6959                                         Report.SymbolRelatedToPreviousError (conflict_symbol);
6960                                         Report.Error (72, Location, "Event `{0}' can override only event", GetSignatureForError ());
6961                                         return false;
6962                                 }
6963                         }
6964  
6965                         return true;
6966                 }
6967
6968                 public override void Emit ()
6969                 {
6970                         if (OptAttributes != null) {
6971                                 EmitContext ec = new EmitContext (
6972                                         Parent, Location, null, MemberType, ModFlags);
6973                                 OptAttributes.Emit (ec, this);
6974                         }
6975
6976                         Add.Emit (Parent);
6977                         Remove.Emit (Parent);
6978
6979                         base.Emit ();
6980                 }
6981
6982                 public override string GetSignatureForError ()
6983                 {
6984                         return base.GetSignatureForError ();
6985                 }
6986
6987                 //
6988                 //   Represents header string for documentation comment.
6989                 //
6990                 public override string DocCommentHeader {
6991                         get { return "E:"; }
6992                 }
6993         }
6994
6995
6996         public class Indexer : PropertyBase {
6997
6998                 class GetIndexerMethod: GetMethod
6999                 {
7000                         public GetIndexerMethod (MethodCore method):
7001                                 base (method)
7002                         {
7003                         }
7004
7005                         public GetIndexerMethod (MethodCore method, Accessor accessor):
7006                                 base (method, accessor)
7007                         {
7008                         }
7009
7010                         public override Type[] ParameterTypes {
7011                                 get {
7012                                         return method.ParameterTypes;
7013                                 }
7014                         }
7015                 }
7016
7017                 class SetIndexerMethod: SetMethod
7018                 {
7019                         readonly Parameters parameters;
7020
7021                         public SetIndexerMethod (MethodCore method):
7022                                 base (method)
7023                         {
7024                         }
7025
7026                         public SetIndexerMethod (MethodCore method, Parameters parameters, Accessor accessor):
7027                                 base (method, accessor)
7028                         {
7029                                 this.parameters = parameters;
7030                         }
7031
7032                         public override Type[] ParameterTypes {
7033                                 get {
7034                                         int top = method.ParameterTypes.Length;
7035                                         Type [] set_pars = new Type [top + 1];
7036                                         method.ParameterTypes.CopyTo (set_pars, 0);
7037                                         set_pars [top] = method.MemberType;
7038                                         return set_pars;
7039                                 }
7040                         }
7041
7042                         protected override InternalParameters GetParameterInfo (EmitContext ec)
7043                         {
7044                                 Parameter [] fixed_parms = parameters.FixedParameters;
7045
7046                                 if (fixed_parms == null){
7047                                         throw new Exception ("We currently do not support only array arguments in an indexer at: " + method.Location);
7048                                         // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
7049                                         // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
7050                                         //
7051                                         // Here is the problem: the `value' parameter has
7052                                         // to come *after* the array parameter in the declaration
7053                                         // like this:
7054                                         // X (object [] x, Type value)
7055                                         // .param [0]
7056                                         //
7057                                         // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
7058                                         // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
7059                                         
7060                                 }
7061                                 
7062                                 Parameter [] tmp = new Parameter [fixed_parms.Length + 1];
7063
7064                                 fixed_parms.CopyTo (tmp, 0);
7065                                 tmp [fixed_parms.Length] = new Parameter (
7066                                         method.Type, "value", Parameter.Modifier.NONE, null, method.Location);
7067
7068                                 Parameters set_formal_params = new Parameters (tmp, null);
7069                                 Type [] types = set_formal_params.GetParameterInfo (ec);
7070                                 
7071                                 return new InternalParameters (types, set_formal_params);
7072                         }
7073                 }
7074
7075
7076                 const int AllowedModifiers =
7077                         Modifiers.NEW |
7078                         Modifiers.PUBLIC |
7079                         Modifiers.PROTECTED |
7080                         Modifiers.INTERNAL |
7081                         Modifiers.PRIVATE |
7082                         Modifiers.VIRTUAL |
7083                         Modifiers.SEALED |
7084                         Modifiers.OVERRIDE |
7085                         Modifiers.UNSAFE |
7086                         Modifiers.EXTERN |
7087                         Modifiers.ABSTRACT;
7088
7089                 const int AllowedInterfaceModifiers =
7090                         Modifiers.NEW;
7091
7092
7093                 public Indexer (TypeContainer ds, Expression type, MemberName name, int mod,
7094                                 bool is_iface, Parameters parameters, Attributes attrs,
7095                                 Accessor get_block, Accessor set_block)
7096                         : base (ds, type, mod,
7097                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
7098                                 is_iface, name, parameters, attrs)
7099                 {
7100                         if (get_block == null)
7101                                 Get = new GetIndexerMethod (this);
7102                         else
7103                                 Get = new GetIndexerMethod (this, get_block);
7104
7105                         if (set_block == null)
7106                                 Set = new SetIndexerMethod (this);
7107                         else
7108                                 Set = new SetIndexerMethod (this, parameters, set_block);
7109                 }
7110                        
7111                 public override bool Define ()
7112                 {
7113                         PropertyAttributes prop_attr =
7114                                 PropertyAttributes.RTSpecialName |
7115                                 PropertyAttributes.SpecialName;
7116                         
7117                         if (!base.Define ())
7118                                 return false;
7119
7120                         if (MemberType == TypeManager.void_type) {
7121                                 Report.Error (620, Location, "Indexers cannot have void type");
7122                                 return false;
7123                         }
7124
7125                         if (OptAttributes != null) {
7126                                 Attribute indexer_attr = OptAttributes.Search (TypeManager.indexer_name_type, ec);
7127                                 if (indexer_attr != null) {
7128                                         // Remove the attribute from the list because it is not emitted
7129                                         OptAttributes.Attrs.Remove (indexer_attr);
7130
7131                                         ShortName = indexer_attr.GetIndexerAttributeValue (ec);
7132
7133                                         if (IsExplicitImpl) {
7134                                                 Report.Error (415, indexer_attr.Location,
7135                                                               "The `IndexerName' attribute is valid only on an " +
7136                                                               "indexer that is not an explicit interface member declaration");
7137                                                 return false;
7138                                         }
7139
7140                                         if ((ModFlags & Modifiers.OVERRIDE) != 0) {
7141                                                 Report.Error (609, indexer_attr.Location,
7142                                                               "Cannot set the `IndexerName' attribute on an indexer marked override");
7143                                                 return false;
7144                                         }
7145
7146                                         if (!Tokenizer.IsValidIdentifier (ShortName)) {
7147                                                 Report.Error (633, indexer_attr.Location,
7148                                                               "The argument to the `IndexerName' attribute must be a valid identifier");
7149                                                 return false;
7150                                         }
7151                                 }
7152                         }
7153
7154                         if (InterfaceType != null) {
7155                                 string base_IndexerName = TypeManager.IndexerPropertyName (InterfaceType);
7156                                 if (base_IndexerName != Name)
7157                                         ShortName = base_IndexerName;
7158                         }
7159
7160                         if (!Parent.AddToMemberContainer (this) ||
7161                                 !Parent.AddToMemberContainer (Get) || !Parent.AddToMemberContainer (Set))
7162                                 return false;
7163
7164                         if (!CheckBase ())
7165                                 return false;
7166
7167                         flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
7168                         if (!Get.IsDummy){
7169                                 GetBuilder = Get.Define (Parent);
7170                                 if (GetBuilder == null)
7171                                         return false;
7172                         }
7173                         
7174                         if (!Set.IsDummy){
7175                                 SetBuilder = Set.Define (Parent);
7176                                 if (SetBuilder == null)
7177                                         return false;
7178                         }
7179
7180                         //
7181                         // Now name the parameters
7182                         //
7183                         Parameter [] p = Parameters.FixedParameters;
7184                         if (p != null) {
7185                                 if ((p [0].ModFlags & Parameter.Modifier.ISBYREF) != 0) {
7186                                         Report.Error (631, Location, "ref and out are not valid in this context");
7187                                         return false;
7188                                 }
7189
7190                                 int i;
7191                                 
7192                                 for (i = 0; i < p.Length; ++i) {
7193                                         if (!Get.IsDummy)
7194                                                 GetBuilder.DefineParameter (
7195                                                         i + 1, p [i].Attributes, p [i].Name);
7196
7197                                         if (!Set.IsDummy)
7198                                                 SetBuilder.DefineParameter (
7199                                                         i + 1, p [i].Attributes, p [i].Name);
7200                                 }
7201
7202                                 if (!Set.IsDummy)
7203                                         SetBuilder.DefineParameter (
7204                                                 i + 1, ParameterAttributes.None, "value");
7205                                         
7206                                 if (i != ParameterTypes.Length) {
7207                                         Parameter array_param = Parameters.ArrayParameter;
7208
7209                                         SetBuilder.DefineParameter (
7210                                                 i + 1, array_param.Attributes, array_param.Name);
7211                                 }
7212                         }
7213
7214                         PropertyBuilder = Parent.TypeBuilder.DefineProperty (
7215                                 Name, prop_attr, MemberType, ParameterTypes);
7216                         
7217                         if (!Get.IsDummy)
7218                                 PropertyBuilder.SetGetMethod (GetBuilder);
7219
7220                         if (!Set.IsDummy)
7221                                 PropertyBuilder.SetSetMethod (SetBuilder);
7222                                 
7223                         TypeManager.RegisterIndexer (PropertyBuilder, GetBuilder, SetBuilder, ParameterTypes);
7224
7225                         return true;
7226                 }
7227
7228                 public override string GetSignatureForError ()
7229                 {
7230                         StringBuilder sb = new StringBuilder (Parent.GetSignatureForError ());
7231                         if (MemberName.Left != null) {
7232                                 sb.Append ('.');
7233                                 sb.Append (MemberName.Left);
7234                         }
7235
7236                         sb.Append (".this");
7237                         sb.Append (Parameters.GetSignatureForError ().Replace ('(', '[').Replace (')', ']'));
7238                         return sb.ToString ();
7239                 }
7240
7241                 public override bool MarkForDuplicationCheck ()
7242                 {
7243                         caching_flags |= Flags.TestMethodDuplication;
7244                         return true;
7245                 }
7246
7247         }
7248
7249         public class Operator : MethodCore, IIteratorContainer {
7250
7251                 const int AllowedModifiers =
7252                         Modifiers.PUBLIC |
7253                         Modifiers.UNSAFE |
7254                         Modifiers.EXTERN |
7255                         Modifiers.STATIC;
7256
7257                 public enum OpType : byte {
7258
7259                         // Unary operators
7260                         LogicalNot,
7261                         OnesComplement,
7262                         Increment,
7263                         Decrement,
7264                         True,
7265                         False,
7266
7267                         // Unary and Binary operators
7268                         Addition,
7269                         Subtraction,
7270
7271                         UnaryPlus,
7272                         UnaryNegation,
7273                         
7274                         // Binary operators
7275                         Multiply,
7276                         Division,
7277                         Modulus,
7278                         BitwiseAnd,
7279                         BitwiseOr,
7280                         ExclusiveOr,
7281                         LeftShift,
7282                         RightShift,
7283                         Equality,
7284                         Inequality,
7285                         GreaterThan,
7286                         LessThan,
7287                         GreaterThanOrEqual,
7288                         LessThanOrEqual,
7289
7290                         // Implicit and Explicit
7291                         Implicit,
7292                         Explicit,
7293
7294                         // Just because of enum
7295                         TOP
7296                 };
7297
7298                 public readonly OpType OperatorType;
7299                 public MethodBuilder   OperatorMethodBuilder;
7300                 
7301                 public Method OperatorMethod;
7302
7303                 static string[] attribute_targets = new string [] { "method", "return" };
7304
7305                 public Operator (TypeContainer parent, OpType type, Expression ret_type,
7306                                  int mod_flags, Parameters parameters,
7307                                  ToplevelBlock block, Attributes attrs, Location loc)
7308                         : base (parent, ret_type, mod_flags, AllowedModifiers, false,
7309                                 new MemberName ("op_" + type, loc), attrs, parameters)
7310                 {
7311                         OperatorType = type;
7312                         Block = block;
7313                 }
7314
7315                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb) 
7316                 {
7317                         OperatorMethod.ApplyAttributeBuilder (a, cb);
7318                 }
7319
7320                 public override AttributeTargets AttributeTargets {
7321                         get {
7322                                 return AttributeTargets.Method; 
7323                         }
7324                 }
7325                 
7326                 protected override bool CheckForDuplications()
7327                 {
7328                         ArrayList ar = Parent.Operators;
7329                         if (ar != null) {
7330                                 int arLen = ar.Count;
7331                                         
7332                                 for (int i = 0; i < arLen; i++) {
7333                                         Operator o = (Operator) ar [i];
7334                                         if (IsDuplicateImplementation (o))
7335                                                 return false;
7336                                 }
7337                         }
7338
7339                         ar = Parent.Methods;
7340                         if (ar != null) {
7341                                 int arLen = ar.Count;
7342                                         
7343                                 for (int i = 0; i < arLen; i++) {
7344                                         Method m = (Method) ar [i];
7345                                         if (IsDuplicateImplementation (m))
7346                                                 return false;
7347                                 }
7348                         }
7349
7350                         return true;
7351                 }
7352
7353                 public override bool Define ()
7354                 {
7355                         const int RequiredModifiers = Modifiers.PUBLIC | Modifiers.STATIC;
7356                         if ((ModFlags & RequiredModifiers) != RequiredModifiers){
7357                                 Report.Error (558, Location, "User-defined operator `{0}' must be declared static and public", GetSignatureForError ());
7358                                 return false;
7359                         }
7360
7361                         if (!DoDefine ())
7362                                 return false;
7363
7364                         if (MemberType == TypeManager.void_type) {
7365                                 Report.Error (590, Location, "User-defined operators cannot return void");
7366                                 return false;
7367                         }
7368
7369                         OperatorMethod = new Method (
7370                                 Parent, Type, ModFlags, false, MemberName,
7371                                 Parameters, OptAttributes);
7372
7373                         OperatorMethod.Block = Block;
7374                         OperatorMethod.IsOperator = this;                       
7375                         OperatorMethod.flags |= MethodAttributes.SpecialName | MethodAttributes.HideBySig;
7376                         OperatorMethod.Define ();
7377
7378                         if (OperatorMethod.MethodBuilder == null)
7379                                 return false;
7380
7381                         OperatorMethodBuilder = OperatorMethod.MethodBuilder;
7382
7383                         parameter_types = OperatorMethod.ParameterTypes;
7384                         Type declaring_type = OperatorMethodBuilder.DeclaringType;
7385                         Type return_type = OperatorMethod.ReturnType;
7386                         Type first_arg_type = parameter_types [0];
7387
7388                         if (!CheckBase ())
7389                                 return false;
7390
7391                         // Rules for conversion operators
7392                         
7393                         if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
7394                                 if (first_arg_type == return_type && first_arg_type == declaring_type){
7395                                         Report.Error (555, Location,
7396                                                 "User-defined operator cannot take an object of the enclosing type and convert to an object of the enclosing type");
7397                                         return false;
7398                                 }
7399                                 
7400                                 if (first_arg_type != declaring_type && return_type != declaring_type){
7401                                         Report.Error (
7402                                                 556, Location, 
7403                                                 "User-defined conversion must convert to or from the " +
7404                                                 "enclosing type");
7405                                         return false;
7406                                 }
7407                                 
7408                                 if (first_arg_type == TypeManager.object_type ||
7409                                         return_type == TypeManager.object_type){
7410                                         Report.Error (
7411                                                 -8, Location,
7412                                                 "User-defined conversion cannot convert to or from " +
7413                                                 "object type");
7414                                         return false;
7415                                 }
7416
7417                                 if (first_arg_type.IsInterface || return_type.IsInterface){
7418                                         Report.Error (552, Location, "User-defined conversion `{0}' cannot convert to or from an interface type",
7419                                                 GetSignatureForError ());
7420                                         return false;
7421                                 }
7422                                 
7423                                 if (first_arg_type.IsSubclassOf (return_type)
7424                                         || return_type.IsSubclassOf (first_arg_type)){
7425                                         if (declaring_type.IsSubclassOf (return_type)) {
7426                                                 Report.Error (553, Location, "User-defined conversion `{0}' cannot convert to or from base class",
7427                                                         GetSignatureForError ());
7428                                                 return false;
7429                                         }
7430                                         Report.Error (554, Location, "User-defined conversion `{0}' cannot convert to or from derived class",
7431                                                 GetSignatureForError ());
7432                                         return false;
7433                                 }
7434                         } else if (OperatorType == OpType.LeftShift || OperatorType == OpType.RightShift) {
7435                                 if (first_arg_type != declaring_type || parameter_types [1] != TypeManager.int32_type) {
7436                                         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");
7437                                         return false;
7438                                 }
7439                         } else if (Parameters.FixedParameters.Length == 1) {
7440                                 // Checks for Unary operators
7441
7442                                 if (OperatorType == OpType.Increment || OperatorType == OpType.Decrement) {
7443                                         if (return_type != declaring_type && !return_type.IsSubclassOf (declaring_type)) {
7444                                                 Report.Error (448, Location,
7445                                                         "The return type for ++ or -- operator must be the containing type or derived from the containing type");
7446                                                 return false;
7447                                         }
7448                                         if (first_arg_type != declaring_type) {
7449                                                 Report.Error (
7450                                                         559, Location, "The parameter type for ++ or -- operator must be the containing type");
7451                                                 return false;
7452                                         }
7453                                 }
7454                                 
7455                                 if (first_arg_type != declaring_type){
7456                                         Report.Error (
7457                                                 562, Location,
7458                                                 "The parameter of a unary operator must be the " +
7459                                                 "containing type");
7460                                         return false;
7461                                 }
7462                                 
7463                                 if (OperatorType == OpType.True || OperatorType == OpType.False) {
7464                                         if (return_type != TypeManager.bool_type){
7465                                                 Report.Error (
7466                                                         215, Location,
7467                                                         "The return type of operator True or False " +
7468                                                         "must be bool");
7469                                                 return false;
7470                                         }
7471                                 }
7472                                 
7473                         } else {
7474                                 // Checks for Binary operators
7475                                 
7476                                 if (first_arg_type != declaring_type &&
7477                                     parameter_types [1] != declaring_type){
7478                                         Report.Error (
7479                                                 563, Location,
7480                                                 "One of the parameters of a binary operator must " +
7481                                                 "be the containing type");
7482                                         return false;
7483                                 }
7484                         }
7485
7486                         return true;
7487                 }
7488                 
7489                 public override void Emit ()
7490                 {
7491                         //
7492                         // abstract or extern methods have no bodies
7493                         //
7494                         if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
7495                                 return;
7496                         
7497                         OperatorMethod.Emit ();
7498                         Block = null;
7499                 }
7500
7501                 // Operator cannot be override
7502                 protected override MethodInfo FindOutBaseMethod (TypeContainer container, ref Type base_ret_type)
7503                 {
7504                         return null;
7505                 }
7506
7507                 public static string GetName (OpType ot)
7508                 {
7509                         switch (ot){
7510                         case OpType.LogicalNot:
7511                                 return "!";
7512                         case OpType.OnesComplement:
7513                                 return "~";
7514                         case OpType.Increment:
7515                                 return "++";
7516                         case OpType.Decrement:
7517                                 return "--";
7518                         case OpType.True:
7519                                 return "true";
7520                         case OpType.False:
7521                                 return "false";
7522                         case OpType.Addition:
7523                                 return "+";
7524                         case OpType.Subtraction:
7525                                 return "-";
7526                         case OpType.UnaryPlus:
7527                                 return "+";
7528                         case OpType.UnaryNegation:
7529                                 return "-";
7530                         case OpType.Multiply:
7531                                 return "*";
7532                         case OpType.Division:
7533                                 return "/";
7534                         case OpType.Modulus:
7535                                 return "%";
7536                         case OpType.BitwiseAnd:
7537                                 return "&";
7538                         case OpType.BitwiseOr:
7539                                 return "|";
7540                         case OpType.ExclusiveOr:
7541                                 return "^";
7542                         case OpType.LeftShift:
7543                                 return "<<";
7544                         case OpType.RightShift:
7545                                 return ">>";
7546                         case OpType.Equality:
7547                                 return "==";
7548                         case OpType.Inequality:
7549                                 return "!=";
7550                         case OpType.GreaterThan:
7551                                 return ">";
7552                         case OpType.LessThan:
7553                                 return "<";
7554                         case OpType.GreaterThanOrEqual:
7555                                 return ">=";
7556                         case OpType.LessThanOrEqual:
7557                                 return "<=";
7558                         case OpType.Implicit:
7559                                 return "implicit";
7560                         case OpType.Explicit:
7561                                 return "explicit";
7562                         default: return "";
7563                         }
7564                 }
7565
7566                 public static OpType GetOperatorType (string name)
7567                 {
7568                         if (name.StartsWith ("op_")){
7569                                 for (int i = 0; i < Unary.oper_names.Length; ++i) {
7570                                         if (Unary.oper_names [i] == name)
7571                                                 return (OpType)i;
7572                                 }
7573
7574                                 for (int i = 0; i < Binary.oper_names.Length; ++i) {
7575                                         if (Binary.oper_names [i] == name)
7576                                                 return (OpType)i;
7577                                 }
7578                         }
7579                         return OpType.TOP;
7580                 }
7581
7582                 public override string GetSignatureForError ()
7583                 {
7584                         StringBuilder sb = new StringBuilder ();
7585                         if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
7586                                 sb.AppendFormat ("{0}.{1} operator {2}", Parent.GetSignatureForError (), GetName (OperatorType), Type.Type == null ? Type.ToString () : TypeManager.CSharpName (Type.Type));
7587                         }
7588                         else {
7589                                 sb.AppendFormat ("{0}.operator {1}", Parent.GetSignatureForError (), GetName (OperatorType));
7590                         }
7591
7592                         sb.Append (Parameters.GetSignatureForError ());
7593                         return sb.ToString ();
7594                 }
7595
7596                 public override bool MarkForDuplicationCheck ()
7597                 {
7598                         caching_flags |= Flags.TestMethodDuplication;
7599                         return true;
7600                 }
7601
7602                 public override string[] ValidAttributeTargets {
7603                         get {
7604                                 return attribute_targets;
7605                         }
7606                 }
7607         }
7608
7609         //
7610         // This is used to compare method signatures
7611         //
7612         struct MethodSignature {
7613                 public string Name;
7614                 public Type RetType;
7615                 public Type [] Parameters;
7616                 
7617                 /// <summary>
7618                 ///    This delegate is used to extract methods which have the
7619                 ///    same signature as the argument
7620                 /// </summary>
7621                 public static MemberFilter method_signature_filter = new MemberFilter (MemberSignatureCompare);
7622                 
7623                 public MethodSignature (string name, Type ret_type, Type [] parameters)
7624                 {
7625                         Name = name;
7626                         RetType = ret_type;
7627
7628                         if (parameters == null)
7629                                 Parameters = TypeManager.NoTypes;
7630                         else
7631                                 Parameters = parameters;
7632                 }
7633
7634                 public override string ToString ()
7635                 {
7636                         string pars = "";
7637                         if (Parameters.Length != 0){
7638                                 System.Text.StringBuilder sb = new System.Text.StringBuilder ();
7639                                 for (int i = 0; i < Parameters.Length; i++){
7640                                         sb.Append (Parameters [i]);
7641                                         if (i+1 < Parameters.Length)
7642                                                 sb.Append (", ");
7643                                 }
7644                                 pars = sb.ToString ();
7645                         }
7646
7647                         return String.Format ("{0} {1} ({2})", RetType, Name, pars);
7648                 }
7649                 
7650                 public override int GetHashCode ()
7651                 {
7652                         return Name.GetHashCode ();
7653                 }
7654
7655                 public override bool Equals (Object o)
7656                 {
7657                         MethodSignature other = (MethodSignature) o;
7658
7659                         if (other.Name != Name)
7660                                 return false;
7661
7662                         if (other.RetType != RetType)
7663                                 return false;
7664                         
7665                         if (Parameters == null){
7666                                 if (other.Parameters == null)
7667                                         return true;
7668                                 return false;
7669                         }
7670
7671                         if (other.Parameters == null)
7672                                 return false;
7673                         
7674                         int c = Parameters.Length;
7675                         if (other.Parameters.Length != c)
7676                                 return false;
7677
7678                         for (int i = 0; i < c; i++)
7679                                 if (other.Parameters [i] != Parameters [i])
7680                                         return false;
7681
7682                         return true;
7683                 }
7684
7685                 static bool MemberSignatureCompare (MemberInfo m, object filter_criteria)
7686                 {
7687                         MethodSignature sig = (MethodSignature) filter_criteria;
7688
7689                         if (m.Name != sig.Name)
7690                                 return false;
7691
7692                         Type ReturnType;
7693                         MethodInfo mi = m as MethodInfo;
7694                         PropertyInfo pi = m as PropertyInfo;
7695
7696                         if (mi != null)
7697                                 ReturnType = mi.ReturnType;
7698                         else if (pi != null)
7699                                 ReturnType = pi.PropertyType;
7700                         else
7701                                 return false;
7702                         
7703                         //
7704                         // we use sig.RetType == null to mean `do not check the
7705                         // method return value.  
7706                         //
7707                         if (sig.RetType != null)
7708                                 if (ReturnType != sig.RetType)
7709                                         return false;
7710
7711                         Type [] args;
7712                         if (mi != null)
7713                                 args = TypeManager.GetArgumentTypes (mi);
7714                         else
7715                                 args = TypeManager.GetArgumentTypes (pi);
7716                         Type [] sigp = sig.Parameters;
7717
7718                         if (args.Length != sigp.Length)
7719                                 return false;
7720
7721                         for (int i = args.Length; i > 0; ){
7722                                 i--;
7723                                 if (args [i] != sigp [i])
7724                                         return false;
7725                         }
7726                         return true;
7727                 }
7728         }
7729 }