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