Ensure that partial classes are registered in their enclosing
[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 && base_type != 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                         EmitConstants ();
2080
2081                         if (default_static_constructor != null)
2082                                 default_static_constructor.Emit ();
2083                         
2084                         if (methods != null)
2085                                 foreach (Method m in methods)
2086                                         m.Emit ();
2087
2088                         if (operators != null)
2089                                 foreach (Operator o in operators)
2090                                         o.Emit ();
2091
2092                         if (properties != null)
2093                                 foreach (Property p in properties)
2094                                         p.Emit ();
2095
2096                         if (indexers != null){
2097                                 indexers.Emit ();
2098                         }
2099                         
2100                         if (fields != null)
2101                                 foreach (FieldMember f in fields)
2102                                         f.Emit ();
2103
2104                         if (events != null){
2105                                 foreach (Event e in Events)
2106                                         e.Emit ();
2107                         }
2108
2109                         if (delegates != null) {
2110                                 foreach (Delegate d in Delegates) {
2111                                         d.Emit ();
2112                                 }
2113                         }
2114
2115                         if (enums != null) {
2116                                 foreach (Enum e in enums) {
2117                                         e.Emit ();
2118                                 }
2119                         }
2120
2121                         if (parts != null) {
2122                                 foreach (ClassPart part in parts)
2123                                         part.EmitType ();
2124                         }
2125
2126                         if ((Pending != null) && !(this is ClassPart))
2127                                 if (Pending.VerifyPendingMethods ())
2128                                         return;
2129
2130                         if (iterators != null)
2131                                 foreach (Iterator iterator in iterators)
2132                                         iterator.EmitType ();
2133                         
2134 //                      if (types != null)
2135 //                              foreach (TypeContainer tc in types)
2136 //                                      tc.Emit ();
2137                 }
2138
2139                 public override void CloseType ()
2140                 {
2141                         if ((caching_flags & Flags.CloseTypeCreated) != 0)
2142                                 return;
2143
2144                         try {
2145                                 caching_flags |= Flags.CloseTypeCreated;
2146                                 TypeBuilder.CreateType ();
2147                         } catch (TypeLoadException){
2148                                 //
2149                                 // This is fine, the code still created the type
2150                                 //
2151 //                              Report.Warning (-20, "Exception while creating class: " + TypeBuilder.Name);
2152 //                              Console.WriteLine (e.Message);
2153                         } catch {
2154                                 Console.WriteLine ("In type: " + Name);
2155                                 throw;
2156                         }
2157                         
2158                         if (Enums != null)
2159                                 foreach (Enum en in Enums)
2160                                         en.CloseType ();
2161
2162                         if (Types != null){
2163                                 foreach (TypeContainer tc in Types)
2164                                         if (tc.Kind == Kind.Struct)
2165                                                 tc.CloseType ();
2166
2167                                 foreach (TypeContainer tc in Types)
2168                                         if (tc.Kind != Kind.Struct)
2169                                                 tc.CloseType ();
2170                         }
2171
2172                         if (Delegates != null)
2173                                 foreach (Delegate d in Delegates)
2174                                         d.CloseType ();
2175
2176                         if (Iterators != null)
2177                                 foreach (Iterator i in Iterators)
2178                                         i.CloseType ();
2179
2180                         types = null;
2181                         properties = null;
2182                         enums = null;
2183                         delegates = null;
2184                         fields = null;
2185                         initialized_fields = null;
2186                         initialized_static_fields = null;
2187                         constants = null;
2188                         interfaces = null;
2189                         methods = null;
2190                         events = null;
2191                         indexers = null;
2192                         operators = null;
2193                         iterators = null;
2194                         ec = null;
2195                         default_constructor = null;
2196                         default_static_constructor = null;
2197                         type_bases = null;
2198                         OptAttributes = null;
2199                         ifaces = null;
2200                         base_cache = null;
2201                         member_cache = null;
2202                 }
2203
2204                 // TODO: make it obsolete and use GetSignatureForError
2205                 public string MakeName (string n)
2206                 {
2207                         return "`" + Name + "." + n + "'";
2208                 }
2209
2210                 //
2211                 // Performs the validation on a Method's modifiers (properties have
2212                 // the same properties).
2213                 //
2214                 public bool MethodModifiersValid (MemberCore mc)
2215                 {
2216                         const int vao = (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE);
2217                         const int va = (Modifiers.VIRTUAL | Modifiers.ABSTRACT);
2218                         const int nv = (Modifiers.NEW | Modifiers.VIRTUAL);
2219                         bool ok = true;
2220                         int flags = mc.ModFlags;
2221                         
2222                         //
2223                         // At most one of static, virtual or override
2224                         //
2225                         if ((flags & Modifiers.STATIC) != 0){
2226                                 if ((flags & vao) != 0){
2227                                         Report.Error (112, mc.Location, "static method '{0}' can not be marked as virtual, abstract or override",
2228                                                 GetSignatureForError ());
2229                                         ok = false;
2230                                 }
2231                         }
2232
2233                         if (Kind == Kind.Struct){
2234                                 if ((flags & va) != 0){
2235                                         Modifiers.Error_InvalidModifier (mc.Location, "virtual or abstract");
2236                                         ok = false;
2237                                 }
2238                         }
2239
2240                         if ((flags & Modifiers.OVERRIDE) != 0 && (flags & nv) != 0){
2241                                 Report.Error (113, mc.Location, "'{0}' marked as override cannot be marked as new or virtual", mc.GetSignatureForError ());
2242                                 ok = false;
2243                         }
2244
2245                         //
2246                         // If the declaration includes the abstract modifier, then the
2247                         // declaration does not include static, virtual or extern
2248                         //
2249                         if ((flags & Modifiers.ABSTRACT) != 0){
2250                                 if ((flags & Modifiers.EXTERN) != 0){
2251                                         Report.Error (
2252                                                 180, mc.Location, "'{0}' can not be both abstract and extern", mc.GetSignatureForError ());
2253                                         ok = false;
2254                                 }
2255
2256                                 if ((flags & Modifiers.SEALED) != 0) {
2257                                         Report.Error (502, mc.Location, "'{0}' cannot be both abstract and sealed", mc.GetSignatureForError ());
2258                                         ok = false;
2259                                 }
2260
2261                                 if ((flags & Modifiers.VIRTUAL) != 0){
2262                                         Report.Error (503, mc.Location, "'{0}' can not be both abstract and virtual", mc.GetSignatureForError ());
2263                                         ok = false;
2264                                 }
2265
2266                                 if ((ModFlags & Modifiers.ABSTRACT) == 0){
2267                                         Report.Error (513, mc.Location, "'{0}' is abstract but its container class is not", mc.GetSignatureForError ());
2268                                         ok = false;
2269                                 }
2270                         }
2271
2272                         if ((flags & Modifiers.PRIVATE) != 0){
2273                                 if ((flags & vao) != 0){
2274                                         Report.Error (621, mc.Location, "'{0}' virtual or abstract members can not be private", mc.GetSignatureForError ());
2275                                         ok = false;
2276                                 }
2277                         }
2278
2279                         if ((flags & Modifiers.SEALED) != 0){
2280                                 if ((flags & Modifiers.OVERRIDE) == 0){
2281                                         Report.Error (238, mc.Location, "'{0}' cannot be sealed because it is not an override", mc.GetSignatureForError ());
2282                                         ok = false;
2283                                 }
2284                         }
2285
2286                         return ok;
2287                 }
2288
2289                 public bool UserDefinedStaticConstructor {
2290                         get {
2291                                 return default_static_constructor != null;
2292                         }
2293                 }
2294
2295                 public Constructor DefaultStaticConstructor {
2296                         get { return default_static_constructor; }
2297                 }
2298
2299                 protected override bool VerifyClsCompliance (DeclSpace ds)
2300                 {
2301                         if (!base.VerifyClsCompliance (ds))
2302                                 return false;
2303
2304                         VerifyClsName ();
2305
2306                         Type base_type = TypeBuilder.BaseType;
2307                         if (base_type != null && !AttributeTester.IsClsCompliant (base_type)) {
2308                                 Report.Error (3009, Location, "'{0}': base type '{1}' is not CLS-compliant", GetSignatureForError (), TypeManager.CSharpName (base_type));
2309                         }
2310
2311                         if (!Parent.IsClsCompliaceRequired (ds)) {
2312                                 Report.Error (3018, Location, "'{0}' cannot be marked as CLS-Compliant because it is a member of non CLS-Compliant type '{1}'", 
2313                                         GetSignatureForError (), Parent.GetSignatureForError ());
2314                         }
2315                         return true;
2316                 }
2317
2318
2319                 /// <summary>
2320                 /// Checks whether container name is CLS Compliant
2321                 /// </summary>
2322                 void VerifyClsName ()
2323                 {
2324                         Hashtable base_members = base_cache == null ? 
2325                                 new Hashtable () :
2326                                 base_cache.GetPublicMembers ();
2327                         Hashtable this_members = new Hashtable ();
2328
2329                         foreach (DictionaryEntry entry in defined_names) {
2330                                 MemberCore mc = (MemberCore)entry.Value;
2331                                 if (!mc.IsClsCompliaceRequired (this))
2332                                         continue;
2333
2334                                 string name = (string)entry.Key;
2335                                 string basename = name.Substring (name.LastIndexOf ('.') + 1);
2336
2337                                 string lcase = basename.ToLower (System.Globalization.CultureInfo.InvariantCulture);
2338                                 object found = base_members [lcase];
2339                                 if (found == null) {
2340                                         found = this_members [lcase];
2341                                         if (found == null) {
2342                                                 this_members.Add (lcase, mc);
2343                                                 continue;
2344                                         }
2345                                 }
2346
2347                                 if ((mc.ModFlags & Modifiers.OVERRIDE) != 0)
2348                                         continue;                                       
2349
2350                                 if (found is MemberInfo) {
2351                                         if (basename == ((MemberInfo)found).Name)
2352                                                 continue;
2353                                         Report.SymbolRelatedToPreviousError ((MemberInfo)found);
2354                                 } else {
2355                                         Report.SymbolRelatedToPreviousError ((MemberCore) found);
2356                                 }
2357                                 Report.Error (3005, mc.Location, "Identifier '{0}' differing only in case is not CLS-compliant", mc.GetSignatureForError ());
2358                         }
2359                 }
2360
2361
2362                 /// <summary>
2363                 ///   Performs checks for an explicit interface implementation.  First it
2364                 ///   checks whether the `interface_type' is a base inteface implementation.
2365                 ///   Then it checks whether `name' exists in the interface type.
2366                 /// </summary>
2367                 public virtual bool VerifyImplements (Type interface_type, string full,
2368                                                       string name, Location loc)
2369                 {
2370                         bool found = false;
2371
2372                         if (ifaces != null){
2373                                 foreach (Type t in ifaces){
2374                                         if (t == interface_type){
2375                                                 found = true;
2376                                                 break;
2377                                         }
2378                                 }
2379                         }
2380                         
2381                         if (!found){
2382                                 Report.Error (540, loc, "`{0}': containing class does not implement interface `{1}'",
2383                                               full, interface_type.FullName);
2384                                 return false;
2385                         }
2386
2387                         return true;
2388                 }
2389
2390                 protected override void VerifyObsoleteAttribute()
2391                 {
2392                         CheckUsageOfObsoleteAttribute (ptype);
2393
2394                         if (ifaces == null)
2395                                 return;
2396
2397                         foreach (Type iface in ifaces) {
2398                                 CheckUsageOfObsoleteAttribute (iface);
2399                         }
2400                 }
2401
2402
2403                 //
2404                 // IMemberContainer
2405                 //
2406
2407                 string IMemberContainer.Name {
2408                         get {
2409                                 return Name;
2410                         }
2411                 }
2412
2413                 Type IMemberContainer.Type {
2414                         get {
2415                                 return TypeBuilder;
2416                         }
2417                 }
2418
2419                 MemberCache IMemberContainer.MemberCache {
2420                         get {
2421                                 return member_cache;
2422                         }
2423                 }
2424
2425                 bool IMemberContainer.IsInterface {
2426                         get {
2427                                 return Kind == Kind.Interface;
2428                         }
2429                 }
2430
2431                 MemberList IMemberContainer.GetMembers (MemberTypes mt, BindingFlags bf)
2432                 {
2433                         return FindMembers (mt, bf | BindingFlags.DeclaredOnly, null, null);
2434                 }
2435
2436                 //
2437                 // Generates xml doc comments (if any), and if required,
2438                 // handle warning report.
2439                 //
2440                 internal override void GenerateDocComment (DeclSpace ds)
2441                 {
2442                         DocUtil.GenerateTypeDocComment (this, ds);
2443                 }
2444
2445                 public override string DocCommentHeader {
2446                         get { return "T:"; }
2447                 }
2448
2449                 public virtual MemberCache BaseCache {
2450                         get {
2451                                 if (base_cache != null)
2452                                         return base_cache;
2453                                 if (TypeBuilder.BaseType != null)
2454                                         base_cache = TypeManager.LookupMemberCache (TypeBuilder.BaseType);
2455                                 if (TypeBuilder.IsInterface)
2456                                         base_cache = TypeManager.LookupBaseInterfacesCache (TypeBuilder);
2457                                 return base_cache;
2458                         }
2459                 }
2460         }
2461
2462         public class PartialContainer : TypeContainer {
2463
2464                 public readonly Namespace Namespace;
2465                 public readonly int OriginalModFlags;
2466                 public readonly int AllowedModifiers;
2467                 public readonly TypeAttributes DefaultTypeAttributes;
2468
2469                 static PartialContainer Create (NamespaceEntry ns, TypeContainer parent,
2470                                                 MemberName member_name, int mod_flags, Kind kind,
2471                                                 Location loc)
2472                 {
2473                         PartialContainer pc;
2474                         DeclSpace ds = RootContext.Tree.GetDecl (member_name);
2475                         if (ds != null) {
2476                                 pc = ds as PartialContainer;
2477
2478                                 if (pc == null) {
2479                                         Report.Error (
2480                                                 260, ds.Location, "Missing partial modifier " +
2481                                                 "on declaration of type `{0}'; another " +
2482                                                 "partial implementation of this type exists",
2483                                                 member_name.GetPartialName());
2484
2485                                         Report.LocationOfPreviousError (loc);
2486                                         return null;
2487                                 }
2488
2489                                 if (pc.Kind != kind) {
2490                                         Report.Error (
2491                                                 261, loc, "Partial declarations of `{0}' " +
2492                                                 "must be all classes, all structs or " +
2493                                                 "all interfaces", member_name.GetPartialName ());
2494                                         return null;
2495                                 }
2496
2497                                 if (pc.OriginalModFlags != mod_flags) {
2498                                         Report.Error (
2499                                                 262, loc, "Partial declarations of `{0}' " +
2500                                                 "have conflicting accessibility modifiers",
2501                                                 member_name.GetPartialName ());
2502                                         return null;
2503                                 }
2504
2505                                 return pc;
2506                         }
2507
2508                         if (parent is ClassPart)
2509                                 parent = ((ClassPart) parent).PartialContainer;
2510
2511                         pc = new PartialContainer (ns.NS, parent, member_name, mod_flags, kind, loc);
2512                         RootContext.Tree.RecordDecl (ns.NS, member_name, pc);
2513
2514                         if (kind == Kind.Interface)
2515                                 parent.AddInterface (pc);
2516                         else if (kind == Kind.Class || kind == Kind.Struct)
2517                                 parent.AddClassOrStruct (pc);
2518                         else
2519                                 throw new InvalidOperationException ();
2520
2521                         return pc;
2522                 }
2523
2524                 public static ClassPart CreatePart (NamespaceEntry ns, TypeContainer parent,
2525                                                     MemberName name, int mod, Attributes attrs,
2526                                                     Kind kind, Location loc)
2527                 {
2528                         PartialContainer pc = Create (ns, parent, name, mod, kind, loc);
2529                         if (pc == null) {
2530                                 // An error occured; create a dummy container, but don't
2531                                 // register it.
2532                                 pc = new PartialContainer (ns.NS, parent, name, mod, kind, loc);
2533                         }
2534
2535                         ClassPart part = new ClassPart (ns, pc, parent, mod, attrs, kind, loc);
2536                         pc.AddPart (part);
2537                         return part;
2538                 }
2539
2540                 protected PartialContainer (Namespace ns, TypeContainer parent,
2541                                             MemberName name, int mod, Kind kind, Location l)
2542                         : base (null, parent, name, null, kind, l)
2543                 {
2544                         this.Namespace = ns;
2545
2546                         switch (kind) {
2547                         case Kind.Class:
2548                                 AllowedModifiers = Class.AllowedModifiers;
2549                                 DefaultTypeAttributes = Class.DefaultTypeAttributes;
2550                                 break;
2551
2552                         case Kind.Struct:
2553                                 AllowedModifiers = Struct.AllowedModifiers;
2554                                 DefaultTypeAttributes = Struct.DefaultTypeAttributes;
2555                                 break;
2556
2557                         case Kind.Interface:
2558                                 AllowedModifiers = Interface.AllowedModifiers;
2559                                 DefaultTypeAttributes = Interface.DefaultTypeAttributes;
2560                                 break;
2561
2562                         default:
2563                                 throw new InvalidOperationException ();
2564                         }
2565
2566                         int accmods;
2567                         if (parent.Parent == null)
2568                                 accmods = Modifiers.INTERNAL;
2569                         else
2570                                 accmods = Modifiers.PRIVATE;
2571
2572                         this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
2573                         this.OriginalModFlags = mod;
2574                 }
2575
2576                 public override PendingImplementation GetPendingImplementations ()
2577                 {
2578                         return PendingImplementation.GetPendingImplementations (this);
2579                 }
2580
2581                 protected override TypeAttributes TypeAttr {
2582                         get {
2583                                 return base.TypeAttr | DefaultTypeAttributes;
2584                         }
2585                 }
2586         }
2587
2588         public class ClassPart : TypeContainer, IMemberContainer {
2589                 public readonly PartialContainer PartialContainer;
2590                 public readonly bool IsPartial;
2591
2592                 public ClassPart (NamespaceEntry ns, PartialContainer pc, TypeContainer parent,
2593                                   int mod, Attributes attrs, Kind kind, Location l)
2594                         : base (ns, parent, pc.MemberName, attrs, kind, l)
2595                 {
2596                         this.PartialContainer = pc;
2597                         this.IsPartial = true;
2598
2599                         int accmods;
2600                         if (parent == null || parent == RootContext.Tree.Types)
2601                                 accmods = Modifiers.INTERNAL;
2602                         else
2603                                 accmods = Modifiers.PRIVATE;
2604
2605                         this.ModFlags = Modifiers.Check (pc.AllowedModifiers, mod, accmods, l);
2606                 }
2607
2608                 public override PendingImplementation GetPendingImplementations ()
2609                 {
2610                         return PartialContainer.Pending;
2611                 }
2612
2613                 public override bool VerifyImplements (Type interface_type, string full,
2614                                                        string name, Location loc)
2615                 {
2616                         return PartialContainer.VerifyImplements (
2617                                 interface_type, full, name, loc);
2618                 }
2619
2620
2621                 public override void RegisterFieldForInitialization (FieldMember field)
2622                 {
2623                         PartialContainer.RegisterFieldForInitialization (field);
2624                 }
2625
2626                 public override bool EmitFieldInitializers (EmitContext ec)
2627                 {
2628                         return PartialContainer.EmitFieldInitializers (ec);
2629                 }
2630
2631                 public override Type FindNestedType (string name)
2632                 {
2633                         return PartialContainer.FindNestedType (name);
2634                 }
2635
2636                 public override MemberCache BaseCache {
2637                         get {
2638                                 return PartialContainer.BaseCache;
2639                         }
2640                 }
2641
2642                 public override TypeBuilder DefineType ()
2643                 {
2644                         throw new InternalErrorException ("Should not get here");
2645                 }
2646
2647         }
2648
2649         public abstract class ClassOrStruct : TypeContainer {
2650                 bool has_explicit_layout = false;
2651                 ListDictionary declarative_security;
2652
2653                 public ClassOrStruct (NamespaceEntry ns, TypeContainer parent,
2654                                       MemberName name, Attributes attrs, Kind kind,
2655                                       Location l)
2656                         : base (ns, parent, name, attrs, kind, l)
2657                 {
2658                 }
2659
2660                 public override PendingImplementation GetPendingImplementations ()
2661                 {
2662                         return PendingImplementation.GetPendingImplementations (this);
2663                 }
2664
2665                 public override bool HasExplicitLayout {
2666                         get {
2667                                 return has_explicit_layout;
2668                         }
2669                 }
2670
2671                 public override void VerifyMembers ()
2672                 {
2673                         base.VerifyMembers ();
2674
2675                         if ((events != null) && (RootContext.WarningLevel >= 3)) {
2676                                 foreach (Event e in events){
2677                                         if (e.status == 0)
2678                                                 Report.Warning (67, e.Location, "The event '{0}' is never used", e.GetSignatureForError ());
2679                                 }
2680                         }
2681                 }
2682
2683                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
2684                 {
2685                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
2686                                 if (declarative_security == null)
2687                                         declarative_security = new ListDictionary ();
2688
2689                                 a.ExtractSecurityPermissionSet (declarative_security);
2690                                 return;
2691                         }
2692
2693                         if (a.Type == TypeManager.struct_layout_attribute_type && a.GetLayoutKindValue () == LayoutKind.Explicit)
2694                                 has_explicit_layout = true;
2695
2696                         base.ApplyAttributeBuilder (a, cb);
2697                 }
2698
2699                 public override void Emit()
2700                 {
2701                         base.Emit ();
2702
2703                         if (declarative_security != null) {
2704                                 foreach (DictionaryEntry de in declarative_security) {
2705                                         TypeBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
2706                                 }
2707                         }
2708                 }
2709         }
2710
2711         /// <summary>
2712         /// Class handles static classes declaration
2713         /// </summary>
2714         public sealed class StaticClass: Class {
2715                 public StaticClass (NamespaceEntry ns, TypeContainer parent, MemberName name, int mod,
2716                         Attributes attrs, Location l)
2717                         : base (ns, parent, name, mod, attrs, l)
2718                 {
2719                         if (RootContext.Version == LanguageVersion.ISO_1) {
2720                                 Report.FeatureIsNotStandardized (l, "static classes");
2721                         }
2722                 }
2723
2724                 protected override int AllowedModifiersProp {
2725                         get {
2726                                 return Modifiers.NEW | Modifiers.PUBLIC | Modifiers.PROTECTED | Modifiers.INTERNAL | Modifiers.PRIVATE |
2727                                         Modifiers.STATIC | Modifiers.UNSAFE;
2728                         }
2729                 }
2730
2731                 protected override void DefineContainerMembers (MemberCoreArrayList list)
2732                 {
2733                         if (list == null)
2734                                 return;
2735
2736                         foreach (MemberCore m in list) {
2737                                 if (m is Operator) {
2738                                         Report.Error (715, m.Location, "'{0}': static classes cannot contain user-defined operators", m.GetSignatureForError (this));
2739                                         continue;
2740                                 }
2741
2742                                 if ((m.ModFlags & Modifiers.PROTECTED) != 0)
2743                                         Report.Warning (628, 4, m.Location, "'{0}': new protected member declared in static class", m.GetSignatureForError (this));
2744
2745                                 if (m is Indexer) {
2746                                         Report.Error (720, m.Location, "'{0}': cannot declare indexers in a static class", m.GetSignatureForError (this));
2747                                         continue;
2748                                 }
2749
2750                                 if ((m.ModFlags & Modifiers.STATIC) != 0 || m is Enum || m is Delegate)
2751                                         continue;
2752
2753                                 if (m is Constructor) {
2754                                         Report.Error (710, m.Location, "'{0}': Static classes cannot have instance constructors", GetSignatureForError ());
2755                                         continue;
2756                                 }
2757
2758                                 if (m is Destructor) {
2759                                         Report.Error (711, m.Location, "'{0}': Static class cannot contain destructor", GetSignatureForError ());
2760                                         continue;
2761                                 }
2762
2763                                 Report.Error (708, m.Location, "'{0}': cannot declare instance members in a static class", m.GetSignatureForError (this));
2764                         }
2765
2766                         base.DefineContainerMembers (list);
2767                 }
2768
2769                 public override TypeBuilder DefineType()
2770                 {
2771                         if ((ModFlags & (Modifiers.SEALED | Modifiers.STATIC)) == (Modifiers.SEALED | Modifiers.STATIC)) {
2772                                 Report.Error (441, Location, "'{0}': a class cannot be both static and sealed", GetSignatureForError ());
2773                                 return null;
2774                         }
2775
2776                         TypeBuilder tb = base.DefineType ();
2777                         if (tb == null)
2778                                 return null;
2779
2780                         if (ptype != TypeManager.object_type) {
2781                                 Report.Error (713, Location, "Static class '{0}' cannot derive from type '{1}'. Static classes must derive from object", GetSignatureForError (), TypeManager.CSharpName (ptype));
2782                                 return null;
2783                         }
2784
2785                         if (ifaces != null) {
2786                                 foreach (Type t in ifaces)
2787                                         Report.SymbolRelatedToPreviousError (t);
2788                                 Report.Error (714, Location, "'{0}': static classes cannot implement interfaces", GetSignatureForError ());
2789                         }
2790                         return tb;
2791                 }
2792
2793                 protected override TypeAttributes TypeAttr {
2794                         get {
2795                                 return base.TypeAttr | TypeAttributes.Abstract | TypeAttributes.Sealed;
2796                         }
2797                 }
2798         }
2799
2800         public class Class : ClassOrStruct {
2801                 // TODO: remove this and use only AllowedModifiersProp to fix partial classes bugs
2802                 public const int AllowedModifiers =
2803                         Modifiers.NEW |
2804                         Modifiers.PUBLIC |
2805                         Modifiers.PROTECTED |
2806                         Modifiers.INTERNAL |
2807                         Modifiers.PRIVATE |
2808                         Modifiers.ABSTRACT |
2809                         Modifiers.SEALED |
2810                         Modifiers.UNSAFE;
2811
2812                 bool WasTransitError;
2813
2814                 public Class (NamespaceEntry ns, TypeContainer parent, MemberName name, int mod,
2815                               Attributes attrs, Location l)
2816                         : base (ns, parent, name, attrs, Kind.Class, l)
2817                 {
2818                         this.ModFlags = mod;
2819                 }
2820
2821                 virtual protected int AllowedModifiersProp {
2822                         get {
2823                                 return AllowedModifiers;
2824                         }
2825                 }
2826
2827                 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
2828                 {
2829                         if (a.Type == TypeManager.attribute_usage_type) {
2830                                 if (ptype != TypeManager.attribute_type && !ptype.IsSubclassOf (TypeManager.attribute_type) &&
2831                                         TypeBuilder.FullName != "System.Attribute") {
2832                                         Report.Error (641, a.Location, "Attribute '{0}' is only valid on classes derived from System.Attribute", a.Name);
2833                                 }
2834                         }
2835
2836                         if (a.Type == TypeManager.conditional_attribute_type &&
2837                                 !(ptype == TypeManager.attribute_type || ptype.IsSubclassOf (TypeManager.attribute_type))) {
2838                                 Report.Error (1689, a.Location, "Attribute 'System.Diagnostics.ConditionalAttribute' is only valid on methods or attribute classes");
2839                                 return;
2840                         }
2841
2842                         if (AttributeTester.IsAttributeExcluded (a.Type))
2843                                 return;
2844
2845                         base.ApplyAttributeBuilder (a, cb);
2846                 }
2847
2848                 public const TypeAttributes DefaultTypeAttributes =
2849                         TypeAttributes.AutoLayout | TypeAttributes.Class;
2850
2851                 public override TypeBuilder DefineType()
2852                 {
2853                         if (InTransit) {
2854                                 if (WasTransitError)
2855                                         return null;
2856                                 throw new CircularDepException (this);
2857                         }
2858
2859                         if ((ModFlags & Modifiers.ABSTRACT) == Modifiers.ABSTRACT && (ModFlags & (Modifiers.SEALED | Modifiers.STATIC)) != 0) {
2860                                 Report.Error (418, Location, "'{0}': an abstract class cannot be sealed or static", GetSignatureForError ());
2861                                 return null;
2862                         }
2863
2864                         int accmods = Parent.Parent == null ? Modifiers.INTERNAL : Modifiers.PRIVATE;
2865                         ModFlags = Modifiers.Check (AllowedModifiersProp, ModFlags, accmods, Location);
2866
2867                         try {
2868                                 return base.DefineType ();
2869                         }
2870                         catch (CircularDepException e) {
2871                                 Report.SymbolRelatedToPreviousError (e.Container);
2872                                 Report.Error (146, Location, "Circular base class dependency involving '{0}' and '{1}'",
2873                                         GetSignatureForError (), e.Container.GetSignatureForError ());
2874                                 WasTransitError = true;
2875                                 return null;
2876                         }
2877                 }
2878
2879                 /// Search for at least one defined condition in ConditionalAttribute of attribute class
2880                 /// Valid only for attribute classes.
2881                 public bool IsExcluded ()
2882                 {
2883                         if ((caching_flags & Flags.Excluded_Undetected) == 0)
2884                                 return (caching_flags & Flags.Excluded) != 0;
2885
2886                         caching_flags &= ~Flags.Excluded_Undetected;
2887
2888                         if (OptAttributes == null)
2889                                 return false;
2890
2891                         Attribute[] attrs = OptAttributes.SearchMulti (TypeManager.conditional_attribute_type, ec);
2892
2893                         if (attrs == null)
2894                                 return false;
2895
2896                         foreach (Attribute a in attrs) {
2897                                 string condition = a.GetConditionalAttributeValue (Parent.EmitContext);
2898                                 if (RootContext.AllDefines.Contains (condition))
2899                                         return false;
2900                         }
2901
2902                         caching_flags |= Flags.Excluded;
2903                         return true;
2904                 }
2905
2906                 //
2907                 // FIXME: How do we deal with the user specifying a different
2908                 // layout?
2909                 //
2910                 protected override TypeAttributes TypeAttr {
2911                         get {
2912                                 return base.TypeAttr | DefaultTypeAttributes;
2913                         }
2914                 }
2915         }
2916
2917         public class Struct : ClassOrStruct {
2918                 // <summary>
2919                 //   Modifiers allowed in a struct declaration
2920                 // </summary>
2921                 public const int AllowedModifiers =
2922                         Modifiers.NEW       |
2923                         Modifiers.PUBLIC    |
2924                         Modifiers.PROTECTED |
2925                         Modifiers.INTERNAL  |
2926                         Modifiers.UNSAFE    |
2927                         Modifiers.PRIVATE;
2928
2929                 public Struct (NamespaceEntry ns, TypeContainer parent, MemberName name,
2930                                int mod, Attributes attrs, Location l)
2931                         : base (ns, parent, name, attrs, Kind.Struct, l)
2932                 {
2933                         int accmods;
2934                         
2935                         if (parent.Parent == null)
2936                                 accmods = Modifiers.INTERNAL;
2937                         else
2938                                 accmods = Modifiers.PRIVATE;
2939                         
2940                         this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
2941
2942                         this.ModFlags |= Modifiers.SEALED;
2943                 }
2944
2945                 public const TypeAttributes DefaultTypeAttributes =
2946                         TypeAttributes.SequentialLayout |
2947                         TypeAttributes.Sealed |
2948                         TypeAttributes.BeforeFieldInit;
2949
2950                 //
2951                 // FIXME: Allow the user to specify a different set of attributes
2952                 // in some cases (Sealed for example is mandatory for a class,
2953                 // but what SequentialLayout can be changed
2954                 //
2955                 protected override TypeAttributes TypeAttr {
2956                         get {
2957                                 return base.TypeAttr | DefaultTypeAttributes;
2958                         }
2959                 }
2960
2961                 public override TypeBuilder DefineType()
2962                 {
2963                         if (InTransit) {
2964                                 InTransit = false;
2965                                 throw new CircularDepException (this);
2966                         }
2967
2968                         try {
2969                                 return base.DefineType ();
2970                         }
2971                         catch (CircularDepException e) {
2972                                 InTransit = false;
2973                                 Report.SymbolRelatedToPreviousError (this);
2974                                 Error_TypeInListIsNotInterface (e.Container.Location, GetSignatureForError ());
2975                                 return null;
2976                         }
2977                 }
2978         }
2979
2980         /// <summary>
2981         ///   Interfaces
2982         /// </summary>
2983         public class Interface : TypeContainer, IMemberContainer {
2984
2985                 bool WasTransitError;
2986
2987                 /// <summary>
2988                 ///   Modifiers allowed in a class declaration
2989                 /// </summary>
2990                 public const int AllowedModifiers =
2991                         Modifiers.NEW       |
2992                         Modifiers.PUBLIC    |
2993                         Modifiers.PROTECTED |
2994                         Modifiers.INTERNAL  |
2995                         Modifiers.UNSAFE    |
2996                         Modifiers.PRIVATE;
2997
2998                 public Interface (NamespaceEntry ns, TypeContainer parent, MemberName name, int mod,
2999                                   Attributes attrs, Location l)
3000                         : base (ns, parent, name, attrs, Kind.Interface, l)
3001                 {
3002                         int accmods;
3003
3004                         if (parent.Parent == null)
3005                                 accmods = Modifiers.INTERNAL;
3006                         else
3007                                 accmods = Modifiers.PRIVATE;
3008
3009                         this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
3010                 }
3011
3012                 public override PendingImplementation GetPendingImplementations ()
3013                 {
3014                         return null;
3015                 }
3016
3017                 public const TypeAttributes DefaultTypeAttributes =
3018                         TypeAttributes.AutoLayout |
3019                         TypeAttributes.Abstract |
3020                         TypeAttributes.Interface;
3021
3022                 protected override TypeAttributes TypeAttr {
3023                         get {
3024                                 return base.TypeAttr | DefaultTypeAttributes;
3025                         }
3026                 }
3027
3028                 public override TypeBuilder DefineType()
3029                 {
3030                         if (InTransit) {
3031                                 if (WasTransitError) 
3032                                         return null;
3033                                 throw new CircularDepException (this);
3034                         }
3035
3036                         try {
3037                                 return base.DefineType ();
3038                         }
3039                         catch (CircularDepException e) {
3040                                 Report.SymbolRelatedToPreviousError (e.Container);
3041                                 Report.Error (529, Location, "Inherited interface '{0}' causes a cycle in the interface hierarchy of '{1}'",
3042                                         e.Container.GetSignatureForError (), GetSignatureForError ());
3043                                 WasTransitError = true;
3044                                 return null;
3045                         }
3046                 }
3047
3048                 protected override bool VerifyClsCompliance (DeclSpace ds)
3049                 {
3050                         if (!base.VerifyClsCompliance (ds))
3051                                 return false;
3052
3053                         if (ifaces != null) {
3054                                 foreach (Type t in ifaces) {
3055                                         if (AttributeTester.IsClsCompliant (t))
3056                                                 continue;
3057
3058                                         Report.SymbolRelatedToPreviousError (t);
3059                                         Report.Warning (3027, 1, Location, "'{0}' is not CLS-compliant because base interface '{1}' is not CLS-compliant",
3060                                                 GetSignatureForError (), TypeManager.CSharpName (t));
3061                                 }
3062                         }
3063
3064                         return true;
3065                 }
3066         }
3067
3068         public abstract class MethodCore : MemberBase {
3069                 public readonly Parameters Parameters;
3070                 protected ToplevelBlock block;
3071                 
3072                 //
3073                 // Parameters, cached for semantic analysis.
3074                 //
3075                 protected InternalParameters parameter_info;
3076                 protected Type [] parameter_types;
3077
3078                 // Whether this is an operator method.
3079                 public bool IsOperator;
3080
3081                 //
3082                 // The method we're overriding if this is an override method.
3083                 //
3084                 protected MethodInfo base_method = null;
3085
3086                 static string[] attribute_targets = new string [] { "method", "return" };
3087
3088                 public MethodCore (TypeContainer parent, Expression type, int mod,
3089                                    int allowed_mod, bool is_interface, MemberName name,
3090                                    Attributes attrs, Parameters parameters, Location loc)
3091                         : base (parent, type, mod, allowed_mod, Modifiers.PRIVATE, name,
3092                                 attrs, loc)
3093                 {
3094                         Parameters = parameters;
3095                         IsInterface = is_interface;
3096                 }
3097                 
3098                 //
3099                 //  Returns the System.Type array for the parameters of this method
3100                 //
3101                 public Type [] ParameterTypes {
3102                         get {
3103                                 return parameter_types;
3104                         }
3105                 }
3106
3107                 public InternalParameters ParameterInfo
3108                 {
3109                         get {
3110                                 return parameter_info;
3111                         }
3112                 }
3113                 
3114                 public ToplevelBlock Block {
3115                         get {
3116                                 return block;
3117                         }
3118
3119                         set {
3120                                 block = value;
3121                         }
3122                 }
3123
3124                 protected override bool CheckBase ()
3125                 {
3126                         if (!base.CheckBase ())
3127                                 return false;
3128                         
3129                         // Check whether arguments were correct.
3130                         if (!DoDefineParameters ())
3131                                 return false;
3132
3133                         if ((caching_flags & Flags.TestMethodDuplication) != 0 && !CheckForDuplications ())
3134                                 return false;
3135
3136                         if (IsExplicitImpl)
3137                                 return true;
3138
3139                         // Is null for System.Object while compiling corlib and base interfaces
3140                         if (Parent.BaseCache == null) {
3141                                 if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0)) {
3142                                         Report.Warning (109, Location, "The member '{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError (Parent));
3143                                 }
3144                                 return true;
3145                         }
3146
3147                         Type base_ret_type = null;
3148                         base_method = FindOutBaseMethod (Parent, ref base_ret_type);
3149
3150                         // method is override
3151                         if (base_method != null) {
3152
3153                                 if (!CheckMethodAgainstBase ())
3154                                         return false;
3155
3156                                 if ((ModFlags & Modifiers.NEW) == 0) {
3157                                         if (MemberType != TypeManager.TypeToCoreType (base_ret_type)) {
3158                                                 Report.SymbolRelatedToPreviousError (base_method);
3159                                                 if (this is PropertyBase) {
3160                                                         Report.Error (1715, Location, "'{0}': type must be '{1}' to match overridden member '{2}'", 
3161                                                                 GetSignatureForError (), TypeManager.CSharpName (base_ret_type), TypeManager.CSharpSignature (base_method));
3162                                                 }
3163                                                 else {
3164                                                         Report.Error (508, Location, GetSignatureForError (Parent) + ": cannot " +
3165                                                                 "change return type when overriding inherited member");
3166                                                 }
3167                                                 return false;
3168                                         }
3169                                 } else {
3170                                         if (base_method.IsAbstract && !IsInterface) {
3171                                                 Report.SymbolRelatedToPreviousError (base_method);
3172                                                 Report.Error (533, Location, "'{0}' hides inherited abstract member", GetSignatureForError (Parent));
3173                                                 return false;
3174                                         }
3175                                 }
3176
3177                                 if (base_method.IsSpecialName && !(this is PropertyBase)) {
3178                                         Report.Error (561, Location, "'{0}': cannot override '{1}' because it is a special compiler-generated method", GetSignatureForError (Parent), TypeManager.GetFullNameSignature (base_method));
3179                                         return false;
3180                                 }
3181
3182                                 if (RootContext.WarningLevel > 2) {
3183                                         if (Name == "Equals" && parameter_types.Length == 1 && parameter_types [0] == TypeManager.object_type)
3184                                                 Parent.Methods.HasEquals = true;
3185                                         else if (Name == "GetHashCode" && parameter_types.Length == 0)
3186                                                 Parent.Methods.HasGetHashCode = true;
3187                                 }
3188
3189                                 if ((ModFlags & Modifiers.OVERRIDE) != 0) {
3190                                         ObsoleteAttribute oa = AttributeTester.GetMethodObsoleteAttribute (base_method);
3191                                         if (oa != null) {
3192                                                 EmitContext ec = new EmitContext (this.Parent, this.Parent, Location, null, null, ModFlags, false);
3193                                                 if (OptAttributes == null || !OptAttributes.Contains (TypeManager.obsolete_attribute_type, ec)) {
3194                                                         Report.SymbolRelatedToPreviousError (base_method);
3195                                                         Report.Warning (672, 1, Location, "Member '{0}' overrides obsolete member. Add the Obsolete attribute to '{0}'", GetSignatureForError (Parent));
3196                                                 }
3197                                         }
3198                                 }
3199                                 return true;
3200                         }
3201
3202                         MemberInfo conflict_symbol = Parent.FindBaseMemberWithSameName (Name, !(this is Property));
3203                         if ((ModFlags & Modifiers.OVERRIDE) != 0) {
3204                                 if (conflict_symbol != null) {
3205                                         Report.SymbolRelatedToPreviousError (conflict_symbol);
3206                                         if (this is PropertyBase)
3207                                                 Report.Error (544, Location, "'{0}': cannot override because '{1}' is not a property", GetSignatureForError (Parent), TypeManager.GetFullNameSignature (conflict_symbol));
3208                                         else
3209                                                 Report.Error (505, Location, "'{0}': cannot override because '{1}' is not a method", GetSignatureForError (Parent), TypeManager.GetFullNameSignature (conflict_symbol));
3210                                 } else
3211                                         Report.Error (115, Location, "'{0}': no suitable methods found to override", GetSignatureForError (Parent));
3212                                 return false;
3213                         }
3214
3215                         if (conflict_symbol == null) {
3216                                 if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0)) {
3217                                         Report.Warning (109, Location, "The member '{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError (Parent));
3218                                 }
3219                                 return true;
3220                         }
3221
3222                         if ((ModFlags & Modifiers.NEW) == 0) {
3223                                 if (this is Method && conflict_symbol is MethodBase)
3224                                         return true;
3225
3226                                 Report.SymbolRelatedToPreviousError (conflict_symbol);
3227                                 Report.Warning (108, Location, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError (Parent));
3228                         }
3229
3230                         return true;
3231                 }
3232
3233
3234                 //
3235                 // Performs various checks on the MethodInfo `mb' regarding the modifier flags
3236                 // that have been defined.
3237                 //
3238                 // `name' is the user visible name for reporting errors (this is used to
3239                 // provide the right name regarding method names and properties)
3240                 //
3241                 bool CheckMethodAgainstBase ()
3242                 {
3243                         bool ok = true;
3244
3245                         // TODO: replace with GetSignatureForError 
3246                         string name = base_method.DeclaringType.Name + "." + base_method.Name;
3247
3248                         if ((ModFlags & Modifiers.OVERRIDE) != 0){
3249                                 if (!(base_method.IsAbstract || base_method.IsVirtual)){
3250                                         Report.Error (
3251                                                 506, Location, Parent.MakeName (Name) +
3252                                                 ": cannot override inherited member `" +
3253                                                 name + "' because it is not " +
3254                                                 "virtual, abstract or override");
3255                                         ok = false;
3256                                 }
3257                                 
3258                                 // Now we check that the overriden method is not final
3259                                 
3260                                 if (base_method.IsFinal) {
3261                                         Report.SymbolRelatedToPreviousError (base_method);
3262                                         Report.Error (239, Location, "'{0}': cannot override inherited member '{1}' because it is sealed",
3263                                                               GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3264                                         ok = false;
3265                                 }
3266                                 //
3267                                 // Check that the permissions are not being changed
3268                                 //
3269                                 MethodAttributes thisp = flags & MethodAttributes.MemberAccessMask;
3270                                 MethodAttributes base_classp = base_method.Attributes & MethodAttributes.MemberAccessMask;
3271
3272                                 if (!CheckAccessModifiers (thisp, base_classp, base_method)) {
3273                                         Error_CannotChangeAccessModifiers (Parent, base_method, name);
3274                                         ok = false;
3275                                 }
3276                         }
3277
3278                         if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE)) == 0 && Name != "Finalize") {
3279                                 ModFlags |= Modifiers.NEW;
3280                                 Report.SymbolRelatedToPreviousError (base_method);
3281                                 if (!IsInterface && (base_method.IsVirtual || base_method.IsAbstract)) {
3282                                         if (RootContext.WarningLevel >= 2)
3283                                                 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));
3284                                 } else
3285                                         Report.Warning (108, Location, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError (Parent));
3286                         }
3287
3288                         return ok;
3289                 }
3290                 
3291                 protected bool CheckAccessModifiers (MethodAttributes thisp, MethodAttributes base_classp, MethodInfo base_method)
3292                 {
3293                         if ((base_classp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
3294                                 //
3295                                 // when overriding protected internal, the method can be declared
3296                                 // protected internal only within the same assembly
3297                                 //
3298
3299                                 if ((thisp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
3300                                         if (Parent.TypeBuilder.Assembly != base_method.DeclaringType.Assembly){
3301                                                 //
3302                                                 // assemblies differ - report an error
3303                                                 //
3304                                                 
3305                                                 return false;
3306                                         } else if (thisp != base_classp) {
3307                                                 //
3308                                                 // same assembly, but other attributes differ - report an error
3309                                                 //
3310                                                 
3311                                                 return false;
3312                                         };
3313                                 } else if ((thisp & MethodAttributes.Family) != MethodAttributes.Family) {
3314                                         //
3315                                         // if it's not "protected internal", it must be "protected"
3316                                         //
3317
3318                                         return false;
3319                                 } else if (Parent.TypeBuilder.Assembly == base_method.DeclaringType.Assembly) {
3320                                         //
3321                                         // protected within the same assembly - an error
3322                                         //
3323                                         return false;
3324                                 } else if ((thisp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem)) != 
3325                                            (base_classp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem))) {
3326                                         //
3327                                         // protected ok, but other attributes differ - report an error
3328                                         //
3329                                         return false;
3330                                 }
3331                                 return true;
3332                         } else {
3333                                 return (thisp == base_classp);
3334                         }
3335                 }
3336                 
3337                 void Error_CannotChangeAccessModifiers (TypeContainer parent, MethodInfo base_method, string name)
3338                 {
3339                         //
3340                         // FIXME: report the old/new permissions?
3341                         //
3342                         Report.Error (
3343                                 507, Location, parent.MakeName (Name) +
3344                                 ": can't change the access modifiers when overriding inherited " +
3345                                 "member `" + name + "'");
3346                 }
3347
3348                 protected static string Error722 {
3349                         get {
3350                                 return "'{0}': static types cannot be used as return types";
3351                         }
3352                 }
3353
3354                 /// <summary>
3355                 /// For custom member duplication search in a container
3356                 /// </summary>
3357                 protected abstract bool CheckForDuplications ();
3358
3359                 /// <summary>
3360                 /// Gets base method and its return type
3361                 /// </summary>
3362                 protected abstract MethodInfo FindOutBaseMethod (TypeContainer container, ref Type base_ret_type);
3363
3364                 protected virtual bool DoDefineParameters ()
3365                 {
3366                         EmitContext ec = Parent.EmitContext;
3367                         if (ec == null)
3368                                 throw new InternalErrorException ("DoDefineParameters invoked too early");
3369
3370                         bool old_unsafe = ec.InUnsafe;
3371                         ec.InUnsafe = InUnsafe;
3372                         // Check if arguments were correct
3373                         parameter_types = Parameters.GetParameterInfo (ec);
3374                         ec.InUnsafe = old_unsafe;
3375
3376                         if ((parameter_types == null) ||
3377                             !CheckParameters (Parent, parameter_types))
3378                                 return false;
3379
3380                         parameter_info = new InternalParameters (parameter_types, Parameters);
3381
3382                         Parameter array_param = Parameters.ArrayParameter;
3383                         if ((array_param != null) &&
3384                             (!array_param.ParameterType.IsArray ||
3385                              (array_param.ParameterType.GetArrayRank () != 1))) {
3386                                 Report.Error (225, Location, "params parameter has to be a single dimensional array");
3387                                 return false;
3388                         }
3389
3390                         return true;
3391                 }
3392
3393                 public override string[] ValidAttributeTargets {
3394                         get {
3395                                 return attribute_targets;
3396                         }
3397                 }
3398
3399                 protected override bool VerifyClsCompliance (DeclSpace ds)
3400                 {
3401                         if (!base.VerifyClsCompliance (ds)) {
3402                                 if ((ModFlags & Modifiers.ABSTRACT) != 0 && IsExposedFromAssembly (ds) && ds.IsClsCompliaceRequired (ds)) {
3403                                         Report.Error (3011, Location, "'{0}': only CLS-compliant members can be abstract", GetSignatureForError ());
3404                                 }
3405                                 return false;
3406                         }
3407
3408                         if (Parameters.HasArglist) {
3409                                 Report.Error (3000, Location, "Methods with variable arguments are not CLS-compliant");
3410                         }
3411
3412                         if (!AttributeTester.IsClsCompliant (MemberType)) {
3413                                 if (this is PropertyBase)
3414                                         Report.Error (3003, Location, "Type of `{0}' is not CLS-compliant",
3415                                                       GetSignatureForError ());
3416                                 else
3417                                         Report.Error (3002, Location, "Return type of '{0}' is not CLS-compliant",
3418                                                       GetSignatureForError ());
3419                         }
3420
3421                         AttributeTester.AreParametersCompliant (Parameters.FixedParameters, Location);
3422
3423                         return true;
3424                 }
3425
3426                 protected bool IsDuplicateImplementation (MethodCore method)
3427                 {
3428                         if ((method == this) || (method.Name != Name))
3429                                 return false;
3430
3431                         Type[] param_types = method.ParameterTypes;
3432                         if (param_types == null)
3433                                 return false;
3434
3435                         if (param_types.Length != ParameterTypes.Length)
3436                                 return false;
3437
3438                         for (int i = 0; i < param_types.Length; i++)
3439                                 if (param_types [i] != ParameterTypes [i])
3440                                         return false;
3441
3442                         // TODO: make operator compatible with MethodCore to avoid this
3443                         if (this is Operator && method is Operator) {
3444                                 if (MemberType != method.MemberType)
3445                                         return false;
3446                         }
3447
3448                         //
3449                         // Try to report 663: method only differs on out/ref
3450                         //
3451                         ParameterData info = ParameterInfo;
3452                         ParameterData other_info = method.ParameterInfo;
3453                         for (int i = 0; i < info.Count; i++){
3454                                 if (info.ParameterModifier (i) != other_info.ParameterModifier (i)){
3455                                         Report.Error (663, Location, "Overload method only differs in parameter modifier");
3456                                         return false;
3457                                 }
3458                         }
3459
3460                         Report.SymbolRelatedToPreviousError (method);
3461                         if (this is Operator && method is Operator)
3462                                 Report.Error (557, Location, "Duplicate user-defined conversion in type '{0}'", Parent.Name);
3463                         else
3464                                 Report.Error (111, Location, TypeContainer.Error111, Parent.Name, Name);
3465                         return true;
3466                 }
3467
3468                 public override bool IsUsed
3469                 {
3470                         get {
3471                                 if (IsExplicitImpl)
3472                                         return true;
3473
3474                                 return base.IsUsed;
3475                         }
3476                 }
3477
3478                 //
3479                 // Returns a string that represents the signature for this 
3480                 // member which should be used in XML documentation.
3481                 //
3482                 public override string GetDocCommentName (DeclSpace ds)
3483                 {
3484                         return DocUtil.GetMethodDocCommentName (this, ds);
3485                 }
3486
3487                 //
3488                 // Raised (and passed an XmlElement that contains the comment)
3489                 // when GenerateDocComment is writing documentation expectedly.
3490                 //
3491                 // FIXME: with a few effort, it could be done with XmlReader,
3492                 // that means removal of DOM use.
3493                 //
3494                 internal override void OnGenerateDocComment (DeclSpace ds, XmlElement el)
3495                 {
3496                         DocUtil.OnMethodGenerateDocComment (this, ds, el);
3497                 }
3498
3499                 //
3500                 //   Represents header string for documentation comment.
3501                 //
3502                 public override string DocCommentHeader {
3503                         get { return "M:"; }
3504                 }
3505
3506                 protected override void VerifyObsoleteAttribute()
3507                 {
3508                         base.VerifyObsoleteAttribute ();
3509
3510                         if (parameter_types == null)
3511                                 return;
3512
3513                         foreach (Type type in parameter_types) {
3514                                 CheckUsageOfObsoleteAttribute (type);
3515                         }
3516                 }
3517         }
3518
3519         public class SourceMethod : ISourceMethod
3520         {
3521                 TypeContainer container;
3522                 MethodBase builder;
3523
3524                 protected SourceMethod (TypeContainer container, MethodBase builder,
3525                                         ISourceFile file, Location start, Location end)
3526                 {
3527                         this.container = container;
3528                         this.builder = builder;
3529                         
3530                         CodeGen.SymbolWriter.OpenMethod (
3531                                 file, this, start.Row, 0, end.Row, 0);
3532                 }
3533
3534                 public string Name {
3535                         get { return builder.Name; }
3536                 }
3537
3538                 public int NamespaceID {
3539                         get { return container.NamespaceEntry.SymbolFileID; }
3540                 }
3541
3542                 public int Token {
3543                         get {
3544                                 if (builder is MethodBuilder)
3545                                         return ((MethodBuilder) builder).GetToken ().Token;
3546                                 else if (builder is ConstructorBuilder)
3547                                         return ((ConstructorBuilder) builder).GetToken ().Token;
3548                                 else
3549                                         throw new NotSupportedException ();
3550                         }
3551                 }
3552
3553                 public void CloseMethod ()
3554                 {
3555                         if (CodeGen.SymbolWriter != null)
3556                                 CodeGen.SymbolWriter.CloseMethod ();
3557                 }
3558
3559                 public static SourceMethod Create (TypeContainer parent,
3560                                                    MethodBase builder, Block block)
3561                 {
3562                         if (CodeGen.SymbolWriter == null)
3563                                 return null;
3564                         if (block == null)
3565                                 return null;
3566
3567                         Location start_loc = block.StartLocation;
3568                         if (Location.IsNull (start_loc))
3569                                 return null;
3570
3571                         Location end_loc = block.EndLocation;
3572                         if (Location.IsNull (end_loc))
3573                                 return null;
3574
3575                         ISourceFile file = start_loc.SourceFile;
3576                         if (file == null)
3577                                 return null;
3578
3579                         return new SourceMethod (
3580                                 parent, builder, file, start_loc, end_loc);
3581                 }
3582         }
3583
3584         public class Method : MethodCore, IIteratorContainer, IMethodData {
3585                 public MethodBuilder MethodBuilder;
3586                 public MethodData MethodData;
3587                 ReturnParameter return_attributes;
3588                 ListDictionary declarative_security;
3589
3590                 /// <summary>
3591                 ///   Modifiers allowed in a class declaration
3592                 /// </summary>
3593                 const int AllowedModifiers =
3594                         Modifiers.NEW |
3595                         Modifiers.PUBLIC |
3596                         Modifiers.PROTECTED |
3597                         Modifiers.INTERNAL |
3598                         Modifiers.PRIVATE |
3599                         Modifiers.STATIC |
3600                         Modifiers.VIRTUAL |
3601                         Modifiers.SEALED |
3602                         Modifiers.OVERRIDE |
3603                         Modifiers.ABSTRACT |
3604                         Modifiers.UNSAFE |
3605                         Modifiers.METHOD_YIELDS | 
3606                         Modifiers.EXTERN;
3607
3608                 const int AllowedInterfaceModifiers =
3609                         Modifiers.NEW | Modifiers.UNSAFE;
3610
3611                 //
3612                 // return_type can be "null" for VOID values.
3613                 //
3614                 public Method (TypeContainer ds, Expression return_type, int mod, bool is_iface,
3615                                MemberName name, Parameters parameters, Attributes attrs,
3616                                Location l)
3617                         : base (ds, return_type, mod,
3618                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
3619                                 is_iface, name, attrs, parameters, l)
3620                 {
3621                 }
3622
3623                 public override AttributeTargets AttributeTargets {
3624                         get {
3625                                 return AttributeTargets.Method;
3626                         }
3627                 }
3628                 
3629                 public override string GetSignatureForError()
3630                 {
3631                         if (MethodBuilder == null) {
3632                                 return GetSignatureForError (Parent);
3633                         }
3634                         return TypeManager.CSharpSignature (MethodBuilder);
3635                 }
3636
3637                 /// <summary>
3638                 /// Use this method when MethodBuilder is null
3639                 /// </summary>
3640                 public override string GetSignatureForError (TypeContainer tc)
3641                 {
3642                         // TODO: get params from somewhere
3643                         if (parameter_info == null)
3644                                 return base.GetSignatureForError (tc);
3645
3646                         // TODO: move to parameters
3647                         System.Text.StringBuilder args = new System.Text.StringBuilder ();
3648                         if (parameter_info.Parameters.FixedParameters != null) {
3649                                 for (int i = 0; i < parameter_info.Parameters.FixedParameters.Length; ++i) {
3650                                         Parameter p = parameter_info.Parameters.FixedParameters [i];
3651                                         args.Append (p.GetSignatureForError ());
3652
3653                                         if (i < parameter_info.Parameters.FixedParameters.Length - 1)
3654                                                 args.Append (',');
3655                                 }
3656                         }
3657
3658                         return String.Concat (base.GetSignatureForError (tc), "(", args.ToString (), ")");
3659                 }
3660
3661                 void DuplicateEntryPoint (MethodInfo b, Location location)
3662                 {
3663                         Report.Error (
3664                                 17, location,
3665                                 "Program `" + CodeGen.FileName +
3666                                 "'  has more than one entry point defined: `" +
3667                                 TypeManager.CSharpSignature(b) + "'");
3668                 }
3669
3670                 public bool IsEntryPoint (MethodBuilder b, InternalParameters pinfo)
3671                 {
3672                         if (b.ReturnType != TypeManager.void_type &&
3673                             b.ReturnType != TypeManager.int32_type)
3674                                 return false;
3675
3676                         if (pinfo.Count == 0)
3677                                 return true;
3678
3679                         if (pinfo.Count > 1)
3680                                 return false;
3681
3682                         Type t = pinfo.ParameterType(0);
3683                         if (t.IsArray &&
3684                             (t.GetArrayRank() == 1) &&
3685                             (TypeManager.GetElementType(t) == TypeManager.string_type) &&
3686                             (pinfo.ParameterModifier(0) == Parameter.Modifier.NONE))
3687                                 return true;
3688                         else
3689                                 return false;
3690                 }
3691
3692                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
3693                 {
3694                         if (a.Target == AttributeTargets.ReturnValue) {
3695                                 if (return_attributes == null)
3696                                         return_attributes = new ReturnParameter (MethodBuilder, Location);
3697
3698                                 return_attributes.ApplyAttributeBuilder (a, cb);
3699                                 return;
3700                         }
3701
3702                         if (a.Type == TypeManager.methodimpl_attr_type &&
3703                                 (a.GetMethodImplOptions () & MethodImplOptions.InternalCall) != 0) {
3704                                 MethodBuilder.SetImplementationFlags (MethodImplAttributes.InternalCall | MethodImplAttributes.Runtime);
3705                         }
3706
3707                         if (a.Type == TypeManager.dllimport_type) {
3708                                 const int extern_static = Modifiers.EXTERN | Modifiers.STATIC;
3709                                 if ((ModFlags & extern_static) != extern_static) {
3710                                         Report.Error (601, a.Location, "The DllImport attribute must be specified on a method marked `static' and `extern'");
3711                                 }
3712
3713                                 return;
3714                         }
3715
3716                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
3717                                 if (declarative_security == null)
3718                                         declarative_security = new ListDictionary ();
3719                                 a.ExtractSecurityPermissionSet (declarative_security);
3720                                 return;
3721                         }
3722
3723                         if (a.Type == TypeManager.conditional_attribute_type) {
3724                                 if (IsOperator || IsExplicitImpl) {
3725                                         Report.Error (577, Location, "Conditional not valid on '{0}' because it is a destructor, operator, or explicit interface implementation", GetSignatureForError ());
3726                                         return;
3727                                 }
3728
3729                                 if (ReturnType != TypeManager.void_type) {
3730                                         Report.Error (578, Location, "Conditional not valid on '{0}' because its return type is not void", GetSignatureForError ());
3731                                         return;
3732                                 }
3733
3734                                 if ((ModFlags & Modifiers.OVERRIDE) != 0) {
3735                                         Report.Error (243, Location, "Conditional not valid on '{0}' because it is an override method", GetSignatureForError ());
3736                                         return;
3737                                 }
3738
3739                                 if (IsInterface) {
3740                                         Report.Error (582, Location, "Conditional not valid on interface members");
3741                                         return;
3742                                 }
3743
3744                                 if (MethodData.IsImplementing) {
3745                                         Report.Error (629, Location, "Conditional member '{0}' cannot implement interface member", GetSignatureForError ());
3746                                         return;
3747                                 }
3748
3749                                 for (int i = 0; i < parameter_info.Count; ++i) {
3750                                         if ((parameter_info.ParameterModifier (i) & Parameter.Modifier.OUT) != 0) {
3751                                                 Report.Error (685, Location, "Conditional method '{0}' cannot have an out parameter", GetSignatureForError ());
3752                                                 return;
3753                                         }
3754                                 }
3755                         }
3756
3757                         MethodBuilder.SetCustomAttribute (cb);
3758                 }
3759
3760                 protected override bool CheckForDuplications ()
3761                 {
3762                         ArrayList ar = Parent.Methods;
3763                         if (ar != null) {
3764                                 int arLen = ar.Count;
3765                                         
3766                                 for (int i = 0; i < arLen; i++) {
3767                                         Method m = (Method) ar [i];
3768                                         if (IsDuplicateImplementation (m))
3769                                                 return false;
3770                                 }
3771                         }
3772
3773                         ar = Parent.Properties;
3774                         if (ar != null) {
3775                                 for (int i = 0; i < ar.Count; ++i) {
3776                                         PropertyBase pb = (PropertyBase) ar [i];
3777                                         if (pb.AreAccessorsDuplicateImplementation (this))
3778                                                 return false;
3779                                 }
3780                         }
3781
3782                         ar = Parent.Indexers;
3783                         if (ar != null) {
3784                                 for (int i = 0; i < ar.Count; ++i) {
3785                                         PropertyBase pb = (PropertyBase) ar [i];
3786                                         if (pb.AreAccessorsDuplicateImplementation (this))
3787                                                 return false;
3788                                 }
3789                         }
3790
3791                         ar = Parent.Events;
3792                         if (ar != null) {
3793                                 for (int i = 0; i < ar.Count; ++i) {
3794                                         Event ev = (Event) ar [i];
3795                                         if (ev.AreAccessorsDuplicateImplementation (this))
3796                                                 return false;
3797                                 }
3798                         }
3799
3800                         return true;
3801                 }
3802
3803                 //
3804                 // Creates the type
3805                 //
3806                 public override bool Define ()
3807                 {
3808                         if (!DoDefine ())
3809                                 return false;
3810
3811                         if (RootContext.StdLib && (ReturnType == TypeManager.arg_iterator_type || ReturnType == TypeManager.typed_reference_type)) {
3812                                 Error1599 (Location, ReturnType);
3813                                 return false;
3814                         }
3815
3816                         if (!CheckBase ())
3817                                 return false;
3818
3819                         if (IsOperator)
3820                                 flags |= MethodAttributes.SpecialName | MethodAttributes.HideBySig;
3821
3822                         MethodData = new MethodData (this, ParameterInfo, ModFlags, flags, this);
3823
3824                         if (!MethodData.Define (Parent))
3825                                 return false;
3826
3827                         if (ReturnType == TypeManager.void_type && ParameterTypes.Length == 0 && 
3828                                 Name == "Finalize" && !(this is Destructor)) {
3829                                 Report.Warning (465, 1, Location, "Introducing a 'Finalize' method can interfere with destructor invocation. Did you intend to declare a destructor?");
3830                         }
3831
3832                         //
3833                         // Setup iterator if we are one
3834                         //
3835                         if ((ModFlags & Modifiers.METHOD_YIELDS) != 0){
3836                                 Iterator iterator = new Iterator (
3837                                         Parent, Name, MemberType,
3838                                         ParameterInfo, ModFlags, block, Location);
3839
3840                                 if (!iterator.DefineIterator ())
3841                                         return false;
3842
3843                                 block = iterator.Block;
3844                         }
3845
3846                         MethodBuilder = MethodData.MethodBuilder;
3847                         
3848                         //
3849                         // This is used to track the Entry Point,
3850                         //
3851                         if (Name == "Main" &&
3852                             ((ModFlags & Modifiers.STATIC) != 0) && RootContext.NeedsEntryPoint && 
3853                             (RootContext.MainClass == null ||
3854                              RootContext.MainClass == Parent.TypeBuilder.FullName)){
3855                                 if (IsEntryPoint (MethodBuilder, ParameterInfo)) {
3856                                         IMethodData md = TypeManager.GetMethod (MethodBuilder);
3857                                         md.SetMemberIsUsed ();
3858
3859                                         if (RootContext.EntryPoint == null) {
3860                                                 RootContext.EntryPoint = MethodBuilder;
3861                                                 RootContext.EntryPointLocation = Location;
3862                                         } else {
3863                                                 DuplicateEntryPoint (RootContext.EntryPoint, RootContext.EntryPointLocation);
3864                                                 DuplicateEntryPoint (MethodBuilder, Location);
3865                                         }
3866                                 } else {
3867                                         if (RootContext.WarningLevel >= 4)
3868                                                 Report.Warning (28, Location, "'{0}' has the wrong signature to be an entry point", TypeManager.CSharpSignature(MethodBuilder));
3869                                 }
3870                         }
3871
3872                         if (MemberType.IsAbstract && MemberType.IsSealed) {
3873                                 Report.Error (722, Location, Error722, TypeManager.CSharpName (MemberType));
3874                                 return false;
3875                         }
3876
3877                         return true;
3878                 }
3879
3880                 //
3881                 // Emits the code
3882                 // 
3883                 public override void Emit ()
3884                 {
3885                         MethodData.Emit (Parent, this);
3886                         base.Emit ();
3887
3888                         if (declarative_security != null) {
3889                                 foreach (DictionaryEntry de in declarative_security) {
3890                                         MethodBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
3891                                 }
3892                         }
3893
3894                         Block = null;
3895                         MethodData = null;
3896                 }
3897
3898                 public static void Error1599 (Location loc, Type t)
3899                 {
3900                         Report.Error (1599, loc, "Method or delegate cannot return type '{0}'", TypeManager.CSharpName (t));
3901                 }
3902
3903                 protected override MethodInfo FindOutBaseMethod (TypeContainer container, ref Type base_ret_type)
3904                 {
3905                         MethodInfo mi = (MethodInfo) container.BaseCache.FindMemberToOverride (
3906                                 container.TypeBuilder, Name, ParameterTypes, false);
3907
3908                         if (mi == null)
3909                                 return null;
3910
3911                         base_ret_type = mi.ReturnType;
3912                         return mi;
3913                 }
3914
3915                 public override bool MarkForDuplicationCheck ()
3916                 {
3917                         caching_flags |= Flags.TestMethodDuplication;
3918                         return true;
3919                 }
3920
3921                 protected override bool VerifyClsCompliance(DeclSpace ds)
3922                 {
3923                         if (!base.VerifyClsCompliance (ds))
3924                                 return false;
3925
3926                         if (parameter_types.Length > 0) {
3927                                 ArrayList al = (ArrayList)ds.MemberCache.Members [Name];
3928                                 if (al.Count > 1)
3929                                         ds.MemberCache.VerifyClsParameterConflict (al, this, MethodBuilder);
3930                         }
3931
3932                         return true;
3933                 }
3934
3935
3936                 void IIteratorContainer.SetYields ()
3937                 {
3938                         ModFlags |= Modifiers.METHOD_YIELDS;
3939                 }
3940         
3941                 #region IMethodData Members
3942
3943                 public CallingConventions CallingConventions {
3944                         get {
3945                                 CallingConventions cc = Parameters.GetCallingConvention ();
3946                                 if (Parameters.HasArglist)
3947                                         block.HasVarargs = true;
3948
3949                                 if (!IsInterface)
3950                                         if ((ModFlags & Modifiers.STATIC) == 0)
3951                                                 cc |= CallingConventions.HasThis;
3952
3953                                 // FIXME: How is `ExplicitThis' used in C#?
3954                         
3955                                 return cc;
3956                         }
3957                 }
3958
3959                 public Type ReturnType {
3960                         get {
3961                                 return MemberType;
3962                         }
3963                 }
3964
3965                 public MemberName MethodName {
3966                         get {
3967                                 return MemberName;
3968                         }
3969                 }
3970
3971                 public new Location Location {
3972                         get {
3973                                 return base.Location;
3974                         }
3975                 }
3976
3977                 protected override bool CheckBase() {
3978                         if (!base.CheckBase ())
3979                                 return false;
3980
3981                         // TODO: Destructor should derive from MethodCore
3982                         if (base_method != null && (ModFlags & Modifiers.OVERRIDE) != 0 && Name == "Finalize" &&
3983                                 base_method.DeclaringType == TypeManager.object_type && !(this is Destructor)) {
3984                                 Report.Error (249, Location, "Do not override object.Finalize. Instead, provide a destructor");
3985                                 return false;
3986                         }
3987
3988                         return true;
3989                 }
3990
3991                 public EmitContext CreateEmitContext (TypeContainer tc, ILGenerator ig)
3992                 {
3993                         return new EmitContext (
3994                                 tc, Parent, Location, ig, ReturnType, ModFlags, false);
3995                 }
3996
3997                 public ObsoleteAttribute GetObsoleteAttribute ()
3998                 {
3999                         return GetObsoleteAttribute (Parent);
4000                 }
4001
4002                 /// <summary>
4003                 /// Returns true if method has conditional attribute and the conditions is not defined (method is excluded).
4004                 /// </summary>
4005                 public bool IsExcluded (EmitContext ec)
4006                 {
4007                         if ((caching_flags & Flags.Excluded_Undetected) == 0)
4008                                 return (caching_flags & Flags.Excluded) != 0;
4009
4010                         caching_flags &= ~Flags.Excluded_Undetected;
4011
4012                         if (base_method == null) {
4013                                 if (OptAttributes == null)
4014                                         return false;
4015
4016                                 Attribute[] attrs = OptAttributes.SearchMulti (TypeManager.conditional_attribute_type, ec);
4017
4018                                 if (attrs == null)
4019                                         return false;
4020
4021                                 foreach (Attribute a in attrs) {
4022                                         string condition = a.GetConditionalAttributeValue (Parent.EmitContext);
4023                                         if (RootContext.AllDefines.Contains (condition))
4024                                                 return false;
4025                                 }
4026
4027                                 caching_flags |= Flags.Excluded;
4028                                 return true;
4029                         }
4030
4031                         IMethodData md = TypeManager.GetMethod (base_method);
4032                         if (md == null) {
4033                                 if (AttributeTester.IsConditionalMethodExcluded (base_method)) {
4034                                         caching_flags |= Flags.Excluded;
4035                                         return true;
4036                                 }
4037                                 return false;
4038                         }
4039
4040                         if (md.IsExcluded (ec)) {
4041                                 caching_flags |= Flags.Excluded;
4042                                 return true;
4043                         }
4044                         return false;
4045                 }
4046
4047                 #endregion
4048         }
4049
4050         public abstract class ConstructorInitializer {
4051                 ArrayList argument_list;
4052                 protected ConstructorInfo base_constructor;
4053                 Parameters parameters;
4054                 Location loc;
4055                 
4056                 public ConstructorInitializer (ArrayList argument_list, Parameters parameters,
4057                                                Location loc)
4058                 {
4059                         this.argument_list = argument_list;
4060                         this.parameters = parameters;
4061                         this.loc = loc;
4062                 }
4063
4064                 public ArrayList Arguments {
4065                         get {
4066                                 return argument_list;
4067                         }
4068                 }
4069
4070                 public bool Resolve (ConstructorBuilder caller_builder, Block block, EmitContext ec)
4071                 {
4072                         Expression base_constructor_group;
4073                         Type t;
4074                         bool error = false;
4075
4076                         ec.CurrentBlock = block;
4077
4078                         if (argument_list != null){
4079                                 foreach (Argument a in argument_list){
4080                                         if (!a.Resolve (ec, loc))
4081                                                 return false;
4082                                 }
4083                         }
4084                         ec.CurrentBlock = null;
4085
4086                         if (this is ConstructorBaseInitializer) {
4087                                 if (ec.ContainerType.BaseType == null)
4088                                         return true;
4089
4090                                 t = ec.ContainerType.BaseType;
4091                                 if (ec.ContainerType.IsValueType) {
4092                                         Report.Error (522, loc,
4093                                                 "structs cannot call base class constructors");
4094                                         return false;
4095                                 }
4096                         } else
4097                                 t = ec.ContainerType;
4098
4099                         base_constructor_group = Expression.MemberLookup (
4100                                 ec, t, ".ctor", MemberTypes.Constructor,
4101                                 BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
4102                                 loc);
4103                         
4104                         if (base_constructor_group == null){
4105                                 error = true;
4106                                 base_constructor_group = Expression.MemberLookup (
4107                                         ec, t, null, t, ".ctor", MemberTypes.Constructor,
4108                                         BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly,
4109                                         loc);
4110                         }
4111
4112                         int errors = Report.Errors;
4113                         if (base_constructor_group != null)
4114                                 base_constructor = (ConstructorInfo) Invocation.OverloadResolve (
4115                                         ec, (MethodGroupExpr) base_constructor_group, argument_list,
4116                                         false, loc);
4117                         
4118                         if (base_constructor == null) {
4119                                 if (errors == Report.Errors)
4120                                         Report.Error (1501, loc, "Can not find a constructor for this argument list");
4121                                 return false;
4122                         }
4123
4124                         if (error) {
4125                                 Report.Error (122, loc, "`{0}' is inaccessible due to its protection level",
4126                                               TypeManager.CSharpSignature (base_constructor));
4127                                 base_constructor = null;
4128                                 return false;
4129                         }
4130
4131                         if (base_constructor == caller_builder){
4132                                 Report.Error (516, loc, "Constructor `{0}' can not call itself", TypeManager.CSharpSignature (caller_builder));
4133                                 return false;
4134                         }
4135                         
4136                         return true;
4137                 }
4138
4139                 public void Emit (EmitContext ec)
4140                 {
4141                         if (base_constructor != null){
4142                                 ec.Mark (loc, false);
4143                                 if (ec.IsStatic)
4144                                         Invocation.EmitCall (ec, true, true, null, base_constructor, argument_list, loc);
4145                                 else
4146                                         Invocation.EmitCall (ec, true, false, ec.GetThis (loc), base_constructor, argument_list, loc);
4147                         }
4148                 }
4149         }
4150
4151         public class ConstructorBaseInitializer : ConstructorInitializer {
4152                 public ConstructorBaseInitializer (ArrayList argument_list, Parameters pars, Location l) :
4153                         base (argument_list, pars, l)
4154                 {
4155                 }
4156         }
4157
4158         public class ConstructorThisInitializer : ConstructorInitializer {
4159                 public ConstructorThisInitializer (ArrayList argument_list, Parameters pars, Location l) :
4160                         base (argument_list, pars, l)
4161                 {
4162                 }
4163         }
4164         
4165         public class Constructor : MethodCore, IMethodData {
4166                 public ConstructorBuilder ConstructorBuilder;
4167                 public ConstructorInitializer Initializer;
4168                 ListDictionary declarative_security;
4169
4170                 // <summary>
4171                 //   Modifiers allowed for a constructor.
4172                 // </summary>
4173                 public const int AllowedModifiers =
4174                         Modifiers.PUBLIC |
4175                         Modifiers.PROTECTED |
4176                         Modifiers.INTERNAL |
4177                         Modifiers.STATIC |
4178                         Modifiers.UNSAFE |
4179                         Modifiers.EXTERN |              
4180                         Modifiers.PRIVATE;
4181
4182                 bool has_compliant_args = false;
4183                 //
4184                 // The spec claims that static is not permitted, but
4185                 // my very own code has static constructors.
4186                 //
4187                 public Constructor (TypeContainer ds, string name, int mod, Parameters args,
4188                                     ConstructorInitializer init, Location l)
4189                         : base (ds, null, mod, AllowedModifiers, false, new MemberName (name),
4190                                 null, args, l)
4191                 {
4192                         Initializer = init;
4193                 }
4194
4195                 public override string GetSignatureForError()
4196                 {
4197                         if (ConstructorBuilder == null)
4198                                 return GetSignatureForError (Parent);
4199
4200                         return TypeManager.CSharpSignature (ConstructorBuilder);
4201                 }
4202
4203                 public bool HasCompliantArgs {
4204                         get {
4205                                 return has_compliant_args;
4206                         }
4207                 }
4208
4209                 public override AttributeTargets AttributeTargets {
4210                         get {
4211                                 return AttributeTargets.Constructor;
4212                         }
4213                 }
4214
4215
4216                 //
4217                 // Returns true if this is a default constructor
4218                 //
4219                 public bool IsDefault ()
4220                 {
4221                         if ((ModFlags & Modifiers.STATIC) != 0)
4222                                 return  (Parameters.FixedParameters == null ? true : Parameters.Empty) &&
4223                                         (Parameters.ArrayParameter == null ? true : Parameters.Empty);
4224                         
4225                         else
4226                                 return  (Parameters.FixedParameters == null ? true : Parameters.Empty) &&
4227                                         (Parameters.ArrayParameter == null ? true : Parameters.Empty) &&
4228                                         (Initializer is ConstructorBaseInitializer) &&
4229                                         (Initializer.Arguments == null);
4230                 }
4231
4232                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
4233                 {
4234                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
4235                                 if (declarative_security == null) {
4236                                         declarative_security = new ListDictionary ();
4237                                 }
4238                                 a.ExtractSecurityPermissionSet (declarative_security);
4239                                 return;
4240                         }
4241
4242                         ConstructorBuilder.SetCustomAttribute (cb);
4243                 }
4244                 
4245                 protected override bool CheckForDuplications ()
4246                 {
4247                         ArrayList ar = Parent.InstanceConstructors;
4248                         if (ar != null) {
4249                                 int arLen = ar.Count;
4250                                         
4251                                 for (int i = 0; i < arLen; i++) {
4252                                         Constructor m = (Constructor) ar [i];
4253                                         if (IsDuplicateImplementation (m))
4254                                                 return false;
4255                                 }
4256                         }
4257                         return true;
4258                 }
4259
4260                 protected override bool CheckBase ()
4261                 {
4262                         // Check whether arguments were correct.
4263                         if (!DoDefineParameters ())
4264                                 return false;
4265
4266                         // TODO: skip the rest for generated ctor
4267                         if ((ModFlags & Modifiers.STATIC) != 0)
4268                                 return true;
4269
4270                         if (!CheckForDuplications ())
4271                                 return false;
4272
4273                         if (Parent.Kind == Kind.Struct) {
4274                                 if (ParameterTypes.Length == 0) {
4275                                         Report.Error (568, Location, 
4276                                                 "Structs can not contain explicit parameterless " +
4277                                                 "constructors");
4278                                         return false;
4279                                 }
4280
4281                                 if ((ModFlags & Modifiers.PROTECTED) != 0) {
4282                                         Report.Error (666, Location, "Protected member in struct declaration");
4283                                         return false;
4284                                 }
4285                         }
4286
4287                         if ((RootContext.WarningLevel >= 4) && ((Parent.ModFlags & Modifiers.SEALED) != 0 && (ModFlags & Modifiers.PROTECTED) != 0)) {
4288                                 Report.Warning (628, Location, "'{0}': new protected member declared in sealed class", GetSignatureForError (Parent));
4289                         }
4290                         
4291                         return true;
4292                 }
4293                 
4294                 //
4295                 // Creates the ConstructorBuilder
4296                 //
4297                 public override bool Define ()
4298                 {
4299                         MethodAttributes ca = (MethodAttributes.RTSpecialName |
4300                                                MethodAttributes.SpecialName);
4301                         
4302                         if ((ModFlags & Modifiers.STATIC) != 0) {
4303                                 ca |= MethodAttributes.Static | MethodAttributes.Private;
4304                         } else {
4305                                 ca |= MethodAttributes.HideBySig;
4306
4307                                 if ((ModFlags & Modifiers.PUBLIC) != 0)
4308                                         ca |= MethodAttributes.Public;
4309                                 else if ((ModFlags & Modifiers.PROTECTED) != 0){
4310                                         if ((ModFlags & Modifiers.INTERNAL) != 0)
4311                                                 ca |= MethodAttributes.FamORAssem;
4312                                         else 
4313                                                 ca |= MethodAttributes.Family;
4314                                 } else if ((ModFlags & Modifiers.INTERNAL) != 0)
4315                                         ca |= MethodAttributes.Assembly;
4316                                 else if (IsDefault ())
4317                                         ca |= MethodAttributes.Public;
4318                                 else
4319                                         ca |= MethodAttributes.Private;
4320                         }
4321                         
4322                         // Check if arguments were correct.
4323                         if (!CheckBase ())
4324                                 return false;
4325
4326                         ConstructorBuilder = Parent.TypeBuilder.DefineConstructor (
4327                                 ca, CallingConventions,
4328                                 ParameterTypes);
4329
4330                         if ((ModFlags & Modifiers.UNSAFE) != 0)
4331                                 ConstructorBuilder.InitLocals = false;
4332                         
4333                         TypeManager.AddMethod (ConstructorBuilder, this);
4334
4335                         //
4336                         // HACK because System.Reflection.Emit is lame
4337                         //
4338                         TypeManager.RegisterMethod (ConstructorBuilder, ParameterInfo, ParameterTypes);
4339
4340                         return true;
4341                 }
4342
4343                 //
4344                 // Emits the code
4345                 //
4346                 public override void Emit ()
4347                 {
4348                         EmitContext ec = CreateEmitContext (null, null);
4349
4350                         //
4351                         // extern methods have no bodies
4352                         //
4353                         if ((ModFlags & Modifiers.EXTERN) != 0) {
4354                                 if ((block != null) && ((ModFlags & Modifiers.EXTERN) != 0)) {
4355                                         Report.Error (
4356                                                 179, Location, "External constructor `" +
4357                                                 TypeManager.CSharpSignature (ConstructorBuilder) +
4358                                                 "' can not have a body");
4359                                         return;
4360                                 }
4361                         } else if (block == null) {
4362                                 Report.Error (
4363                                         501, Location, "Constructor `" +
4364                                         TypeManager.CSharpSignature (ConstructorBuilder) +
4365                                         "' must declare a body since it is not marked extern");
4366                                 return;
4367                         }
4368
4369                         // If this is a non-static `struct' constructor and doesn't have any
4370                         // initializer, it must initialize all of the struct's fields.
4371                         if ((Parent.Kind == Kind.Struct) &&
4372                             ((ModFlags & Modifiers.STATIC) == 0) && (Initializer == null))
4373                                 Block.AddThisVariable (Parent, Location);
4374
4375                         if (block != null)
4376                                 block.ResolveMeta (ec, ParameterInfo);
4377
4378                         if ((ModFlags & Modifiers.STATIC) == 0){
4379                                 if (Parent.Kind == Kind.Class && Initializer == null)
4380                                         Initializer = new ConstructorBaseInitializer (
4381                                                 null, Parameters.EmptyReadOnlyParameters, Location);
4382
4383
4384                                 //
4385                                 // Spec mandates that Initializers will not have
4386                                 // `this' access
4387                                 //
4388                                 ec.IsStatic = true;
4389                                 if ((Initializer != null) &&
4390                                     !Initializer.Resolve (ConstructorBuilder, block, ec))
4391                                         return;
4392                                 ec.IsStatic = false;
4393                         }
4394
4395                         Parameters.LabelParameters (ec, ConstructorBuilder);
4396                         
4397                         SourceMethod source = SourceMethod.Create (
4398                                 Parent, ConstructorBuilder, block);
4399
4400                         //
4401                         // Classes can have base initializers and instance field initializers.
4402                         //
4403                         if (Parent.Kind == Kind.Class){
4404                                 if ((ModFlags & Modifiers.STATIC) == 0){
4405
4406                                         //
4407                                         // If we use a "this (...)" constructor initializer, then
4408                                         // do not emit field initializers, they are initialized in the other constructor
4409                                         //
4410                                         if (!(Initializer != null && Initializer is ConstructorThisInitializer))
4411                                                 Parent.EmitFieldInitializers (ec);
4412                                 }
4413                         }
4414                         if (Initializer != null) {
4415                                 if (GetObsoleteAttribute () != null || Parent.GetObsoleteAttribute (Parent) != null)
4416                                         ec.TestObsoleteMethodUsage = false;
4417
4418                                 Initializer.Emit (ec);
4419                         }
4420                         
4421                         if ((ModFlags & Modifiers.STATIC) != 0)
4422                                 Parent.EmitFieldInitializers (ec);
4423
4424                         if (OptAttributes != null) 
4425                                 OptAttributes.Emit (ec, this);
4426
4427                         ec.EmitTopBlock (block, ParameterInfo, Location);
4428
4429                         if (source != null)
4430                                 source.CloseMethod ();
4431
4432                         base.Emit ();
4433
4434                         if (declarative_security != null) {
4435                                 foreach (DictionaryEntry de in declarative_security) {
4436                                         ConstructorBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
4437                                 }
4438                         }
4439
4440                         block = null;
4441                 }
4442
4443                 // Is never override
4444                 protected override MethodInfo FindOutBaseMethod (TypeContainer container, ref Type base_ret_type)
4445                 {
4446                         return null;
4447                 }
4448
4449                 protected override bool VerifyClsCompliance (DeclSpace ds)
4450                 {
4451                         if (!base.VerifyClsCompliance (ds) || !IsExposedFromAssembly (ds)) {
4452                                 return false;
4453                         }
4454                         
4455                         if (parameter_types.Length > 0) {
4456                                 ArrayList al = (ArrayList)ds.MemberCache.Members [".ctor"];
4457                                 if (al.Count > 3)
4458                                         ds.MemberCache.VerifyClsParameterConflict (al, this, ConstructorBuilder);
4459  
4460                                 if (ds.TypeBuilder.IsSubclassOf (TypeManager.attribute_type)) {
4461                                         foreach (Type param in parameter_types) {
4462                                                 if (param.IsArray) {
4463                                                         return true;
4464                                                 }
4465                                         }
4466                                 }
4467                         }
4468                         has_compliant_args = true;
4469                         return true;
4470                 }
4471
4472                 #region IMethodData Members
4473
4474                 public System.Reflection.CallingConventions CallingConventions {
4475                         get {
4476                                 CallingConventions cc = Parameters.GetCallingConvention ();
4477
4478                                 if (Parent.Kind == Kind.Class)
4479                                         if ((ModFlags & Modifiers.STATIC) == 0)
4480                                                 cc |= CallingConventions.HasThis;
4481
4482                                 // FIXME: How is `ExplicitThis' used in C#?
4483                         
4484                                 return cc;
4485                         }
4486                 }
4487
4488                 public new Location Location {
4489                         get {
4490                                 return base.Location;
4491                         }
4492                 }
4493
4494                 public MemberName MethodName {
4495                         get {
4496                                 return MemberName;
4497                         }
4498                 }
4499
4500                 public Type ReturnType {
4501                         get {
4502                                 return MemberType;
4503                         }
4504                 }
4505
4506                 public EmitContext CreateEmitContext (TypeContainer tc, ILGenerator ig)
4507                 {
4508                         ILGenerator ig_ = ConstructorBuilder.GetILGenerator ();
4509                         return new EmitContext (Parent, Location, ig_, null, ModFlags, true);
4510                 }
4511
4512                 public ObsoleteAttribute GetObsoleteAttribute ()
4513                 {
4514                         return GetObsoleteAttribute (Parent);
4515                 }
4516
4517                 public bool IsExcluded(EmitContext ec)
4518                 {
4519                         return false;
4520                 }
4521
4522                 #endregion
4523         }
4524
4525         /// <summary>
4526         /// Interface for MethodData class. Holds links to parent members to avoid member duplication.
4527         /// </summary>
4528         public interface IMethodData
4529         {
4530                 CallingConventions CallingConventions { get; }
4531                 Location Location { get; }
4532                 MemberName MethodName { get; }
4533                 Type[] ParameterTypes { get; }
4534                 Type ReturnType { get; }
4535
4536                 Attributes OptAttributes { get; }
4537                 ToplevelBlock Block { get; }
4538
4539                 EmitContext CreateEmitContext (TypeContainer tc, ILGenerator ig);
4540                 ObsoleteAttribute GetObsoleteAttribute ();
4541                 string GetSignatureForError (TypeContainer tc);
4542                 bool IsExcluded (EmitContext ec);
4543                 bool IsClsCompliaceRequired (DeclSpace ds);
4544                 void SetMemberIsUsed ();
4545         }
4546
4547         //
4548         // Encapsulates most of the Method's state
4549         //
4550         public class MethodData {
4551
4552                 readonly IMethodData method;
4553
4554                 //
4555                 // The return type of this method
4556                 //
4557                 public readonly InternalParameters ParameterInfo;
4558
4559                 //
4560                 // Are we implementing an interface ?
4561                 //
4562                 public bool IsImplementing = false;
4563
4564                 //
4565                 // Protected data.
4566                 //
4567                 protected MemberBase member;
4568                 protected int modifiers;
4569                 protected MethodAttributes flags;
4570
4571                 MethodBuilder builder = null;
4572                 public MethodBuilder MethodBuilder {
4573                         get {
4574                                 return builder;
4575                         }
4576                 }
4577
4578                 public MethodData (MemberBase member, InternalParameters parameters,
4579                                    int modifiers, MethodAttributes flags, IMethodData method)
4580                 {
4581                         this.member = member;
4582                         this.ParameterInfo = parameters;
4583                         this.modifiers = modifiers;
4584                         this.flags = flags;
4585
4586                         this.method = method;
4587                 }
4588
4589                 public bool Define (TypeContainer container)
4590                 {
4591                         MethodInfo implementing = null;
4592
4593                         string name = method.MethodName.Name;
4594                         string method_name = name;
4595
4596                         Type[] ParameterTypes = method.ParameterTypes;
4597
4598                         if (container.Pending != null){
4599                                 if (member is Indexer) // TODO: test it, but it should work without this IF
4600                                         implementing = container.Pending.IsInterfaceIndexer (
4601                                                 member.InterfaceType, method.ReturnType, ParameterInfo);
4602                                 else
4603                                         implementing = container.Pending.IsInterfaceMethod (
4604                                                 member.InterfaceType, name, method.ReturnType, ParameterInfo);
4605
4606                                 if (member.InterfaceType != null){
4607                                         if (implementing == null){
4608                                                 if (member is PropertyBase) {
4609                                                         Report.Error (550, method.Location, "'{0}' is an accessor not found in interface member '{1}'",
4610                                                                 method.GetSignatureForError (container), member.Name);
4611
4612                                                 } else {
4613                                                         Report.Error (539, method.Location,
4614                                                                 "'{0}' in explicit interface declaration is not a member of interface", member.GetSignatureForError () );
4615                                                 }
4616                                                 return false;
4617                                         }
4618                                         if (implementing.IsSpecialName && !((member is PropertyBase || member is EventProperty))) {
4619                                                 Report.SymbolRelatedToPreviousError (implementing);
4620                                                 Report.Error (683, method.Location, "'{0}' explicit method implementation cannot implement '{1}' because it is an accessor",
4621                                                         member.GetSignatureForError (), TypeManager.CSharpSignature (implementing));
4622                                                 return false;
4623                                         }
4624                                         method_name = member.InterfaceType.FullName + "." + name;
4625                                 } else {
4626                                         if (implementing != null && method is AbstractPropertyEventMethod && !implementing.IsSpecialName) {
4627                                                 Report.SymbolRelatedToPreviousError (implementing);
4628                                                 Report.Error (686, method.Location, "Accessor '{0}' cannot implement interface member '{1}' for type '{2}'. Use an explicit interface implementation",
4629                                                         method.GetSignatureForError (container), TypeManager.CSharpSignature (implementing), container.GetSignatureForError ());
4630                                                 return false;
4631                                         }
4632                                 }
4633                         }
4634
4635                         //
4636                         // For implicit implementations, make sure we are public, for
4637                         // explicit implementations, make sure we are private.
4638                         //
4639                         if (implementing != null){
4640                                 //
4641                                 // Setting null inside this block will trigger a more
4642                                 // verbose error reporting for missing interface implementations
4643                                 //
4644                                 // The "candidate" function has been flagged already
4645                                 // but it wont get cleared
4646                                 //
4647                                 if (member.IsExplicitImpl){
4648                                         if ((modifiers & (Modifiers.PUBLIC | Modifiers.ABSTRACT | Modifiers.VIRTUAL)) != 0){
4649                                                 Modifiers.Error_InvalidModifier (method.Location, "public, virtual or abstract");
4650                                                 implementing = null;
4651                                         }
4652                                 } else if ((flags & MethodAttributes.MemberAccessMask) != MethodAttributes.Public){
4653                                         if (TypeManager.IsInterfaceType (implementing.DeclaringType)){
4654                                                 //
4655                                                 // If this is an interface method implementation,
4656                                                 // check for public accessibility
4657                                                 //
4658                                                 implementing = null;
4659                                         } else if ((flags & MethodAttributes.MemberAccessMask) == MethodAttributes.Private){
4660                                                 // We may never be private.
4661                                                 implementing = null;
4662                                         } else if ((modifiers & Modifiers.OVERRIDE) == 0){
4663                                                 //
4664                                                 // We may be protected if we're overriding something.
4665                                                 //
4666                                                 implementing = null;
4667                                         }
4668                                 } 
4669                                         
4670                                 //
4671                                 // Static is not allowed
4672                                 //
4673                                 if ((modifiers & Modifiers.STATIC) != 0){
4674                                         implementing = null;
4675                                         Modifiers.Error_InvalidModifier (method.Location, "static");
4676                                 }
4677                         }
4678                         
4679                         //
4680                         // If implementing is still valid, set flags
4681                         //
4682                         if (implementing != null){
4683                                 //
4684                                 // When implementing interface methods, set NewSlot
4685                                 // unless, we are overwriting a method.
4686                                 //
4687                                 if (implementing.DeclaringType.IsInterface){
4688                                         if ((modifiers & Modifiers.OVERRIDE) == 0)
4689                                                 flags |= MethodAttributes.NewSlot;
4690                                 }
4691                                 flags |=
4692                                         MethodAttributes.Virtual |
4693                                         MethodAttributes.HideBySig;
4694
4695                                 // Set Final unless we're virtual, abstract or already overriding a method.
4696                                 if ((modifiers & (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE)) == 0)
4697                                         flags |= MethodAttributes.Final;
4698
4699                                 IsImplementing = true;
4700                         }
4701
4702                         EmitContext ec = method.CreateEmitContext (container, null);
4703
4704                         DefineMethodBuilder (ec, container, method_name, ParameterTypes);
4705
4706                         if (builder == null)
4707                                 return false;
4708
4709                         if ((modifiers & Modifiers.UNSAFE) != 0)
4710                                 builder.InitLocals = false;
4711
4712                         if (IsImplementing){
4713                                 //
4714                                 // clear the pending implemntation flag
4715                                 //
4716                                 if (member is Indexer) {
4717                                         container.Pending.ImplementIndexer (
4718                                                 member.InterfaceType, builder, method.ReturnType,
4719                                                 ParameterInfo, member.IsExplicitImpl);
4720                                 } else
4721                                         container.Pending.ImplementMethod (
4722                                                 member.InterfaceType, name, method.ReturnType,
4723                                                 ParameterInfo, member.IsExplicitImpl);
4724
4725                                 if (member.IsExplicitImpl)
4726                                         container.TypeBuilder.DefineMethodOverride (
4727                                                 builder, implementing);
4728
4729                         }
4730
4731                         TypeManager.RegisterMethod (builder, ParameterInfo, ParameterTypes);
4732                         TypeManager.AddMethod (builder, method);
4733
4734                         return true;
4735                 }
4736
4737
4738                 /// <summary>
4739                 /// Create the MethodBuilder for the method 
4740                 /// </summary>
4741                 void DefineMethodBuilder (EmitContext ec, TypeContainer container, string method_name, Type[] ParameterTypes)
4742                 {
4743                         const int extern_static = Modifiers.EXTERN | Modifiers.STATIC;
4744
4745                         if ((modifiers & extern_static) == extern_static) {
4746
4747                                 if (method.OptAttributes != null) {
4748                                         Attribute dllimport_attribute = method.OptAttributes.Search (TypeManager.dllimport_type, ec);
4749                                         if (dllimport_attribute != null) {
4750                                                 flags |= MethodAttributes.PinvokeImpl;
4751                                                 builder = dllimport_attribute.DefinePInvokeMethod (
4752                                                         ec, container.TypeBuilder, method_name, flags,
4753                                                         method.ReturnType, ParameterTypes);
4754
4755                                                 return;
4756                                         }
4757                                 }
4758
4759                                 // for extern static method must be specified either DllImport attribute or MethodImplAttribute.
4760                                 // We are more strict than Microsoft and report CS0626 like error
4761                                 if (method.OptAttributes == null ||
4762                                         !method.OptAttributes.Contains (TypeManager.methodimpl_attr_type, ec)) {
4763                                         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));
4764                                         return;
4765                                 }
4766                         }
4767
4768                         builder = container.TypeBuilder.DefineMethod (
4769                                 method_name, flags, method.CallingConventions,
4770                                 method.ReturnType, ParameterTypes);
4771                 }
4772
4773                 //
4774                 // Emits the code
4775                 // 
4776                 public void Emit (TypeContainer container, Attributable kind)
4777                 {
4778                         EmitContext ec;
4779                         if ((flags & MethodAttributes.PinvokeImpl) == 0)
4780                                 ec = method.CreateEmitContext (container, builder.GetILGenerator ());
4781                         else
4782                                 ec = method.CreateEmitContext (container, null);
4783
4784                         if (method.GetObsoleteAttribute () != null || container.GetObsoleteAttribute (container) != null)
4785                                 ec.TestObsoleteMethodUsage = false;
4786
4787                         Location loc = method.Location;
4788                         Attributes OptAttributes = method.OptAttributes;
4789
4790                         if (OptAttributes != null)
4791                                 OptAttributes.Emit (ec, kind);
4792
4793                         if (member is MethodCore)
4794                                 ((MethodCore) member).Parameters.LabelParameters (ec, MethodBuilder);
4795
4796                         ToplevelBlock block = method.Block;
4797                         
4798                         //
4799                         // abstract or extern methods have no bodies
4800                         //
4801                         if ((modifiers & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0){
4802                                 if (block == null)
4803                                         return;
4804
4805                                 //
4806                                 // abstract or extern methods have no bodies.
4807                                 //
4808                                 if ((modifiers & Modifiers.ABSTRACT) != 0)
4809                                         Report.Error (
4810                                                 500, method.Location, "Abstract method `" +
4811                                                 TypeManager.CSharpSignature (builder) +
4812                                                 "' can not have a body");
4813
4814                                 if ((modifiers & Modifiers.EXTERN) != 0)
4815                                         Report.Error (
4816                                                 179, method.Location, "External method `" +
4817                                                 TypeManager.CSharpSignature (builder) +
4818                                                 "' can not have a body");
4819
4820                                 return;
4821                         }
4822
4823                         //
4824                         // Methods must have a body unless they're extern or abstract
4825                         //
4826                         if (block == null) {
4827                                 Report.Error (
4828                                         501, method.Location, "Method `" +
4829                                         TypeManager.CSharpSignature (builder) +
4830                                         "' must declare a body since it is not marked " +
4831                                         "abstract or extern");
4832                                 return;
4833                         }
4834
4835                         SourceMethod source = SourceMethod.Create (
4836                                 container, MethodBuilder, method.Block);
4837
4838                         //
4839                         // Handle destructors specially
4840                         //
4841                         // FIXME: This code generates buggy code
4842                         //
4843                         if (member is Destructor)
4844                                 EmitDestructor (ec, block);
4845                         else
4846                                 ec.EmitTopBlock (block, ParameterInfo, loc);
4847
4848                         if (source != null)
4849                                 source.CloseMethod ();
4850                 }
4851
4852                 void EmitDestructor (EmitContext ec, ToplevelBlock block)
4853                 {
4854                         ILGenerator ig = ec.ig;
4855                         
4856                         Label finish = ig.DefineLabel ();
4857
4858                         block.SetDestructor ();
4859                         
4860                         ig.BeginExceptionBlock ();
4861                         ec.ReturnLabel = finish;
4862                         ec.HasReturnLabel = true;
4863                         ec.EmitTopBlock (block, null, method.Location);
4864                         
4865                         // ig.MarkLabel (finish);
4866                         ig.BeginFinallyBlock ();
4867                         
4868                         if (ec.ContainerType.BaseType != null) {
4869                                 Expression member_lookup = Expression.MemberLookup (
4870                                         ec, ec.ContainerType.BaseType, null, ec.ContainerType.BaseType,
4871                                         "Finalize", MemberTypes.Method, Expression.AllBindingFlags, method.Location);
4872
4873                                 if (member_lookup != null){
4874                                         MethodGroupExpr base_destructor = ((MethodGroupExpr) member_lookup);
4875                                 
4876                                         ig.Emit (OpCodes.Ldarg_0);
4877                                         ig.Emit (OpCodes.Call, (MethodInfo) base_destructor.Methods [0]);
4878                                 }
4879                         }
4880                         
4881                         ig.EndExceptionBlock ();
4882                         //ig.MarkLabel (ec.ReturnLabel);
4883                         ig.Emit (OpCodes.Ret);
4884                 }
4885         }
4886
4887         // Should derive from MethodCore
4888         public class Destructor : Method {
4889
4890                 public Destructor (TypeContainer ds, Expression return_type, int mod,
4891                                    string name, Parameters parameters, Attributes attrs,
4892                                    Location l)
4893                         : base (ds, return_type, mod, false, new MemberName (name),
4894                                 parameters, attrs, l)
4895                 { }
4896
4897                 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
4898                 {
4899                         if (a.Type == TypeManager.conditional_attribute_type) {
4900                                 Report.Error (577, Location, "Conditional not valid on '{0}' because it is a destructor, operator, or explicit interface implementation", GetSignatureForError ());
4901                                 return;
4902                         }
4903
4904                         base.ApplyAttributeBuilder (a, cb);
4905                 }
4906         }
4907         
4908         abstract public class MemberBase : MemberCore {
4909                 public Expression Type;
4910
4911                 public MethodAttributes flags;
4912                         
4913                 protected readonly int explicit_mod_flags;
4914
4915                 //
4916                 // The "short" name of this property / indexer / event.  This is the
4917                 // name without the explicit interface.
4918                 //
4919                 public string ShortName {
4920                         get { return MemberName.Name; }
4921                         set {
4922                                 SetMemberName (new MemberName (MemberName.Left, value));
4923                         }
4924                 }
4925
4926                 //
4927                 // The type of this property / indexer / event
4928                 //
4929                 Type member_type;
4930                 public Type MemberType {
4931                         get {
4932                                 if (member_type == null && Type != null) {
4933                                         EmitContext ec = Parent.EmitContext;
4934                                         bool old_unsafe = ec.InUnsafe;
4935                                         ec.InUnsafe = InUnsafe;
4936                                         Type = Type.ResolveAsTypeTerminal (ec, false);
4937                                         ec.InUnsafe = old_unsafe;
4938
4939                                         member_type = Type == null ? null : Type.Type;
4940                                 }
4941                                 return member_type;
4942                         }
4943                 }
4944
4945                 //
4946                 // Whether this is an interface member.
4947                 //
4948                 public bool IsInterface;
4949
4950                 //
4951                 // If true, this is an explicit interface implementation
4952                 //
4953                 public bool IsExplicitImpl;
4954
4955                 //
4956                 // The interface type we are explicitly implementing
4957                 //
4958                 public Type InterfaceType = null;
4959
4960                 //
4961                 // The constructor is only exposed to our children
4962                 //
4963                 protected MemberBase (TypeContainer parent, Expression type, int mod,
4964                                       int allowed_mod, int def_mod, MemberName name,
4965                                       Attributes attrs, Location loc)
4966                         : base (parent, name, attrs, loc)
4967                 {
4968                         explicit_mod_flags = mod;
4969                         Type = type;
4970                         ModFlags = Modifiers.Check (allowed_mod, mod, def_mod, loc);
4971                         IsExplicitImpl = (MemberName.Left != null);
4972                 }
4973
4974                 protected virtual bool CheckBase ()
4975                 {
4976                         if ((ModFlags & Modifiers.PROTECTED) != 0 && Parent.Kind == Kind.Struct) {
4977                                 Report.Error (666, Location, "Protected member in struct declaration");
4978                                 return false;
4979                         }
4980    
4981                         if ((RootContext.WarningLevel >= 4) &&
4982                             ((Parent.ModFlags & Modifiers.SEALED) != 0) &&
4983                             ((ModFlags & Modifiers.PROTECTED) != 0) &&
4984                             ((ModFlags & Modifiers.OVERRIDE) == 0) && (Name != "Finalize")) {
4985                                 Report.Warning (628, Location, "'{0}': new protected member declared in sealed class", GetSignatureForError (Parent));
4986                         }
4987                         return true;
4988                 }
4989
4990                 protected virtual bool CheckParameters (DeclSpace ds, Type [] parameters)
4991                 {
4992                         bool error = false;
4993
4994                         foreach (Type partype in parameters){
4995                                 if (partype == TypeManager.void_type) {
4996                                         Report.Error (
4997                                                 1547, Location, "Keyword 'void' cannot " +
4998                                                 "be used in this context");
4999                                         return false;
5000                                 }
5001
5002                                 if (partype.IsPointer){
5003                                         if (!UnsafeOK (ds))
5004                                                 error = true;
5005                                         if (!TypeManager.VerifyUnManaged (TypeManager.GetElementType (partype), Location))
5006                                                 error = true;
5007                                 }
5008
5009                                 if (ds.AsAccessible (partype, ModFlags))
5010                                         continue;
5011
5012                                 if (this is Indexer)
5013                                         Report.Error (55, Location,
5014                                                       "Inconsistent accessibility: parameter type `" +
5015                                                       TypeManager.CSharpName (partype) + "' is less " +
5016                                                       "accessible than indexer `" + Name + "'");
5017                                 else if ((this is Method) && ((Method) this).IsOperator)
5018                                         Report.Error (57, Location,
5019                                                       "Inconsistent accessibility: parameter type `" +
5020                                                       TypeManager.CSharpName (partype) + "' is less " +
5021                                                       "accessible than operator `" + Name + "'");
5022                                 else
5023                                         Report.Error (51, Location,
5024                                                       "Inconsistent accessibility: parameter type `" +
5025                                                       TypeManager.CSharpName (partype) + "' is less " +
5026                                                       "accessible than method `" + Name + "'");
5027                                 error = true;
5028                         }
5029
5030                         return !error;
5031                 }
5032
5033                 protected virtual bool DoDefine ()
5034                 {
5035                         EmitContext ec = Parent.EmitContext;
5036                         if (ec == null)
5037                                 throw new InternalErrorException ("MemberBase.DoDefine called too early");
5038
5039                         if (Name == null)
5040                                 throw new InternalErrorException ();
5041
5042                         if (IsInterface) {
5043                                 ModFlags = Modifiers.PUBLIC |
5044                                         Modifiers.ABSTRACT |
5045                                         Modifiers.VIRTUAL | (ModFlags & Modifiers.UNSAFE) | (ModFlags & Modifiers.NEW);
5046
5047                                 flags = MethodAttributes.Public |
5048                                         MethodAttributes.Abstract |
5049                                         MethodAttributes.HideBySig |
5050                                         MethodAttributes.NewSlot |
5051                                         MethodAttributes.Virtual;
5052                         } else {
5053                                 if (!Parent.MethodModifiersValid (this))
5054                                         return false;
5055
5056                                 flags = Modifiers.MethodAttr (ModFlags);
5057                         }
5058
5059                         if (MemberType == null)
5060                                 return false;
5061
5062                         if ((Parent.ModFlags & Modifiers.SEALED) != 0){
5063                                 if ((ModFlags & (Modifiers.VIRTUAL|Modifiers.ABSTRACT)) != 0){
5064                                         Report.Error (549, Location, "Virtual method can not be contained in sealed class");
5065                                         return false;
5066                                 }
5067                         }
5068                         
5069                         // verify accessibility
5070                         if (!Parent.AsAccessible (MemberType, ModFlags)) {
5071                                 Report.SymbolRelatedToPreviousError (MemberType);
5072                                 if (this is Property)
5073                                         Report.Error (53, Location,
5074                                                       "Inconsistent accessibility: property type `" +
5075                                                       TypeManager.CSharpName (MemberType) + "' is less " +
5076                                                       "accessible than property `" + GetSignatureForError () + "'");
5077                                 else if (this is Indexer)
5078                                         Report.Error (54, Location,
5079                                                       "Inconsistent accessibility: indexer return type `" +
5080                                                       TypeManager.CSharpName (MemberType) + "' is less " +
5081                                                       "accessible than indexer `" + Name + "'");
5082                                 else if (this is MethodCore) {
5083                                         if (this is Operator)
5084                                                 Report.Error (56, Location,
5085                                                               "Inconsistent accessibility: return type `" +
5086                                                               TypeManager.CSharpName (MemberType) + "' is less " +
5087                                                               "accessible than operator `" + Name + "'");
5088                                         else
5089                                                 Report.Error (50, Location,
5090                                                               "Inconsistent accessibility: return type `" +
5091                                                               TypeManager.CSharpName (MemberType) + "' is less " +
5092                                                               "accessible than method `" + Name + "'");
5093                                 } else {
5094                                         Report.Error (52, Location,
5095                                                       "Inconsistent accessibility: field type `" +
5096                                                       TypeManager.CSharpName (MemberType) + "' is less " +
5097                                                       "accessible than field `" + Name + "'");
5098                                 }
5099                                 return false;
5100                         }
5101
5102                         if (MemberType.IsPointer && !UnsafeOK (Parent))
5103                                 return false;
5104
5105                         if (IsExplicitImpl) {
5106                                 Expression expr = MemberName.Left.GetTypeExpression (Location);
5107                                 TypeExpr texpr = expr.ResolveAsTypeTerminal (ec, false);
5108                                 if (texpr == null)
5109                                         return false;
5110
5111                                 InterfaceType = texpr.ResolveType (ec);
5112
5113                                 if (!InterfaceType.IsInterface) {
5114                                         Report.Error (538, Location, "'{0}' in explicit interface declaration is not an interface", TypeManager.CSharpName (InterfaceType));
5115                                         return false;
5116                                 }
5117                                 
5118                                 if (!Parent.VerifyImplements (InterfaceType, ShortName, Name, Location))
5119                                         return false;
5120                                 
5121                                 Modifiers.Check (Modifiers.AllowedExplicitImplFlags, explicit_mod_flags, 0, Location);
5122                                 
5123                         }
5124                         return true;
5125                 }
5126
5127                 public override string GetSignatureForError (TypeContainer tc)
5128                 {
5129                         return String.Concat (tc.Name, '.', base.GetSignatureForError (tc));
5130                 }
5131
5132                 protected bool IsTypePermitted ()
5133                 {
5134                         if (MemberType == TypeManager.arg_iterator_type || MemberType == TypeManager.typed_reference_type) {
5135                                 Report.Error (610, Location, "Field or property cannot be of type '{0}'", TypeManager.CSharpName (MemberType));
5136                                 return false;
5137                         }
5138                         return true;
5139                 }
5140
5141                 protected override bool VerifyClsCompliance(DeclSpace ds)
5142                 {
5143                         if (base.VerifyClsCompliance (ds)) {
5144                                 return true;
5145                         }
5146
5147                         if (IsInterface && HasClsCompliantAttribute && ds.IsClsCompliaceRequired (ds)) {
5148                                 Report.Error (3010, Location, "'{0}': CLS-compliant interfaces must have only CLS-compliant members", GetSignatureForError ());
5149                         }
5150                         return false;
5151                 }
5152
5153                 protected override void VerifyObsoleteAttribute()
5154                 {
5155                         CheckUsageOfObsoleteAttribute (MemberType);
5156                 }
5157         }
5158
5159         //
5160         // Fields and Events both generate FieldBuilders, we use this to share 
5161         // their common bits.  This is also used to flag usage of the field
5162         //
5163         abstract public class FieldBase : MemberBase {
5164                 public FieldBuilder  FieldBuilder;
5165                 public Status status;
5166
5167                 [Flags]
5168                 public enum Status : byte {
5169                         ASSIGNED = 1,
5170                         HAS_OFFSET = 4          // Used by FieldMember.
5171                 }
5172
5173                 static string[] attribute_targets = new string [] { "field" };
5174
5175                 /// <summary>
5176                 ///  Symbol with same name in base class/struct
5177                 /// </summary>
5178                 public MemberInfo conflict_symbol;
5179
5180                 //
5181                 // The constructor is only exposed to our children
5182                 //
5183                 protected FieldBase (TypeContainer parent, Expression type, int mod,
5184                                      int allowed_mod, MemberName name, object init,
5185                                      Attributes attrs, Location loc)
5186                         : base (parent, type, mod, allowed_mod, Modifiers.PRIVATE,
5187                                 name, attrs, loc)
5188                 {
5189                         this.init = init;
5190                 }
5191
5192                 public override AttributeTargets AttributeTargets {
5193                         get {
5194                                 return AttributeTargets.Field;
5195                         }
5196                 }
5197
5198                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
5199                 {
5200                         if (a.Type == TypeManager.marshal_as_attr_type) {
5201                                 UnmanagedMarshal marshal = a.GetMarshal (this);
5202                                 if (marshal != null) {
5203                                         FieldBuilder.SetMarshal (marshal);
5204                                 }
5205                                 return;
5206                         }
5207
5208                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
5209                                 a.Error_InvalidSecurityParent ();
5210                                 return;
5211                         }
5212
5213                         FieldBuilder.SetCustomAttribute (cb);
5214                 }
5215
5216                 //
5217                 // Whether this field has an initializer.
5218                 //
5219                 public bool HasInitializer {
5220                         get {
5221                                 return init != null;
5222                         }
5223                 }
5224
5225                 protected readonly Object init;
5226
5227                 // Private.
5228                 Expression init_expr;
5229                 bool init_expr_initialized = false;
5230
5231                 //
5232                 // Resolves and returns the field initializer.
5233                 //
5234                 public Expression GetInitializerExpression (EmitContext ec)
5235                 {
5236                         if (init_expr_initialized)
5237                                 return init_expr;
5238
5239                         Expression e;
5240                         if (init is Expression)
5241                                 e = (Expression) init;
5242                         else
5243                                 e = new ArrayCreation (Type, "", (ArrayList)init, Location);
5244
5245                         EmitContext parent_ec = Parent.EmitContext;
5246
5247                         bool old_is_static = parent_ec.IsStatic;
5248                         parent_ec.IsStatic = ec.IsStatic;
5249                         parent_ec.IsFieldInitializer = true;
5250                         e = e.DoResolve (parent_ec);
5251                         parent_ec.IsFieldInitializer = false;
5252                         parent_ec.IsStatic = old_is_static;
5253
5254                         init_expr = e;
5255                         init_expr_initialized = true;
5256
5257                         return init_expr;
5258                 }
5259
5260                 protected override bool CheckBase ()
5261                 {
5262                         if (!base.CheckBase ())
5263                                 return false;
5264  
5265                         // TODO: Implement
5266                         if (IsInterface)
5267                                 return true;
5268  
5269                         conflict_symbol = Parent.FindBaseMemberWithSameName (Name, false);
5270                         if (conflict_symbol == null) {
5271                                 if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0)) {
5272                                         Report.Warning (109, Location, "The member '{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError (Parent));
5273                                 }
5274                                 return true;
5275                         }
5276  
5277                         if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE)) == 0) {
5278                                 Report.SymbolRelatedToPreviousError (conflict_symbol);
5279                                 Report.Warning (108, Location, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError (Parent));
5280                         }
5281  
5282                         return true;
5283                 }
5284
5285                 public override string GetSignatureForError ()
5286                 {
5287                         if (FieldBuilder == null) {
5288                                 return base.GetSignatureForError (Parent);
5289                         }
5290                         return TypeManager.GetFullNameSignature (FieldBuilder);
5291                 }
5292
5293                 protected virtual bool IsFieldClsCompliant {
5294                         get {
5295                                 if (FieldBuilder == null)
5296                                         return true;
5297
5298                                 return AttributeTester.IsClsCompliant (FieldBuilder.FieldType);
5299                         }
5300                 }
5301
5302                 public override string[] ValidAttributeTargets {
5303                         get {
5304                                 return attribute_targets;
5305                         }
5306                 }
5307
5308                 protected override bool VerifyClsCompliance (DeclSpace ds)
5309                 {
5310                         if (!base.VerifyClsCompliance (ds))
5311                                 return false;
5312
5313                         if (!IsFieldClsCompliant) {
5314                                 Report.Error (3003, Location, "Type of '{0}' is not CLS-compliant", GetSignatureForError ());
5315                         }
5316                         return true;
5317                 }
5318
5319
5320                 public void SetAssigned ()
5321                 {
5322                         status |= Status.ASSIGNED;
5323                 }
5324         }
5325
5326         public abstract class FieldMember: FieldBase
5327         {
5328                 protected FieldMember (TypeContainer parent, Expression type, int mod,
5329                         int allowed_mod, MemberName name, object init, Attributes attrs, Location loc)
5330                         : base (parent, type, mod, allowed_mod | Modifiers.ABSTRACT, name, init, attrs, loc)
5331                 {
5332                         if ((mod & Modifiers.ABSTRACT) != 0)
5333                                 Report.Error (681, loc, "The modifier 'abstract' is not valid on fields. Try using a property instead");
5334                 }
5335
5336                 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
5337                 {
5338                         if (a.Type == TypeManager.field_offset_attribute_type)
5339                         {
5340                                 status |= Status.HAS_OFFSET;
5341
5342                                 if (!Parent.HasExplicitLayout) {
5343                                         Report.Error (636, Location, "The FieldOffset attribute can only be placed on members of types marked with the StructLayout(LayoutKind.Explicit)");
5344                                         return;
5345                                 }
5346
5347                                 if ((ModFlags & Modifiers.STATIC) != 0 || this is Const) {
5348                                         Report.Error (637, Location, "The FieldOffset attribute is not allowed on static or const fields");
5349                                         return;
5350                                 }
5351                         }
5352
5353 #if NET_2_0
5354                         if (a.Type == TypeManager.fixed_buffer_attr_type) {
5355                                 Report.Error (1716, Location, "Do not use 'System.Runtime.CompilerServices.FixedBuffer' attribute. Use the 'fixed' field modifier instead");
5356                                 return;
5357                         }
5358 #endif
5359
5360                         base.ApplyAttributeBuilder (a, cb);
5361                 }
5362
5363
5364                 public override bool Define()
5365                 {
5366                         EmitContext ec = Parent.EmitContext;
5367                         if (ec == null)
5368                                 throw new InternalErrorException ("FieldMember.Define called too early");
5369
5370                         if (MemberType == null)
5371                                 return false;
5372
5373                         if (MemberType == TypeManager.void_type) {
5374                                 Report.Error (1547, Location, "Keyword 'void' cannot be used in this context");
5375                                 return false;
5376                         }
5377
5378                         if (!CheckBase ())
5379                                 return false;
5380                         
5381                         if (!Parent.AsAccessible (MemberType, ModFlags)) {
5382                                 Report.Error (52, Location,
5383                                         "Inconsistent accessibility: field type `" +
5384                                         TypeManager.CSharpName (MemberType) + "' is less " +
5385                                         "accessible than field `" + Name + "'");
5386                                 return false;
5387                         }
5388
5389                         if (!IsTypePermitted ())
5390                                 return false;
5391
5392                         if (MemberType.IsPointer && !UnsafeOK (Parent))
5393                                 return false;
5394
5395                         return true;
5396                 }
5397
5398                 public override void Emit ()
5399                 {
5400                         if (OptAttributes != null) {
5401                                 EmitContext ec = new EmitContext (Parent, Location, null, FieldBuilder.FieldType, ModFlags);
5402                                 OptAttributes.Emit (ec, this);
5403                         }
5404
5405                         if (Parent.HasExplicitLayout && ((status & Status.HAS_OFFSET) == 0) && (ModFlags & Modifiers.STATIC) == 0) {
5406                                 Report.Error (625, Location, "'{0}': Instance field types marked with StructLayout(LayoutKind.Explicit) must have a FieldOffset attribute.", GetSignatureForError ());
5407                         }
5408
5409                         base.Emit ();
5410                 }
5411
5412                 //
5413                 //   Represents header string for documentation comment.
5414                 //
5415                 public override string DocCommentHeader {
5416                         get { return "F:"; }
5417                 }
5418         }
5419
5420         interface IFixedBuffer
5421         {
5422                 FieldInfo Element { get; }
5423                 Type ElementType { get; }
5424         }
5425
5426         public class FixedFieldExternal: IFixedBuffer
5427         {
5428                 FieldInfo element_field;
5429
5430                 public FixedFieldExternal (FieldInfo fi)
5431                 {
5432                         element_field = fi.FieldType.GetField (FixedField.FixedElementName);
5433                 }
5434
5435                 #region IFixedField Members
5436
5437                 public FieldInfo Element {
5438                         get {
5439                                 return element_field;
5440                         }
5441                 }
5442
5443                 public Type ElementType {
5444                         get {
5445                                 return element_field.FieldType;
5446                         }
5447                 }
5448
5449                 #endregion
5450         }
5451
5452         /// <summary>
5453         /// Fixed buffer implementation
5454         /// </summary>
5455         public class FixedField: FieldMember, IFixedBuffer
5456         {
5457                 public const string FixedElementName = "FixedElementField";
5458                 static int GlobalCounter = 0;
5459                 static object[] ctor_args = new object[] { (short)LayoutKind.Sequential };
5460                 static FieldInfo[] fi;
5461
5462                 TypeBuilder fixed_buffer_type;
5463                 FieldBuilder element;
5464                 Expression size_expr;
5465                 int buffer_size;
5466
5467                 const int AllowedModifiers =
5468                         Modifiers.NEW |
5469                         Modifiers.PUBLIC |
5470                         Modifiers.PROTECTED |
5471                         Modifiers.INTERNAL |
5472                         Modifiers.PRIVATE;
5473
5474                 public FixedField (TypeContainer parent, Expression type, int mod, string name,
5475                         Expression size_expr, Attributes attrs, Location loc):
5476                         base (parent, type, mod, AllowedModifiers, new MemberName (name), null, attrs, loc)
5477                 {
5478                         if (RootContext.Version == LanguageVersion.ISO_1)
5479                                 Report.FeatureIsNotStandardized (loc, "fixed sized buffers");
5480
5481                         this.size_expr = size_expr;
5482                 }
5483
5484                 public override bool Define()
5485                 {
5486 #if !NET_2_0
5487                         if ((ModFlags & (Modifiers.PUBLIC | Modifiers.PROTECTED)) != 0)
5488                                 Report.Warning (-23, Location, "Only private or internal fixed sized buffers are supported by .NET 1.x");
5489 #endif
5490
5491                         if (Parent.Kind != Kind.Struct) {
5492                                 Report.Error (1642, Location, "Fixed buffer fields may only be members of structs");
5493                                 return false;
5494                         }
5495
5496                         if (!base.Define ())
5497                                 return false;
5498
5499                         if (!TypeManager.IsPrimitiveType (MemberType)) {
5500                                 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");
5501                                 return false;
5502                         }
5503
5504                         Expression e = size_expr.Resolve (Parent.EmitContext);
5505                         if (e == null)
5506                                 return false;
5507
5508                         Constant c = e as Constant;
5509                         if (c == null) {
5510                                 Report.Error (133, Location, "The expression being assigned to '{0}' must be constant", GetSignatureForError ());
5511                                 return false;
5512                         }
5513
5514                         IntConstant buffer_size_const = c.ToInt (Location);
5515                         if (buffer_size_const == null)
5516                                 return false;
5517
5518                         buffer_size = buffer_size_const.Value;
5519
5520                         if (buffer_size <= 0) {
5521                                 Report.Error (1665, Location, "Fixed sized buffer '{0}' must have a length greater than zero", GetSignatureForError ());
5522                                 return false;
5523                         }
5524
5525                         int type_size = Expression.GetTypeSize (MemberType);
5526
5527                         if (buffer_size > int.MaxValue / type_size) {
5528                                 Report.Error (1664, Location, "Fixed sized buffer of length '{0}' and type '{1}' exceeded 2^31 limit",
5529                                         buffer_size.ToString (), TypeManager.CSharpName (MemberType));
5530                                 return false;
5531                         }
5532
5533                         buffer_size *= type_size;
5534
5535                         // Define nested
5536                         string name = String.Format ("<{0}>__FixedBuffer{1}", Name, GlobalCounter++);
5537
5538                         fixed_buffer_type = Parent.TypeBuilder.DefineNestedType (name,
5539                                 TypeAttributes.NestedPublic | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit, TypeManager.value_type);
5540                         element = fixed_buffer_type.DefineField (FixedElementName, MemberType, FieldAttributes.Public);
5541                         RootContext.RegisterCompilerGeneratedType (fixed_buffer_type);
5542
5543                         FieldBuilder = Parent.TypeBuilder.DefineField (Name, fixed_buffer_type, Modifiers.FieldAttr (ModFlags));
5544                         TypeManager.RegisterFieldBase (FieldBuilder, this);
5545
5546                         return true;
5547                 }
5548
5549                 public override void Emit()
5550                 {
5551                         if (fi == null)
5552                                 fi = new FieldInfo [] { TypeManager.struct_layout_attribute_type.GetField ("Size") };
5553
5554                         object[] fi_val = new object[1];
5555                         fi_val [0] = buffer_size;
5556
5557                         CustomAttributeBuilder cab = new CustomAttributeBuilder (TypeManager.struct_layout_attribute_ctor, 
5558                                 ctor_args, fi, fi_val);
5559                         fixed_buffer_type.SetCustomAttribute (cab);
5560
5561 #if NET_2_0
5562                         cab = new CustomAttributeBuilder (TypeManager.fixed_buffer_attr_ctor, new object[] { MemberType, buffer_size } );
5563                         FieldBuilder.SetCustomAttribute (cab);
5564 #endif
5565                         base.Emit ();
5566                 }
5567
5568                 protected override bool IsFieldClsCompliant {
5569                         get {
5570                                 return false;
5571                         }
5572                 }
5573
5574                 #region IFixedField Members
5575
5576                 public FieldInfo Element {
5577                         get {
5578                                 return element;
5579                         }
5580                 }
5581
5582                 public Type ElementType {
5583                         get {
5584                                 return MemberType;
5585                         }
5586                 }
5587
5588                 #endregion
5589         }
5590
5591         //
5592         // The Field class is used to represents class/struct fields during parsing.
5593         //
5594         public class Field : FieldMember {
5595                 // <summary>
5596                 //   Modifiers allowed in a class declaration
5597                 // </summary>
5598                 const int AllowedModifiers =
5599                         Modifiers.NEW |
5600                         Modifiers.PUBLIC |
5601                         Modifiers.PROTECTED |
5602                         Modifiers.INTERNAL |
5603                         Modifiers.PRIVATE |
5604                         Modifiers.STATIC |
5605                         Modifiers.VOLATILE |
5606                         Modifiers.UNSAFE |
5607                         Modifiers.READONLY;
5608
5609                 public Field (TypeContainer parent, Expression type, int mod, string name,
5610                               Object expr_or_array_init, Attributes attrs, Location loc)
5611                         : base (parent, type, mod, AllowedModifiers, new MemberName (name),
5612                                 expr_or_array_init, attrs, loc)
5613                 {
5614                 }
5615
5616                 public override bool Define ()
5617                 {
5618                         if (!base.Define ())
5619                                 return false;
5620
5621                         if (RootContext.WarningLevel > 1){
5622                                 Type ptype = Parent.TypeBuilder.BaseType;
5623
5624                                 // ptype is only null for System.Object while compiling corlib.
5625                                 if (ptype != null){
5626                                         TypeContainer.FindMembers (
5627                                                 ptype, MemberTypes.Method,
5628                                                 BindingFlags.Public |
5629                                                 BindingFlags.Static | BindingFlags.Instance,
5630                                                 System.Type.FilterName, Name);
5631                                 }
5632                         }
5633
5634                         if ((ModFlags & Modifiers.VOLATILE) != 0){
5635                                 if (!MemberType.IsClass){
5636                                         Type vt = MemberType;
5637                                         
5638                                         if (TypeManager.IsEnumType (vt))
5639                                                 vt = TypeManager.EnumToUnderlying (MemberType);
5640
5641                                         if (!((vt == TypeManager.bool_type) ||
5642                                               (vt == TypeManager.sbyte_type) ||
5643                                               (vt == TypeManager.byte_type) ||
5644                                               (vt == TypeManager.short_type) ||
5645                                               (vt == TypeManager.ushort_type) ||
5646                                               (vt == TypeManager.int32_type) ||
5647                                               (vt == TypeManager.uint32_type) ||    
5648                                               (vt == TypeManager.char_type) ||
5649                                               (vt == TypeManager.float_type) ||
5650                                               (!vt.IsValueType))){
5651                                                 Report.Error (
5652                                                         677, Location, Parent.MakeName (Name) +
5653                                                         " A volatile field can not be of type `" +
5654                                                         TypeManager.CSharpName (vt) + "'");
5655                                                 return false;
5656                                         }
5657                                 }
5658
5659                                 if ((ModFlags & Modifiers.READONLY) != 0){
5660                                         Report.Error (
5661                                                       678, Location,
5662                                                       "A field can not be both volatile and readonly");
5663                                         return false;
5664                                 }
5665                         }
5666
5667                         FieldAttributes fa = Modifiers.FieldAttr (ModFlags);
5668
5669                         if (Parent.Kind == Kind.Struct && 
5670                             ((fa & FieldAttributes.Static) == 0) &&
5671                             MemberType == Parent.TypeBuilder &&
5672                             !TypeManager.IsBuiltinType (MemberType)){
5673                                 Report.Error (523, Location, "Struct member `" + Parent.Name + "." + Name + 
5674                                               "' causes a cycle in the structure layout");
5675                                 return false;
5676                         }
5677
5678                         try {
5679                                 FieldBuilder = Parent.TypeBuilder.DefineField (
5680                                         Name, MemberType, Modifiers.FieldAttr (ModFlags));
5681
5682                                 TypeManager.RegisterFieldBase (FieldBuilder, this);
5683                         }
5684                         catch (ArgumentException) {
5685                                 Report.Warning (-24, Location, "The Microsoft runtime is unable to use [void|void*] as a field type, try using the Mono runtime.");
5686                                 return false;
5687                         }
5688
5689                         return true;
5690                 }
5691
5692                 protected override bool VerifyClsCompliance (DeclSpace ds)
5693                 {
5694                         if (!base.VerifyClsCompliance (ds))
5695                                 return false;
5696
5697                         if ((ModFlags & Modifiers.VOLATILE) != 0) {
5698                                 Report.Warning (3026, 1, Location, "CLS-compliant field '{0}' cannot be volatile", GetSignatureForError ());
5699                         }
5700
5701                         return true;
5702                 }
5703         }
5704
5705         //
5706         // `set' and `get' accessors are represented with an Accessor.
5707         // 
5708         public class Accessor {
5709                 //
5710                 // Null if the accessor is empty, or a Block if not
5711                 //
5712                 public const int AllowedModifiers = 
5713                         Modifiers.PUBLIC |
5714                         Modifiers.PROTECTED |
5715                         Modifiers.INTERNAL |
5716                         Modifiers.PRIVATE;
5717                 
5718                 public ToplevelBlock Block;
5719                 public Attributes Attributes;
5720                 public Location Location;
5721                 public int ModFlags;
5722                 
5723                 public Accessor (ToplevelBlock b, int mod, Attributes attrs, Location loc)
5724                 {
5725                         Block = b;
5726                         Attributes = attrs;
5727                         Location = loc;
5728                         ModFlags = Modifiers.Check (AllowedModifiers, mod, 0, loc);
5729                 }
5730         }
5731
5732
5733         // Ooouh Martin, templates are missing here.
5734         // When it will be possible move here a lot of child code and template method type.
5735         public abstract class AbstractPropertyEventMethod: MemberCore, IMethodData {
5736                 protected MethodData method_data;
5737                 protected ToplevelBlock block;
5738                 protected ListDictionary declarative_security;
5739
5740                 // The accessor are created event if they are not wanted.
5741                 // But we need them because their names are reserved.
5742                 // Field says whether accessor will be emited or not
5743                 public readonly bool IsDummy;
5744
5745                 protected readonly string prefix;
5746
5747                 ReturnParameter return_attributes;
5748
5749                 public AbstractPropertyEventMethod (MemberBase member, string prefix)
5750                         : base (null, SetupName (prefix, member), null, member.Location)
5751                 {
5752                         this.prefix = prefix;
5753                         IsDummy = true;
5754                 }
5755
5756                 public AbstractPropertyEventMethod (MemberBase member, Accessor accessor,
5757                                                     string prefix)
5758                         : base (null, SetupName (prefix, member),
5759                                 accessor.Attributes, accessor.Location)
5760                 {
5761                         this.prefix = prefix;
5762                         this.block = accessor.Block;
5763                 }
5764
5765                 static MemberName SetupName (string prefix, MemberBase member)
5766                 {
5767                         return new MemberName (member.MemberName.Left, prefix + member.ShortName);
5768                 }
5769
5770                 public void UpdateName (MemberBase member)
5771                 {
5772                         SetMemberName (SetupName (prefix, member));
5773                 }
5774
5775                 #region IMethodData Members
5776
5777                 public ToplevelBlock Block {
5778                         get {
5779                                 return block;
5780                         }
5781
5782                         set {
5783                                 block = value;
5784                         }
5785                 }
5786
5787                 public CallingConventions CallingConventions {
5788                         get {
5789                                 return CallingConventions.Standard;
5790                         }
5791                 }
5792
5793                 public bool IsExcluded (EmitContext ec)
5794                 {
5795                         return false;
5796                 }
5797
5798                 public MemberName MethodName {
5799                         get {
5800                                 return MemberName;
5801                         }
5802                 }
5803
5804                 public abstract ObsoleteAttribute GetObsoleteAttribute ();
5805                 public abstract Type[] ParameterTypes { get; }
5806                 public abstract Type ReturnType { get; }
5807                 public abstract EmitContext CreateEmitContext(TypeContainer tc, ILGenerator ig);
5808
5809                 #endregion
5810
5811                 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
5812                 {
5813                         if (a.Type == TypeManager.cls_compliant_attribute_type || a.Type == TypeManager.obsolete_attribute_type ||
5814                                         a.Type == TypeManager.conditional_attribute_type) {
5815                                 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 ());
5816                                 return;
5817                         }
5818
5819                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
5820                                 if (declarative_security == null)
5821                                         declarative_security = new ListDictionary ();
5822                                 a.ExtractSecurityPermissionSet (declarative_security);
5823                                 return;
5824                         }
5825
5826                         if (a.Target == AttributeTargets.Method) {
5827                                 method_data.MethodBuilder.SetCustomAttribute (cb);
5828                                 return;
5829                         }
5830
5831                         if (a.Target == AttributeTargets.ReturnValue) {
5832                                 if (return_attributes == null)
5833                                         return_attributes = new ReturnParameter (method_data.MethodBuilder, Location);
5834
5835                                 return_attributes.ApplyAttributeBuilder (a, cb);
5836                                 return;
5837                         }
5838
5839                         ApplyToExtraTarget (a, cb);
5840                 }
5841
5842                 virtual protected void ApplyToExtraTarget (Attribute a, CustomAttributeBuilder cb)
5843                 {
5844                         System.Diagnostics.Debug.Fail ("You forgot to define special attribute target handling");
5845                 }
5846
5847                 public override bool Define()
5848                 {
5849                         throw new NotSupportedException ();
5850                 }
5851
5852                 public virtual void Emit (TypeContainer container)
5853                 {
5854                         EmitMethod (container);
5855
5856                         if (declarative_security != null) {
5857                                 foreach (DictionaryEntry de in declarative_security) {
5858                                         method_data.MethodBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
5859                                 }
5860                         }
5861
5862                         block = null;
5863                 }
5864
5865                 protected virtual void EmitMethod (TypeContainer container)
5866                 {
5867                         method_data.Emit (container, this);
5868                 }
5869
5870                 public override bool IsClsCompliaceRequired(DeclSpace ds)
5871                 {
5872                         return false;
5873                 }
5874
5875                 public bool IsDuplicateImplementation (MethodCore method)
5876                 {
5877                         if (Name != method.Name)
5878                                 return false;
5879
5880                         Type[] param_types = method.ParameterTypes;
5881
5882                         if (param_types.Length != ParameterTypes.Length)
5883                                 return false;
5884
5885                         for (int i = 0; i < param_types.Length; i++)
5886                                 if (param_types [i] != ParameterTypes [i])
5887                                         return false;
5888
5889                         Report.SymbolRelatedToPreviousError (method);
5890                         Report.Error (111, Location, TypeContainer.Error111, method.Parent.GetSignatureForError (), Name);
5891                         return true;
5892                 }
5893
5894                 public override bool IsUsed
5895                 {
5896                         get {
5897                                 if (IsDummy)
5898                                         return false;
5899
5900                                 return base.IsUsed;
5901                         }
5902                 }
5903
5904                 public new Location Location { 
5905                         get {
5906                                 return base.Location;
5907                         }
5908                 }
5909
5910                 //
5911                 //   Represents header string for documentation comment.
5912                 //
5913                 public override string DocCommentHeader {
5914                         get { throw new InvalidOperationException ("Unexpected attempt to get doc comment from " + this.GetType () + "."); }
5915                 }
5916
5917                 protected override void VerifyObsoleteAttribute()
5918                 {
5919                 }
5920
5921         }
5922
5923         //
5924         // Properties and Indexers both generate PropertyBuilders, we use this to share 
5925         // their common bits.
5926         //
5927         abstract public class PropertyBase : MethodCore {
5928
5929                 public class GetMethod: PropertyMethod
5930                 {
5931                         static string[] attribute_targets = new string [] { "method", "return" };
5932
5933                         public GetMethod (MethodCore method):
5934                                 base (method, "get_")
5935                         {
5936                         }
5937
5938                         public GetMethod (MethodCore method, Accessor accessor):
5939                                 base (method, accessor, "get_")
5940                         {
5941                         }
5942
5943                         public override MethodBuilder Define(TypeContainer container)
5944                         {
5945                                 base.Define (container);
5946                                 
5947                                 method_data = new MethodData (method, method.ParameterInfo, ModFlags, flags, this);
5948
5949                                 if (!method_data.Define (container))
5950                                         return null;
5951
5952                                 return method_data.MethodBuilder;
5953                         }
5954
5955                         public override string GetSignatureForError (TypeContainer tc)
5956                         {
5957                                 return String.Concat (base.GetSignatureForError (tc), ".get");
5958                         }
5959
5960                         public override Type ReturnType {
5961                                 get {
5962                                         return method.MemberType;
5963                                 }
5964                         }
5965
5966                         public override string[] ValidAttributeTargets {
5967                                 get {
5968                                         return attribute_targets;
5969                                 }
5970                         }
5971                 }
5972
5973                 public class SetMethod: PropertyMethod {
5974
5975                         static string[] attribute_targets = new string [] { "method", "param", "return" };
5976                         ImplicitParameter param_attr;
5977
5978                         public SetMethod (MethodCore method):
5979                                 base (method, "set_")
5980                         {
5981                         }
5982
5983                         public SetMethod (MethodCore method, Accessor accessor):
5984                                 base (method, accessor, "set_")
5985                         {
5986                         }
5987
5988                         protected override void ApplyToExtraTarget(Attribute a, CustomAttributeBuilder cb)
5989                         {
5990                                 if (a.Target == AttributeTargets.Parameter) {
5991                                         if (param_attr == null)
5992                                                 param_attr = new ImplicitParameter (method_data.MethodBuilder, method.Location);
5993
5994                                         param_attr.ApplyAttributeBuilder (a, cb);
5995                                         return;
5996                                 }
5997
5998                                 base.ApplyAttributeBuilder (a, cb);
5999                         }
6000
6001                         protected virtual InternalParameters GetParameterInfo (EmitContext ec)
6002                         {
6003                                 Parameter [] parms = new Parameter [1];
6004                                 parms [0] = new Parameter (method.Type, "value", Parameter.Modifier.NONE, null, method.Location);
6005                                 Parameters parameters = new Parameters (parms, null);
6006
6007                                 bool old_unsafe = ec.InUnsafe;
6008                                 ec.InUnsafe = InUnsafe;
6009                                 Type [] types = parameters.GetParameterInfo (ec);
6010                                 ec.InUnsafe = old_unsafe;
6011
6012                                 return new InternalParameters (types, parameters);
6013                         }
6014
6015                         public override MethodBuilder Define (TypeContainer container)
6016                         {
6017                                 if (container.EmitContext == null)
6018                                         throw new InternalErrorException ("SetMethod.Define called too early");
6019                                         
6020                                 base.Define (container);
6021                                 
6022                                 method_data = new MethodData (method, GetParameterInfo (container.EmitContext), ModFlags, flags, this);
6023
6024                                 if (!method_data.Define (container))
6025                                         return null;
6026
6027                                 return method_data.MethodBuilder;
6028                         }
6029
6030                         public override string GetSignatureForError (TypeContainer tc)
6031                         {
6032                                 return String.Concat (base.GetSignatureForError (tc), ".set");
6033                         }
6034
6035                         public override Type[] ParameterTypes {
6036                                 get {
6037                                         return new Type[] { method.MemberType };
6038                                 }
6039                         }
6040
6041                         public override Type ReturnType {
6042                                 get {
6043                                         return TypeManager.void_type;
6044                                 }
6045                         }
6046
6047                         public override string[] ValidAttributeTargets {
6048                                 get {
6049                                         return attribute_targets;
6050                                 }
6051                         }
6052                 }
6053
6054                 static string[] attribute_targets = new string [] { "property" };
6055
6056                 public abstract class PropertyMethod: AbstractPropertyEventMethod
6057                 {
6058                         protected readonly MethodCore method;
6059                         protected MethodAttributes flags;
6060
6061                         public PropertyMethod (MethodCore method, string prefix)
6062                                 : base (method, prefix)
6063                         {
6064                                 this.method = method;
6065                                 Parent = method.Parent;
6066                         }
6067
6068                         public PropertyMethod (MethodCore method, Accessor accessor,
6069                                                string prefix)
6070                                 : base (method, accessor, prefix)
6071                         {
6072                                 this.method = method;
6073                                 Parent = method.Parent;
6074                                 this.ModFlags = accessor.ModFlags;
6075
6076                                 if (accessor.ModFlags != 0 && RootContext.Version == LanguageVersion.ISO_1) {
6077                                         Report.FeatureIsNotStandardized (Location, "accessor modifiers");
6078                                 }
6079                         }
6080
6081                         public override AttributeTargets AttributeTargets {
6082                                 get {
6083                                         return AttributeTargets.Method;
6084                                 }
6085                         }
6086
6087                         public override bool IsClsCompliaceRequired(DeclSpace ds)
6088                         {
6089                                 return method.IsClsCompliaceRequired (ds);
6090                         }
6091
6092                         public InternalParameters ParameterInfo 
6093                         {
6094                                 get {
6095                                         return method_data.ParameterInfo;
6096                                 }
6097                         }
6098
6099                         public virtual MethodBuilder Define (TypeContainer container)
6100                         {
6101                                 //
6102                                 // Check for custom access modifier
6103                                 //
6104                                 if (ModFlags == 0) {
6105                                         ModFlags = method.ModFlags;
6106                                         flags = method.flags;
6107                                 } else {
6108                                         if ((method.ModFlags & Modifiers.ABSTRACT) != 0 && (ModFlags & Modifiers.PRIVATE) != 0) {
6109                                                 Report.Error (442, Location, "{0}': abstract properties cannot have private accessors", GetSignatureForError (container));
6110                                         }
6111
6112                                         CheckModifiers (container, ModFlags);
6113                                         ModFlags |= (method.ModFlags & (~Modifiers.Accessibility));
6114                                         ModFlags |= Modifiers.PROPERTY_CUSTOM;
6115                                         flags = Modifiers.MethodAttr (ModFlags);
6116                                         flags |= (method.flags & (~MethodAttributes.MemberAccessMask));
6117                                 }
6118
6119                                 return null;
6120
6121                         }
6122
6123                         public bool HasCustomAccessModifier
6124                         {
6125                                 get {
6126                                         return (ModFlags & Modifiers.PROPERTY_CUSTOM) != 0;
6127                                 }
6128                         }
6129
6130                         public override Type[] ParameterTypes {
6131                                 get {
6132                                         return TypeManager.NoTypes;
6133                                 }
6134                         }
6135
6136                         public override EmitContext CreateEmitContext (TypeContainer tc,
6137                                                                        ILGenerator ig)
6138                         {
6139                                 return new EmitContext (
6140                                         tc, method.Parent, method.Location, ig, ReturnType,
6141                                         method.ModFlags, false);
6142                         }
6143
6144                         public override ObsoleteAttribute GetObsoleteAttribute ()
6145                         {
6146                                 return method.GetObsoleteAttribute (method.Parent);
6147                         }
6148
6149                         public override string GetSignatureForError (TypeContainer tc)
6150                         {
6151                                 return String.Concat (tc.Name, '.', method.Name);
6152                         }
6153                         
6154                         void CheckModifiers (TypeContainer container, int modflags)
6155                         {
6156                                 int flags = 0;
6157                                 int mflags = method.ModFlags & Modifiers.Accessibility;
6158
6159                                 if ((mflags & Modifiers.PUBLIC) != 0) {
6160                                         flags |= Modifiers.PROTECTED | Modifiers.INTERNAL | Modifiers.PRIVATE;
6161                                 }
6162                                 else if ((mflags & Modifiers.PROTECTED) != 0) {
6163                                         if ((mflags & Modifiers.INTERNAL) != 0)
6164                                                 flags |= Modifiers.PROTECTED | Modifiers.INTERNAL;
6165
6166                                         flags |= Modifiers.PRIVATE;
6167                                 }
6168                                 else if ((mflags & Modifiers.INTERNAL) != 0)
6169                                         flags |= Modifiers.PRIVATE;
6170
6171                                 if ((mflags == modflags) || (modflags & (~flags)) != 0)
6172                                         Report.Error (273, Location, "{0}: accessibility modifier must be more restrictive than the property or indexer",
6173                                                 GetSignatureForError (container));
6174                         }
6175
6176                         public override bool MarkForDuplicationCheck ()
6177                         {
6178                                 caching_flags |= Flags.TestMethodDuplication;
6179                                 return true;
6180                         }
6181                 }
6182
6183
6184                 public PropertyMethod Get, Set;
6185                 public PropertyBuilder PropertyBuilder;
6186                 public MethodBuilder GetBuilder, SetBuilder;
6187
6188                 protected EmitContext ec;
6189
6190                 public PropertyBase (TypeContainer ds, Expression type, int mod_flags,
6191                                      int allowed_mod, bool is_iface, MemberName name,
6192                                      Parameters parameters, Attributes attrs,
6193                                      Location loc)
6194                         : base (ds, type, mod_flags, allowed_mod, is_iface, name,
6195                                 attrs, parameters, loc)
6196                 {
6197                 }
6198
6199                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
6200                 {
6201                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
6202                                 a.Error_InvalidSecurityParent ();
6203                                 return;
6204                         }
6205
6206                         PropertyBuilder.SetCustomAttribute (cb);
6207                 }
6208
6209                 public override AttributeTargets AttributeTargets {
6210                         get {
6211                                 return AttributeTargets.Property;
6212                         }
6213                 }
6214
6215                 public override bool Define ()
6216                 {
6217                         if (!DoDefine ())
6218                                 return false;
6219
6220                         if (!IsTypePermitted ())
6221                                 return false;
6222
6223                         return true;
6224                 }
6225
6226                 protected override bool DoDefine ()
6227                 {
6228                         if (!base.DoDefine ())
6229                                 return false;
6230
6231                         //
6232                         // Accessors modifiers check
6233                         //
6234                         if (Get.ModFlags != 0 && Set.ModFlags != 0) {
6235                                 Report.Error (274, Location, "'{0}': cannot specify accessibility modifiers for both accessors of the property or indexer.",
6236                                                 GetSignatureForError ());
6237                                 return false;
6238                         }
6239
6240                         if ((Get.IsDummy || Set.IsDummy)
6241                                         && (Get.ModFlags != 0 || Set.ModFlags != 0) && (ModFlags & Modifiers.OVERRIDE) == 0) {
6242                                 Report.Error (276, Location, 
6243                                         "'{0}': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor.",
6244                                         GetSignatureForError ());
6245                                 return false;
6246                         }
6247
6248                         if (MemberType.IsAbstract && MemberType.IsSealed) {
6249                                 Report.Error (722, Location, Error722, TypeManager.CSharpName (MemberType));
6250                                 return false;
6251                         }
6252
6253                         ec = new EmitContext (Parent, Location, null, MemberType, ModFlags);
6254                         return true;
6255                 }
6256
6257                 public override string GetSignatureForError()
6258                 {
6259                         if (PropertyBuilder == null)
6260                                 return GetSignatureForError (Parent);
6261
6262                         return TypeManager.CSharpSignature (PropertyBuilder, false);
6263                 }
6264
6265                 protected override bool CheckForDuplications ()
6266                 {
6267                         ArrayList ar = Parent.Indexers;
6268                         if (ar != null) {
6269                                 int arLen = ar.Count;
6270                                         
6271                                 for (int i = 0; i < arLen; i++) {
6272                                         Indexer m = (Indexer) ar [i];
6273                                         if (IsDuplicateImplementation (m))
6274                                                 return false;
6275                                 }
6276                         }
6277
6278                         ar = Parent.Properties;
6279                         if (ar != null) {
6280                                 int arLen = ar.Count;
6281                                         
6282                                 for (int i = 0; i < arLen; i++) {
6283                                         Property m = (Property) ar [i];
6284                                         if (IsDuplicateImplementation (m))
6285                                                 return false;
6286                                 }
6287                         }
6288
6289                         return true;
6290                 }
6291
6292                 // TODO: rename to Resolve......
6293                 protected override MethodInfo FindOutBaseMethod (TypeContainer container, ref Type base_ret_type)
6294                 {
6295                         PropertyInfo base_property = container.BaseCache.FindMemberToOverride (
6296                                 container.TypeBuilder, Name, ParameterTypes, true) as PropertyInfo;
6297   
6298                         if (base_property == null)
6299                                 return null;
6300   
6301                         base_ret_type = base_property.PropertyType;
6302                         MethodInfo get_accessor = base_property.GetGetMethod (true);
6303                         MethodInfo set_accessor = base_property.GetSetMethod (true);
6304                         MethodAttributes get_accessor_access, set_accessor_access;
6305
6306                         if ((ModFlags & Modifiers.OVERRIDE) != 0) {
6307                                 if (Get != null && !Get.IsDummy && get_accessor == null) {
6308                                         Report.SymbolRelatedToPreviousError (base_property);
6309                                         Report.Error (545, Location, "'{0}': cannot override because '{1}' does not have an overridable get accessor", GetSignatureForError (), TypeManager.GetFullNameSignature (base_property));
6310                                 }
6311
6312                                 if (Set != null && !Set.IsDummy && set_accessor == null) {
6313                                         Report.SymbolRelatedToPreviousError (base_property);
6314                                         Report.Error (546, Location, "'{0}': cannot override because '{1}' does not have an overridable set accessor", GetSignatureForError (), TypeManager.GetFullNameSignature (base_property));
6315                                 }
6316                         }
6317                         
6318                         //
6319                         // Check base class accessors access
6320                         //
6321                         get_accessor_access = set_accessor_access = 0;
6322                         if ((ModFlags & Modifiers.NEW) == 0) {
6323                                 if (get_accessor != null) {
6324                                         MethodAttributes get_flags = Modifiers.MethodAttr (Get.ModFlags != 0 ? Get.ModFlags : ModFlags);
6325                                         get_accessor_access = (get_accessor.Attributes & MethodAttributes.MemberAccessMask);
6326
6327                                         if (!Get.IsDummy && !CheckAccessModifiers (get_flags & MethodAttributes.MemberAccessMask, get_accessor_access, get_accessor))
6328                                                 Report.Error (507, Location, "'{0}' can't change the access modifiers when overriding inherited member '{1}'",
6329                                                                 GetSignatureForError (), TypeManager.GetFullNameSignature (base_property));
6330                                 }
6331
6332                                 if (set_accessor != null)  {
6333                                         MethodAttributes set_flags = Modifiers.MethodAttr (Set.ModFlags != 0 ? Set.ModFlags : ModFlags);
6334                                         set_accessor_access = (set_accessor.Attributes & MethodAttributes.MemberAccessMask);
6335
6336                                         if (!Set.IsDummy && !CheckAccessModifiers (set_flags & MethodAttributes.MemberAccessMask, set_accessor_access, set_accessor))
6337                                                 Report.Error (507, Location, "'{0}' can't change the access modifiers when overriding inherited member '{1}'",
6338                                                                 GetSignatureForError (container), TypeManager.GetFullNameSignature (base_property));
6339                                 }
6340                         }
6341
6342                         //
6343                         // Get the less restrictive access
6344                         //
6345                         return get_accessor_access > set_accessor_access ? get_accessor : set_accessor;
6346                 }
6347
6348                 public override void Emit ()
6349                 {
6350                         //
6351                         // The PropertyBuilder can be null for explicit implementations, in that
6352                         // case, we do not actually emit the ".property", so there is nowhere to
6353                         // put the attribute
6354                         //
6355                         if (PropertyBuilder != null && OptAttributes != null)
6356                                 OptAttributes.Emit (ec, this);
6357
6358                         if (!Get.IsDummy)
6359                                 Get.Emit (Parent);
6360
6361                         if (!Set.IsDummy)
6362                                 Set.Emit (Parent);
6363
6364                         base.Emit ();
6365                 }
6366
6367                 /// <summary>
6368                 /// Tests whether accessors are not in collision with some method (CS0111)
6369                 /// </summary>
6370                 public bool AreAccessorsDuplicateImplementation (MethodCore mc)
6371                 {
6372                         return Get.IsDuplicateImplementation (mc) || Set.IsDuplicateImplementation (mc);
6373                 }
6374
6375                 public override bool IsUsed
6376                 {
6377                         get {
6378                                 if (IsExplicitImpl)
6379                                         return true;
6380
6381                                 return Get.IsUsed | Set.IsUsed;
6382                         }
6383                 }
6384
6385                 protected override void SetMemberName (MemberName new_name)
6386                 {
6387                         base.SetMemberName (new_name);
6388
6389                         Get.UpdateName (this);
6390                         Set.UpdateName (this);
6391                 }
6392
6393                 public override string[] ValidAttributeTargets {
6394                         get {
6395                                 return attribute_targets;
6396                         }
6397                 }
6398
6399                 //
6400                 //   Represents header string for documentation comment.
6401                 //
6402                 public override string DocCommentHeader {
6403                         get { return "P:"; }
6404                 }
6405         }
6406                         
6407         public class Property : PropertyBase, IIteratorContainer {
6408                 const int AllowedModifiers =
6409                         Modifiers.NEW |
6410                         Modifiers.PUBLIC |
6411                         Modifiers.PROTECTED |
6412                         Modifiers.INTERNAL |
6413                         Modifiers.PRIVATE |
6414                         Modifiers.STATIC |
6415                         Modifiers.SEALED |
6416                         Modifiers.OVERRIDE |
6417                         Modifiers.ABSTRACT |
6418                         Modifiers.UNSAFE |
6419                         Modifiers.EXTERN |
6420                         Modifiers.METHOD_YIELDS |
6421                         Modifiers.VIRTUAL;
6422
6423                 const int AllowedInterfaceModifiers =
6424                         Modifiers.NEW;
6425
6426                 public Property (TypeContainer ds, Expression type, int mod, bool is_iface,
6427                                  MemberName name, Attributes attrs, Accessor get_block,
6428                                  Accessor set_block, Location loc)
6429                         : base (ds, type, mod,
6430                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
6431                                 is_iface, name, Parameters.EmptyReadOnlyParameters, attrs,
6432                                 loc)
6433                 {
6434                         if (get_block == null)
6435                                 Get = new GetMethod (this);
6436                         else
6437                                 Get = new GetMethod (this, get_block);
6438
6439                         if (set_block == null)
6440                                 Set = new SetMethod (this);
6441                         else
6442                                 Set = new SetMethod (this, set_block);
6443                 }
6444
6445                 public override bool Define ()
6446                 {
6447                         if (!base.Define ())
6448                                 return false;
6449
6450                         if (!CheckBase ())
6451                                 return false;
6452
6453                         flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
6454
6455                         if (!Get.IsDummy) {
6456
6457                                 GetBuilder = Get.Define (Parent);
6458                                 if (GetBuilder == null)
6459                                         return false;
6460
6461                                 //
6462                                 // Setup iterator if we are one
6463                                 //
6464                                 if ((ModFlags & Modifiers.METHOD_YIELDS) != 0){
6465                                         Iterator iterator = new Iterator (
6466                                                 Parent, "get", MemberType,
6467                                                 Get.ParameterInfo,
6468                                                 ModFlags, Get.Block, Location);
6469                                         
6470                                         if (!iterator.DefineIterator ())
6471                                                 return false;
6472                                         Get.Block = iterator.Block;
6473                                 }
6474                         }
6475
6476                         if (!Set.IsDummy) {
6477                                 SetBuilder = Set.Define (Parent);
6478                                 if (SetBuilder == null)
6479                                         return false;
6480
6481                                 SetBuilder.DefineParameter (1, ParameterAttributes.None, "value"); 
6482                         }
6483
6484                         // FIXME - PropertyAttributes.HasDefault ?
6485                         
6486                         PropertyAttributes prop_attr = PropertyAttributes.None;
6487                         if (!IsInterface)
6488                                 prop_attr |= PropertyAttributes.RTSpecialName |
6489                                         PropertyAttributes.SpecialName;
6490
6491                         PropertyBuilder = Parent.TypeBuilder.DefineProperty (
6492                              Name, prop_attr, MemberType, null);
6493                         
6494                         if (!Get.IsDummy)
6495                                 PropertyBuilder.SetGetMethod (GetBuilder);
6496                                 
6497                         if (!Set.IsDummy)
6498                                 PropertyBuilder.SetSetMethod (SetBuilder);
6499                         
6500                         TypeManager.RegisterProperty (PropertyBuilder, GetBuilder, SetBuilder);
6501                         return true;
6502                 }
6503
6504                 public void SetYields ()
6505                 {
6506                         ModFlags |= Modifiers.METHOD_YIELDS;
6507                 }
6508         }
6509
6510         /// </summary>
6511         ///  Gigantic workaround  for lameness in SRE follows :
6512         ///  This class derives from EventInfo and attempts to basically
6513         ///  wrap around the EventBuilder so that FindMembers can quickly
6514         ///  return this in it search for members
6515         /// </summary>
6516         public class MyEventBuilder : EventInfo {
6517                 
6518                 //
6519                 // We use this to "point" to our Builder which is
6520                 // not really a MemberInfo
6521                 //
6522                 EventBuilder MyBuilder;
6523                 
6524                 //
6525                 // We "catch" and wrap these methods
6526                 //
6527                 MethodInfo raise, remove, add;
6528
6529                 EventAttributes attributes;
6530                 Type declaring_type, reflected_type, event_type;
6531                 string name;
6532
6533                 Event my_event;
6534
6535                 public MyEventBuilder (Event ev, TypeBuilder type_builder, string name, EventAttributes event_attr, Type event_type)
6536                 {
6537                         MyBuilder = type_builder.DefineEvent (name, event_attr, event_type);
6538
6539                         // And now store the values in our own fields.
6540                         
6541                         declaring_type = type_builder;
6542
6543                         reflected_type = type_builder;
6544                         
6545                         attributes = event_attr;
6546                         this.name = name;
6547                         my_event = ev;
6548                         this.event_type = event_type;
6549                 }
6550                 
6551                 //
6552                 // Methods that you have to override.  Note that you only need 
6553                 // to "implement" the variants that take the argument (those are
6554                 // the "abstract" methods, the others (GetAddMethod()) are 
6555                 // regular.
6556                 //
6557                 public override MethodInfo GetAddMethod (bool nonPublic)
6558                 {
6559                         return add;
6560                 }
6561                 
6562                 public override MethodInfo GetRemoveMethod (bool nonPublic)
6563                 {
6564                         return remove;
6565                 }
6566                 
6567                 public override MethodInfo GetRaiseMethod (bool nonPublic)
6568                 {
6569                         return raise;
6570                 }
6571                 
6572                 //
6573                 // These methods make "MyEventInfo" look like a Builder
6574                 //
6575                 public void SetRaiseMethod (MethodBuilder raiseMethod)
6576                 {
6577                         raise = raiseMethod;
6578                         MyBuilder.SetRaiseMethod (raiseMethod);
6579                 }
6580
6581                 public void SetRemoveOnMethod (MethodBuilder removeMethod)
6582                 {
6583                         remove = removeMethod;
6584                         MyBuilder.SetRemoveOnMethod (removeMethod);
6585                 }
6586
6587                 public void SetAddOnMethod (MethodBuilder addMethod)
6588                 {
6589                         add = addMethod;
6590                         MyBuilder.SetAddOnMethod (addMethod);
6591                 }
6592
6593                 public void SetCustomAttribute (CustomAttributeBuilder cb)
6594                 {
6595                         MyBuilder.SetCustomAttribute (cb);
6596                 }
6597                 
6598                 public override object [] GetCustomAttributes (bool inherit)
6599                 {
6600                         // FIXME : There's nothing which can be seemingly done here because
6601                         // we have no way of getting at the custom attribute objects of the
6602                         // EventBuilder !
6603                         return null;
6604                 }
6605
6606                 public override object [] GetCustomAttributes (Type t, bool inherit)
6607                 {
6608                         // FIXME : Same here !
6609                         return null;
6610                 }
6611
6612                 public override bool IsDefined (Type t, bool b)
6613                 {
6614                         return true;
6615                 }
6616
6617                 public override EventAttributes Attributes {
6618                         get {
6619                                 return attributes;
6620                         }
6621                 }
6622
6623                 public override string Name {
6624                         get {
6625                                 return name;
6626                         }
6627                 }
6628
6629                 public override Type DeclaringType {
6630                         get {
6631                                 return declaring_type;
6632                         }
6633                 }
6634
6635                 public override Type ReflectedType {
6636                         get {
6637                                 return reflected_type;
6638                         }
6639                 }
6640
6641                 public Type EventType {
6642                         get {
6643                                 return event_type;
6644                         }
6645                 }
6646                 
6647                 public void SetUsed ()
6648                 {
6649                         if (my_event != null) {
6650                                 my_event.status = FieldBase.Status.ASSIGNED;
6651                                 my_event.SetMemberIsUsed ();
6652                         }
6653                 }
6654         }
6655         
6656         /// <summary>
6657         /// For case when event is declared like property (with add and remove accessors).
6658         /// </summary>
6659         public class EventProperty: Event {
6660
6661                 static string[] attribute_targets = new string [] { "event", "property" };
6662
6663                 public EventProperty (TypeContainer parent, Expression type, int mod_flags,
6664                                       bool is_iface, MemberName name, Object init,
6665                                       Attributes attrs, Accessor add, Accessor remove,
6666                                       Location loc)
6667                         : base (parent, type, mod_flags, is_iface, name, init, attrs, loc)
6668                 {
6669                         Add = new AddDelegateMethod (this, add);
6670                         Remove = new RemoveDelegateMethod (this, remove);
6671
6672                         // For this event syntax we don't report error CS0067
6673                         // because it is hard to do it.
6674                         SetAssigned ();
6675                 }
6676
6677                 public override string[] ValidAttributeTargets {
6678                         get {
6679                                 return attribute_targets;
6680                         }
6681                 }
6682         }
6683
6684         /// <summary>
6685         /// Event is declared like field.
6686         /// </summary>
6687         public class EventField: Event {
6688
6689                 static string[] attribute_targets = new string [] { "event", "field", "method" };
6690                 static string[] attribute_targets_interface = new string[] { "event", "method" };
6691
6692                 public EventField (TypeContainer parent, Expression type, int mod_flags,
6693                                    bool is_iface, MemberName name, Object init,
6694                                    Attributes attrs, Location loc)
6695                         : base (parent, type, mod_flags, is_iface, name, init, attrs, loc)
6696                 {
6697                         Add = new AddDelegateMethod (this);
6698                         Remove = new RemoveDelegateMethod (this);
6699                 }
6700
6701                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
6702                 {
6703                         if (a.Target == AttributeTargets.Field) {
6704                                 FieldBuilder.SetCustomAttribute (cb);
6705                                 return;
6706                         }
6707
6708                         if (a.Target == AttributeTargets.Method) {
6709                                 Add.ApplyAttributeBuilder (a, cb);
6710                                 Remove.ApplyAttributeBuilder (a, cb);
6711                                 return;
6712                         }
6713
6714                         base.ApplyAttributeBuilder (a, cb);
6715                 }
6716
6717                 public override string[] ValidAttributeTargets {
6718                         get {
6719                                 return IsInterface ? attribute_targets_interface : attribute_targets;
6720                         }
6721                 }
6722         }
6723
6724         public abstract class Event : FieldBase {
6725
6726                 protected sealed class AddDelegateMethod: DelegateMethod
6727                 {
6728
6729                         public AddDelegateMethod (Event method):
6730                                 base (method, "add_")
6731                         {
6732                         }
6733
6734                         public AddDelegateMethod (Event method, Accessor accessor):
6735                                 base (method, accessor, "add_")
6736                         {
6737                         }
6738
6739                         protected override MethodInfo DelegateMethodInfo {
6740                                 get {
6741                                         return TypeManager.delegate_combine_delegate_delegate;
6742                                 }
6743                         }
6744
6745                 }
6746
6747                 protected sealed class RemoveDelegateMethod: DelegateMethod
6748                 {
6749                         public RemoveDelegateMethod (Event method):
6750                                 base (method, "remove_")
6751                         {
6752                         }
6753
6754                         public RemoveDelegateMethod (Event method, Accessor accessor):
6755                                 base (method, accessor, "remove_")
6756                         {
6757                         }
6758
6759                         protected override MethodInfo DelegateMethodInfo {
6760                                 get {
6761                                         return TypeManager.delegate_remove_delegate_delegate;
6762                                 }
6763                         }
6764
6765                 }
6766
6767                 public abstract class DelegateMethod: AbstractPropertyEventMethod
6768                 {
6769                         protected readonly Event method;
6770                         ImplicitParameter param_attr;
6771
6772                         static string[] attribute_targets = new string [] { "method", "param", "return" };
6773
6774                         public DelegateMethod (Event method, string prefix)
6775                                 : base (method, prefix)
6776                         {
6777                                 this.method = method;
6778                         }
6779
6780                         public DelegateMethod (Event method, Accessor accessor, string prefix)
6781                                 : base (method, accessor, prefix)
6782                         {
6783                                 this.method = method;
6784                         }
6785
6786                         protected override void ApplyToExtraTarget(Attribute a, CustomAttributeBuilder cb)
6787                         {
6788                                 if (a.Target == AttributeTargets.Parameter) {
6789                                         if (param_attr == null)
6790                                                 param_attr = new ImplicitParameter (method_data.MethodBuilder, method.Location);
6791
6792                                         param_attr.ApplyAttributeBuilder (a, cb);
6793                                         return;
6794                                 }
6795
6796                                 base.ApplyAttributeBuilder (a, cb);
6797                         }
6798
6799                         public override AttributeTargets AttributeTargets {
6800                                 get {
6801                                         return AttributeTargets.Method;
6802                                 }
6803                         }
6804
6805                         public override bool IsClsCompliaceRequired(DeclSpace ds)
6806                         {
6807                                 return method.IsClsCompliaceRequired (ds);
6808                         }
6809
6810                         public MethodBuilder Define (TypeContainer container, InternalParameters ip)
6811                         {
6812                                 method_data = new MethodData (method, ip, method.ModFlags,
6813                                         method.flags | MethodAttributes.HideBySig | MethodAttributes.SpecialName, this);
6814
6815                                 if (!method_data.Define (container))
6816                                         return null;
6817
6818                                 MethodBuilder mb = method_data.MethodBuilder;
6819                                 mb.DefineParameter (1, ParameterAttributes.None, "value");
6820                                 return mb;
6821                         }
6822
6823
6824                         protected override void EmitMethod (TypeContainer tc)
6825                         {
6826                                 if (block != null) {
6827                                         base.EmitMethod (tc);
6828                                         return;
6829                                 }
6830
6831                                 if ((method.ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
6832                                         return;
6833
6834                                 ILGenerator ig = method_data.MethodBuilder.GetILGenerator ();
6835                                 FieldInfo field_info = (FieldInfo)method.FieldBuilder;
6836
6837                                 method_data.MethodBuilder.SetImplementationFlags (MethodImplAttributes.Synchronized);
6838                                 if ((method.ModFlags & Modifiers.STATIC) != 0) {
6839                                         ig.Emit (OpCodes.Ldsfld, field_info);
6840                                         ig.Emit (OpCodes.Ldarg_0);
6841                                         ig.Emit (OpCodes.Call, DelegateMethodInfo);
6842                                         ig.Emit (OpCodes.Castclass, method.MemberType);
6843                                         ig.Emit (OpCodes.Stsfld, field_info);
6844                                 } else {
6845                                         ig.Emit (OpCodes.Ldarg_0);
6846                                         ig.Emit (OpCodes.Ldarg_0);
6847                                         ig.Emit (OpCodes.Ldfld, field_info);
6848                                         ig.Emit (OpCodes.Ldarg_1);
6849                                         ig.Emit (OpCodes.Call, DelegateMethodInfo);
6850                                         ig.Emit (OpCodes.Castclass, method.MemberType);
6851                                         ig.Emit (OpCodes.Stfld, field_info);
6852                                 }
6853                                 ig.Emit (OpCodes.Ret);
6854                         }
6855
6856                         protected abstract MethodInfo DelegateMethodInfo { get; }
6857
6858                         public override Type[] ParameterTypes {
6859                                 get {
6860                                         return new Type[] { method.MemberType };
6861                                 }
6862                         }
6863
6864                         public override Type ReturnType {
6865                                 get {
6866                                         return TypeManager.void_type;
6867                                 }
6868                         }
6869
6870                         public override EmitContext CreateEmitContext (TypeContainer tc,
6871                                                                        ILGenerator ig)
6872                         {
6873                                 return new EmitContext (
6874                                         tc, method.Parent, Location, ig, ReturnType,
6875                                         method.ModFlags, false);
6876                         }
6877
6878                         public override string GetSignatureForError (TypeContainer tc)
6879                         {
6880                                 return String.Concat (tc.Name, '.', method.Name);
6881                         }
6882
6883                         public override ObsoleteAttribute GetObsoleteAttribute ()
6884                         {
6885                                 return method.GetObsoleteAttribute (method.Parent);
6886                         }
6887
6888                         public override string[] ValidAttributeTargets {
6889                                 get {
6890                                         return attribute_targets;
6891                                 }
6892                         }
6893                 }
6894
6895
6896                 const int AllowedModifiers =
6897                         Modifiers.NEW |
6898                         Modifiers.PUBLIC |
6899                         Modifiers.PROTECTED |
6900                         Modifiers.INTERNAL |
6901                         Modifiers.PRIVATE |
6902                         Modifiers.STATIC |
6903                         Modifiers.VIRTUAL |
6904                         Modifiers.SEALED |
6905                         Modifiers.OVERRIDE |
6906                         Modifiers.UNSAFE |
6907                         Modifiers.ABSTRACT;
6908
6909                 const int AllowedInterfaceModifiers =
6910                         Modifiers.NEW;
6911
6912                 public DelegateMethod Add, Remove;
6913                 public MyEventBuilder     EventBuilder;
6914                 public MethodBuilder AddBuilder, RemoveBuilder;
6915
6916                 public Event (TypeContainer parent, Expression type, int mod_flags,
6917                               bool is_iface, MemberName name, Object init, Attributes attrs,
6918                               Location loc)
6919                         : base (parent, type, mod_flags,
6920                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
6921                                 name, init, attrs, loc)
6922                 {
6923                         IsInterface = is_iface;
6924                 }
6925
6926                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
6927                 {
6928                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
6929                                 a.Error_InvalidSecurityParent ();
6930                                 return;
6931                         }
6932                         
6933                         EventBuilder.SetCustomAttribute (cb);
6934                 }
6935
6936                 public bool AreAccessorsDuplicateImplementation (MethodCore mc)
6937                 {
6938                         return Add.IsDuplicateImplementation (mc) || Remove.IsDuplicateImplementation (mc);
6939                 }
6940
6941                 public override AttributeTargets AttributeTargets {
6942                         get {
6943                                 return AttributeTargets.Event;
6944                         }
6945                 }
6946
6947                 public override bool Define ()
6948                 {
6949                         EventAttributes e_attr;
6950                         e_attr = EventAttributes.None;
6951
6952                         if (!DoDefine ())
6953                                 return false;
6954
6955                         if (init != null && ((ModFlags & Modifiers.ABSTRACT) != 0)){
6956                                 Report.Error (74, Location, "'" + Parent.Name + "." + Name +
6957                                               "': abstract event can not have an initializer");
6958                                 return false;
6959                         }
6960                         
6961                         if (!MemberType.IsSubclassOf (TypeManager.delegate_type)) {
6962                                 Report.Error (66, Location, "'" + Parent.Name + "." + Name +
6963                                               "' : event must be of a delegate type");
6964                                 return false;
6965                         }
6966
6967                         EmitContext ec = Parent.EmitContext;
6968                         if (ec == null)
6969                                 throw new InternalErrorException ("Event.Define called too early?");
6970                         bool old_unsafe = ec.InUnsafe;
6971                         ec.InUnsafe = InUnsafe;
6972
6973                         Parameter [] parms = new Parameter [1];
6974                         parms [0] = new Parameter (Type, "value", Parameter.Modifier.NONE, null, Location);
6975                         Parameters parameters = new Parameters (parms, null);
6976                         Type [] types = parameters.GetParameterInfo (ec);
6977                         InternalParameters ip = new InternalParameters (types, parameters);
6978
6979                         ec.InUnsafe = old_unsafe;
6980
6981                         if (!CheckBase ())
6982                                 return false;
6983
6984                         //
6985                         // Now define the accessors
6986                         //
6987
6988                         AddBuilder = Add.Define (Parent, ip);
6989                         if (AddBuilder == null)
6990                                 return false;
6991
6992                         RemoveBuilder = Remove.Define (Parent, ip);
6993                         if (RemoveBuilder == null)
6994                                 return false;
6995
6996                         EventBuilder = new MyEventBuilder (this, Parent.TypeBuilder, Name, e_attr, MemberType);
6997                         
6998                         if (Add.Block == null && Remove.Block == null && !IsInterface) {
6999                                 FieldBuilder = Parent.TypeBuilder.DefineField (
7000                                         Name, MemberType,
7001                                         FieldAttributes.Private | ((ModFlags & Modifiers.STATIC) != 0 ? FieldAttributes.Static : 0));
7002                                 TypeManager.RegisterPrivateFieldOfEvent (
7003                                         (EventInfo) EventBuilder, FieldBuilder);
7004                                 TypeManager.RegisterFieldBase (FieldBuilder, this);
7005                         }
7006                         
7007                         EventBuilder.SetAddOnMethod (AddBuilder);
7008                         EventBuilder.SetRemoveOnMethod (RemoveBuilder);
7009
7010                         TypeManager.RegisterEvent (EventBuilder, AddBuilder, RemoveBuilder);
7011                         return true;
7012                 }
7013
7014                 protected override bool CheckBase ()
7015                 {
7016                         if (!base.CheckBase ())
7017                                 return false;
7018  
7019                         if (conflict_symbol != null && (ModFlags & Modifiers.NEW) == 0) {
7020                                 if (!(conflict_symbol is EventInfo)) {
7021                                         Report.SymbolRelatedToPreviousError (conflict_symbol);
7022                                         Report.Error (72, Location, "Event '{0}' can override only event", GetSignatureForError (Parent));
7023                                         return false;
7024                                 }
7025                         }
7026  
7027                         return true;
7028                 }
7029
7030                 public override void Emit ()
7031                 {
7032                         if (OptAttributes != null) {
7033                                 EmitContext ec = new EmitContext (
7034                                         Parent, Location, null, MemberType, ModFlags);
7035                                 OptAttributes.Emit (ec, this);
7036                         }
7037
7038                         Add.Emit (Parent);
7039                         Remove.Emit (Parent);
7040
7041                         base.Emit ();
7042                 }
7043
7044                 public override string GetSignatureForError ()
7045                 {
7046                         if (EventBuilder == null)
7047                                 return base.GetSignatureForError (Parent);
7048
7049                         return TypeManager.GetFullNameSignature (EventBuilder);
7050                 }
7051
7052                 //
7053                 //   Represents header string for documentation comment.
7054                 //
7055                 public override string DocCommentHeader {
7056                         get { return "E:"; }
7057                 }
7058         }
7059
7060
7061         public class Indexer : PropertyBase {
7062
7063                 class GetIndexerMethod: GetMethod
7064                 {
7065                         public GetIndexerMethod (MethodCore method):
7066                                 base (method)
7067                         {
7068                         }
7069
7070                         public GetIndexerMethod (MethodCore method, Accessor accessor):
7071                                 base (method, accessor)
7072                         {
7073                         }
7074
7075                         // TODO: one GetSignatureForError is enough (reuse Parent member)
7076                         public override string GetSignatureForError (TypeContainer tc)
7077                         {
7078                                 string core = base.GetSignatureForError (tc);
7079                                 return core.Replace (TypeContainer.DefaultIndexerName, 
7080                                         String.Format ("this[{0}]", TypeManager.CSharpName (ParameterTypes)));
7081                         }
7082
7083                         public override Type[] ParameterTypes {
7084                                 get {
7085                                         return method.ParameterTypes;
7086                                 }
7087                         }
7088                 }
7089
7090                 class SetIndexerMethod: SetMethod
7091                 {
7092                         readonly Parameters parameters;
7093
7094                         public SetIndexerMethod (MethodCore method):
7095                                 base (method)
7096                         {
7097                         }
7098
7099                         public SetIndexerMethod (MethodCore method, Parameters parameters, Accessor accessor):
7100                                 base (method, accessor)
7101                         {
7102                                 this.parameters = parameters;
7103                         }
7104
7105                         public override Type[] ParameterTypes {
7106                                 get {
7107                                         int top = method.ParameterTypes.Length;
7108                                         Type [] set_pars = new Type [top + 1];
7109                                         method.ParameterTypes.CopyTo (set_pars, 0);
7110                                         set_pars [top] = method.MemberType;
7111                                         return set_pars;
7112                                 }
7113                         }
7114
7115                         protected override InternalParameters GetParameterInfo (EmitContext ec)
7116                         {
7117                                 Parameter [] fixed_parms = parameters.FixedParameters;
7118
7119                                 if (fixed_parms == null){
7120                                         throw new Exception ("We currently do not support only array arguments in an indexer at: " + method.Location);
7121                                         // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
7122                                         // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
7123                                         //
7124                                         // Here is the problem: the `value' parameter has
7125                                         // to come *after* the array parameter in the declaration
7126                                         // like this:
7127                                         // X (object [] x, Type value)
7128                                         // .param [0]
7129                                         //
7130                                         // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
7131                                         // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
7132                                         
7133                                 }
7134                                 
7135                                 Parameter [] tmp = new Parameter [fixed_parms.Length + 1];
7136
7137                                 fixed_parms.CopyTo (tmp, 0);
7138                                 tmp [fixed_parms.Length] = new Parameter (
7139                                         method.Type, "value", Parameter.Modifier.NONE, null, method.Location);
7140
7141                                 Parameters set_formal_params = new Parameters (tmp, null);
7142                                 Type [] types = set_formal_params.GetParameterInfo (ec);
7143                                 
7144                                 return new InternalParameters (types, set_formal_params);
7145                         }
7146                 }
7147
7148
7149                 const int AllowedModifiers =
7150                         Modifiers.NEW |
7151                         Modifiers.PUBLIC |
7152                         Modifiers.PROTECTED |
7153                         Modifiers.INTERNAL |
7154                         Modifiers.PRIVATE |
7155                         Modifiers.VIRTUAL |
7156                         Modifiers.SEALED |
7157                         Modifiers.OVERRIDE |
7158                         Modifiers.UNSAFE |
7159                         Modifiers.EXTERN |
7160                         Modifiers.ABSTRACT;
7161
7162                 const int AllowedInterfaceModifiers =
7163                         Modifiers.NEW;
7164
7165
7166                 public Indexer (TypeContainer ds, Expression type, MemberName name, int mod,
7167                                 bool is_iface, Parameters parameters, Attributes attrs,
7168                                 Accessor get_block, Accessor set_block, Location loc)
7169                         : base (ds, type, mod,
7170                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
7171                                 is_iface, name, parameters, attrs, loc)
7172                 {
7173                         if (get_block == null)
7174                                 Get = new GetIndexerMethod (this);
7175                         else
7176                                 Get = new GetIndexerMethod (this, get_block);
7177
7178                         if (set_block == null)
7179                                 Set = new SetIndexerMethod (this);
7180                         else
7181                                 Set = new SetIndexerMethod (this, parameters, set_block);
7182                 }
7183                        
7184                 public override bool Define ()
7185                 {
7186                         PropertyAttributes prop_attr =
7187                                 PropertyAttributes.RTSpecialName |
7188                                 PropertyAttributes.SpecialName;
7189                         
7190                         if (!base.Define ())
7191                                 return false;
7192
7193                         if (MemberType == TypeManager.void_type) {
7194                                 Report.Error (620, Location, "Indexers cannot have void type");
7195                                 return false;
7196                         }
7197
7198                         if (OptAttributes != null) {
7199                                 Attribute indexer_attr = OptAttributes.Search (TypeManager.indexer_name_type, ec);
7200                                 if (indexer_attr != null) {
7201                                         // Remove the attribute from the list because it is not emitted
7202                                         OptAttributes.Attrs.Remove (indexer_attr);
7203
7204                                         ShortName = indexer_attr.GetIndexerAttributeValue (ec);
7205
7206                                         if (IsExplicitImpl) {
7207                                                 Report.Error (415, indexer_attr.Location,
7208                                                               "The 'IndexerName' attribute is valid only on an " +
7209                                                               "indexer that is not an explicit interface member declaration");
7210                                                 return false;
7211                                         }
7212
7213                                         if ((ModFlags & Modifiers.OVERRIDE) != 0) {
7214                                                 Report.Error (609, indexer_attr.Location,
7215                                                               "Cannot set the 'IndexerName' attribute on an indexer marked override");
7216                                                 return false;
7217                                         }
7218
7219                                         if (!Tokenizer.IsValidIdentifier (ShortName)) {
7220                                                 Report.Error (633, indexer_attr.Location,
7221                                                               "The argument to the 'IndexerName' attribute must be a valid identifier");
7222                                                 return false;
7223                                         }
7224                                 }
7225                         }
7226
7227                         if (InterfaceType != null) {
7228                                 string base_IndexerName = TypeManager.IndexerPropertyName (InterfaceType);
7229                                 if (base_IndexerName != Name)
7230                                         ShortName = base_IndexerName;
7231                         }
7232
7233                         if (!Parent.AddToMemberContainer (this) ||
7234                                 !Parent.AddToMemberContainer (Get) || !Parent.AddToMemberContainer (Set))
7235                                 return false;
7236
7237                         if (!CheckBase ())
7238                                 return false;
7239
7240                         flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
7241                         if (!Get.IsDummy){
7242                                 GetBuilder = Get.Define (Parent);
7243                                 if (GetBuilder == null)
7244                                         return false;
7245                         }
7246                         
7247                         if (!Set.IsDummy){
7248                                 SetBuilder = Set.Define (Parent);
7249                                 if (SetBuilder == null)
7250                                         return false;
7251                         }
7252
7253                         //
7254                         // Now name the parameters
7255                         //
7256                         Parameter [] p = Parameters.FixedParameters;
7257                         if (p != null) {
7258                                 if ((p [0].ModFlags & Parameter.Modifier.ISBYREF) != 0) {
7259                                         Report.Error (631, Location, "ref and out are not valid in this context");
7260                                         return false;
7261                                 }
7262
7263                                 int i;
7264                                 
7265                                 for (i = 0; i < p.Length; ++i) {
7266                                         if (!Get.IsDummy)
7267                                                 GetBuilder.DefineParameter (
7268                                                         i + 1, p [i].Attributes, p [i].Name);
7269
7270                                         if (!Set.IsDummy)
7271                                                 SetBuilder.DefineParameter (
7272                                                         i + 1, p [i].Attributes, p [i].Name);
7273                                 }
7274
7275                                 if (!Set.IsDummy)
7276                                         SetBuilder.DefineParameter (
7277                                                 i + 1, ParameterAttributes.None, "value");
7278                                         
7279                                 if (i != ParameterTypes.Length) {
7280                                         Parameter array_param = Parameters.ArrayParameter;
7281
7282                                         SetBuilder.DefineParameter (
7283                                                 i + 1, array_param.Attributes, array_param.Name);
7284                                 }
7285                         }
7286
7287                         PropertyBuilder = Parent.TypeBuilder.DefineProperty (
7288                                 Name, prop_attr, MemberType, ParameterTypes);
7289                         
7290                         if (!Get.IsDummy)
7291                                 PropertyBuilder.SetGetMethod (GetBuilder);
7292
7293                         if (!Set.IsDummy)
7294                                 PropertyBuilder.SetSetMethod (SetBuilder);
7295                                 
7296                         TypeManager.RegisterIndexer (PropertyBuilder, GetBuilder, SetBuilder, ParameterTypes);
7297
7298                         return true;
7299                 }
7300
7301                 public override string GetSignatureForError ()
7302                 {
7303                         if (PropertyBuilder == null)
7304                                 return GetSignatureForError (Parent);
7305
7306                         return TypeManager.CSharpSignature (PropertyBuilder, true);
7307                 }
7308
7309                 public override string GetSignatureForError(TypeContainer tc)
7310                 {
7311                         return String.Concat (tc.Name, ".this[", Parameters.FixedParameters [0].TypeName.ToString (), ']');
7312                 }
7313
7314                 public override bool MarkForDuplicationCheck ()
7315                 {
7316                         caching_flags |= Flags.TestMethodDuplication;
7317                         return true;
7318                 }
7319
7320         }
7321
7322         public class Operator : MethodCore, IIteratorContainer {
7323
7324                 const int AllowedModifiers =
7325                         Modifiers.PUBLIC |
7326                         Modifiers.UNSAFE |
7327                         Modifiers.EXTERN |
7328                         Modifiers.STATIC;
7329
7330                 public enum OpType : byte {
7331
7332                         // Unary operators
7333                         LogicalNot,
7334                         OnesComplement,
7335                         Increment,
7336                         Decrement,
7337                         True,
7338                         False,
7339
7340                         // Unary and Binary operators
7341                         Addition,
7342                         Subtraction,
7343
7344                         UnaryPlus,
7345                         UnaryNegation,
7346                         
7347                         // Binary operators
7348                         Multiply,
7349                         Division,
7350                         Modulus,
7351                         BitwiseAnd,
7352                         BitwiseOr,
7353                         ExclusiveOr,
7354                         LeftShift,
7355                         RightShift,
7356                         Equality,
7357                         Inequality,
7358                         GreaterThan,
7359                         LessThan,
7360                         GreaterThanOrEqual,
7361                         LessThanOrEqual,
7362
7363                         // Implicit and Explicit
7364                         Implicit,
7365                         Explicit
7366                 };
7367
7368                 public readonly OpType OperatorType;
7369                 public MethodBuilder   OperatorMethodBuilder;
7370                 
7371                 public Method OperatorMethod;
7372
7373                 static string[] attribute_targets = new string [] { "method", "return" };
7374
7375                 public Operator (TypeContainer parent, OpType type, Expression ret_type,
7376                                  int mod_flags, Parameters parameters,
7377                                  ToplevelBlock block, Attributes attrs, Location loc)
7378                         : base (parent, ret_type, mod_flags, AllowedModifiers, false,
7379                                 new MemberName ("op_" + type), attrs, parameters, loc)
7380                 {
7381                         OperatorType = type;
7382                         Block = block;
7383                 }
7384
7385                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb) 
7386                 {
7387                         OperatorMethod.ApplyAttributeBuilder (a, cb);
7388                 }
7389
7390                 public override AttributeTargets AttributeTargets {
7391                         get {
7392                                 return AttributeTargets.Method; 
7393                         }
7394                 }
7395                 
7396                 protected override bool CheckForDuplications()
7397                 {
7398                         ArrayList ar = Parent.Operators;
7399                         if (ar != null) {
7400                                 int arLen = ar.Count;
7401                                         
7402                                 for (int i = 0; i < arLen; i++) {
7403                                         Operator o = (Operator) ar [i];
7404                                         if (IsDuplicateImplementation (o))
7405                                                 return false;
7406                                 }
7407                         }
7408
7409                         ar = Parent.Methods;
7410                         if (ar != null) {
7411                                 int arLen = ar.Count;
7412                                         
7413                                 for (int i = 0; i < arLen; i++) {
7414                                         Method m = (Method) ar [i];
7415                                         if (IsDuplicateImplementation (m))
7416                                                 return false;
7417                                 }
7418                         }
7419
7420                         return true;
7421                 }
7422
7423                 public override bool Define ()
7424                 {
7425
7426                         const int RequiredModifiers = Modifiers.PUBLIC | Modifiers.STATIC;
7427                         if ((ModFlags & RequiredModifiers) != RequiredModifiers){
7428                                 Report.Error (558, Location, "User defined operators '{0}' must be declared static and public", GetSignatureForError (Parent));
7429                                 return false;
7430                         }
7431
7432                         if (!DoDefine ())
7433                                 return false;
7434
7435                         if (MemberType == TypeManager.void_type) {
7436                                 Report.Error (590, Location, "User-defined operators cannot return void");
7437                                 return false;
7438                         }
7439
7440                         OperatorMethod = new Method (
7441                                 Parent, Type, ModFlags, false, MemberName,
7442                                 Parameters, OptAttributes, Location);
7443
7444                         OperatorMethod.Block = Block;
7445                         OperatorMethod.IsOperator = true;                       
7446                         OperatorMethod.flags |= MethodAttributes.SpecialName | MethodAttributes.HideBySig;
7447                         OperatorMethod.Define ();
7448
7449                         if (OperatorMethod.MethodBuilder == null)
7450                                 return false;
7451
7452                         OperatorMethodBuilder = OperatorMethod.MethodBuilder;
7453
7454                         parameter_types = OperatorMethod.ParameterTypes;
7455                         Type declaring_type = OperatorMethodBuilder.DeclaringType;
7456                         Type return_type = OperatorMethod.ReturnType;
7457                         Type first_arg_type = parameter_types [0];
7458
7459                         if (!CheckBase ())
7460                                 return false;
7461
7462                         // Rules for conversion operators
7463                         
7464                         if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
7465                                 if (first_arg_type == return_type && first_arg_type == declaring_type){
7466                                         Report.Error (
7467                                                 555, Location,
7468                                                 "User-defined conversion cannot take an object of the " +
7469                                                 "enclosing type and convert to an object of the enclosing" +
7470                                                 " type");
7471                                         return false;
7472                                 }
7473                                 
7474                                 if (first_arg_type != declaring_type && return_type != declaring_type){
7475                                         Report.Error (
7476                                                 556, Location, 
7477                                                 "User-defined conversion must convert to or from the " +
7478                                                 "enclosing type");
7479                                         return false;
7480                                 }
7481                                 
7482                                 if (first_arg_type == TypeManager.object_type ||
7483                                         return_type == TypeManager.object_type){
7484                                         Report.Error (
7485                                                 -8, Location,
7486                                                 "User-defined conversion cannot convert to or from " +
7487                                                 "object type");
7488                                         return false;
7489                                 }
7490
7491                                 if (first_arg_type.IsInterface || return_type.IsInterface){
7492                                         Report.Error (
7493                                                 552, Location,
7494                                                 "User-defined conversion cannot convert to or from an " +
7495                                                 "interface type");
7496                                         return false;
7497                                 }
7498                                 
7499                                 if (first_arg_type.IsSubclassOf (return_type)
7500                                         || return_type.IsSubclassOf (first_arg_type)){
7501                                         if (declaring_type.IsSubclassOf (return_type)) {
7502                                                 Report.Error (553, Location, "'{0}' : user defined conversion to/from base class", GetSignatureForError ());
7503                                                 return false;
7504                                         }
7505                                         Report.Error (554, Location, "'{0}' : user defined conversion to/from derived class", GetSignatureForError ());
7506                                         return false;
7507                                 }
7508                         } else if (OperatorType == OpType.LeftShift || OperatorType == OpType.RightShift) {
7509                                 if (first_arg_type != declaring_type || parameter_types [1] != TypeManager.int32_type) {
7510                                         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");
7511                                         return false;
7512                                 }
7513                         } else if (Parameters.FixedParameters.Length == 1) {
7514                                 // Checks for Unary operators
7515
7516                                 if (OperatorType == OpType.Increment || OperatorType == OpType.Decrement) {
7517                                         if (return_type != declaring_type && !return_type.IsSubclassOf (declaring_type)) {
7518                                                 Report.Error (448, Location,
7519                                                         "The return type for ++ or -- operator must be the containing type or derived from the containing type");
7520                                                 return false;
7521                                         }
7522                                         if (first_arg_type != declaring_type) {
7523                                                 Report.Error (
7524                                                         559, Location, "The parameter type for ++ or -- operator must be the containing type");
7525                                                 return false;
7526                                         }
7527                                 }
7528                                 
7529                                 if (first_arg_type != declaring_type){
7530                                         Report.Error (
7531                                                 562, Location,
7532                                                 "The parameter of a unary operator must be the " +
7533                                                 "containing type");
7534                                         return false;
7535                                 }
7536                                 
7537                                 if (OperatorType == OpType.True || OperatorType == OpType.False) {
7538                                         if (return_type != TypeManager.bool_type){
7539                                                 Report.Error (
7540                                                         215, Location,
7541                                                         "The return type of operator True or False " +
7542                                                         "must be bool");
7543                                                 return false;
7544                                         }
7545                                 }
7546                                 
7547                         } else {
7548                                 // Checks for Binary operators
7549                                 
7550                                 if (first_arg_type != declaring_type &&
7551                                     parameter_types [1] != declaring_type){
7552                                         Report.Error (
7553                                                 563, Location,
7554                                                 "One of the parameters of a binary operator must " +
7555                                                 "be the containing type");
7556                                         return false;
7557                                 }
7558                         }
7559
7560                         return true;
7561                 }
7562                 
7563                 public override void Emit ()
7564                 {
7565                         //
7566                         // abstract or extern methods have no bodies
7567                         //
7568                         if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
7569                                 return;
7570                         
7571                         OperatorMethod.Emit ();
7572                         Block = null;
7573                 }
7574
7575                 // Operator cannot be override
7576                 protected override MethodInfo FindOutBaseMethod (TypeContainer container, ref Type base_ret_type)
7577                 {
7578                         return null;
7579                 }
7580
7581                 public static string GetName (OpType ot)
7582                 {
7583                         switch (ot){
7584                         case OpType.LogicalNot:
7585                                 return "!";
7586                         case OpType.OnesComplement:
7587                                 return "~";
7588                         case OpType.Increment:
7589                                 return "++";
7590                         case OpType.Decrement:
7591                                 return "--";
7592                         case OpType.True:
7593                                 return "true";
7594                         case OpType.False:
7595                                 return "false";
7596                         case OpType.Addition:
7597                                 return "+";
7598                         case OpType.Subtraction:
7599                                 return "-";
7600                         case OpType.UnaryPlus:
7601                                 return "+";
7602                         case OpType.UnaryNegation:
7603                                 return "-";
7604                         case OpType.Multiply:
7605                                 return "*";
7606                         case OpType.Division:
7607                                 return "/";
7608                         case OpType.Modulus:
7609                                 return "%";
7610                         case OpType.BitwiseAnd:
7611                                 return "&";
7612                         case OpType.BitwiseOr:
7613                                 return "|";
7614                         case OpType.ExclusiveOr:
7615                                 return "^";
7616                         case OpType.LeftShift:
7617                                 return "<<";
7618                         case OpType.RightShift:
7619                                 return ">>";
7620                         case OpType.Equality:
7621                                 return "==";
7622                         case OpType.Inequality:
7623                                 return "!=";
7624                         case OpType.GreaterThan:
7625                                 return ">";
7626                         case OpType.LessThan:
7627                                 return "<";
7628                         case OpType.GreaterThanOrEqual:
7629                                 return ">=";
7630                         case OpType.LessThanOrEqual:
7631                                 return "<=";
7632                         case OpType.Implicit:
7633                                 return "implicit";
7634                         case OpType.Explicit:
7635                                 return "explicit";
7636                         default: return "";
7637                         }
7638                 }
7639
7640                 public override string GetSignatureForError (TypeContainer tc)
7641                 {
7642                         StringBuilder sb = new StringBuilder ();
7643                         sb.AppendFormat ("{0}.operator {1} {2}({3}", tc.Name, GetName (OperatorType), Type.Type == null ? Type.ToString () : TypeManager.CSharpName (Type.Type),
7644                                 Parameters.FixedParameters [0].GetSignatureForError ());
7645                         
7646                         if (Parameters.FixedParameters.Length > 1) {
7647                                 sb.Append (",");
7648                                 sb.Append (Parameters.FixedParameters [1].GetSignatureForError ());
7649                         }
7650                         sb.Append (")");
7651                         return sb.ToString ();
7652                 }
7653
7654                 public override string GetSignatureForError ()
7655                 {
7656                         return ToString ();
7657                 }
7658
7659                 public override bool MarkForDuplicationCheck ()
7660                 {
7661                         caching_flags |= Flags.TestMethodDuplication;
7662                         return true;
7663                 }
7664
7665                 public override string ToString ()
7666                 {
7667                         if (OperatorMethod == null)
7668                                 return Name;
7669
7670                         Type return_type = OperatorMethod.ReturnType;
7671                         Type [] param_types = OperatorMethod.ParameterTypes;
7672                         
7673                         if (Parameters.FixedParameters.Length == 1)
7674                                 return String.Format (
7675                                         "{0} operator {1}({2})",
7676                                         TypeManager.CSharpName (return_type),
7677                                         GetName (OperatorType),
7678                                         param_types [0]);
7679                         else
7680                                 return String.Format (
7681                                         "{0} operator {1}({2}, {3})",
7682                                         TypeManager.CSharpName (return_type),
7683                                         GetName (OperatorType),
7684                                         param_types [0], param_types [1]);
7685                 }
7686
7687                 public override string[] ValidAttributeTargets {
7688                         get {
7689                                 return attribute_targets;
7690                         }
7691                 }
7692
7693                 public void SetYields ()
7694                 {
7695                         ModFlags |= Modifiers.METHOD_YIELDS;
7696                 }
7697         }
7698
7699         //
7700         // This is used to compare method signatures
7701         //
7702         struct MethodSignature {
7703                 public string Name;
7704                 public Type RetType;
7705                 public Type [] Parameters;
7706                 
7707                 /// <summary>
7708                 ///    This delegate is used to extract methods which have the
7709                 ///    same signature as the argument
7710                 /// </summary>
7711                 public static MemberFilter method_signature_filter = new MemberFilter (MemberSignatureCompare);
7712                 
7713                 public MethodSignature (string name, Type ret_type, Type [] parameters)
7714                 {
7715                         Name = name;
7716                         RetType = ret_type;
7717
7718                         if (parameters == null)
7719                                 Parameters = TypeManager.NoTypes;
7720                         else
7721                                 Parameters = parameters;
7722                 }
7723
7724                 public override string ToString ()
7725                 {
7726                         string pars = "";
7727                         if (Parameters.Length != 0){
7728                                 System.Text.StringBuilder sb = new System.Text.StringBuilder ();
7729                                 for (int i = 0; i < Parameters.Length; i++){
7730                                         sb.Append (Parameters [i]);
7731                                         if (i+1 < Parameters.Length)
7732                                                 sb.Append (", ");
7733                                 }
7734                                 pars = sb.ToString ();
7735                         }
7736
7737                         return String.Format ("{0} {1} ({2})", RetType, Name, pars);
7738                 }
7739                 
7740                 public override int GetHashCode ()
7741                 {
7742                         return Name.GetHashCode ();
7743                 }
7744
7745                 public override bool Equals (Object o)
7746                 {
7747                         MethodSignature other = (MethodSignature) o;
7748
7749                         if (other.Name != Name)
7750                                 return false;
7751
7752                         if (other.RetType != RetType)
7753                                 return false;
7754                         
7755                         if (Parameters == null){
7756                                 if (other.Parameters == null)
7757                                         return true;
7758                                 return false;
7759                         }
7760
7761                         if (other.Parameters == null)
7762                                 return false;
7763                         
7764                         int c = Parameters.Length;
7765                         if (other.Parameters.Length != c)
7766                                 return false;
7767
7768                         for (int i = 0; i < c; i++)
7769                                 if (other.Parameters [i] != Parameters [i])
7770                                         return false;
7771
7772                         return true;
7773                 }
7774
7775                 static bool MemberSignatureCompare (MemberInfo m, object filter_criteria)
7776                 {
7777                         MethodSignature sig = (MethodSignature) filter_criteria;
7778
7779                         if (m.Name != sig.Name)
7780                                 return false;
7781
7782                         Type ReturnType;
7783                         MethodInfo mi = m as MethodInfo;
7784                         PropertyInfo pi = m as PropertyInfo;
7785
7786                         if (mi != null)
7787                                 ReturnType = mi.ReturnType;
7788                         else if (pi != null)
7789                                 ReturnType = pi.PropertyType;
7790                         else
7791                                 return false;
7792                         
7793                         //
7794                         // we use sig.RetType == null to mean `do not check the
7795                         // method return value.  
7796                         //
7797                         if (sig.RetType != null)
7798                                 if (ReturnType != sig.RetType)
7799                                         return false;
7800
7801                         Type [] args;
7802                         if (mi != null)
7803                                 args = TypeManager.GetArgumentTypes (mi);
7804                         else
7805                                 args = TypeManager.GetArgumentTypes (pi);
7806                         Type [] sigp = sig.Parameters;
7807
7808                         if (args.Length != sigp.Length)
7809                                 return false;
7810
7811                         for (int i = args.Length; i > 0; ){
7812                                 i--;
7813                                 if (args [i] != sigp [i])
7814                                         return false;
7815                         }
7816                         return true;
7817                 }
7818         }
7819 }