Use Mono_IsInflatedMethod.
[mono.git] / mcs / gmcs / class.cs
1 //
2 // class.cs: Class and Struct handlers
3 //
4 // Authors: Miguel de Icaza (miguel@gnu.org)
5 //          Martin Baulig (martin@gnome.org)
6 //
7 // Licensed under the terms of the GNU GPL
8 //
9 // (C) 2001, 2002, 2003 Ximian, Inc (http://www.ximian.com)
10 //
11 //
12 //  2002-10-11  Miguel de Icaza  <miguel@ximian.com>
13 //
14 //      * class.cs: Following the comment from 2002-09-26 to AddMethod, I
15 //      have fixed a remaining problem: not every AddXXXX was adding a
16 //      fully qualified name.  
17 //
18 //      Now everyone registers a fully qualified name in the DeclSpace as
19 //      being defined instead of the partial name.  
20 //
21 //      Downsides: we are slower than we need to be due to the excess
22 //      copies and the names being registered this way.  
23 //
24 //      The reason for this is that we currently depend (on the corlib
25 //      bootstrap for instance) that types are fully qualified, because
26 //      we dump all the types in the namespace, and we should really have
27 //      types inserted into the proper namespace, so we can only store the
28 //      basenames in the defined_names array.
29 //
30 //
31 #define CACHE
32 using System;
33 using System.Collections;
34 using System.Reflection;
35 using System.Reflection.Emit;
36 using System.Runtime.CompilerServices;
37
38 namespace Mono.CSharp {
39
40         /// <summary>
41         ///   This is the base class for structs and classes.  
42         /// </summary>
43         public class TypeContainer : DeclSpace, IMemberContainer {
44                 // Holds a list of classes and structures
45                 ArrayList types;
46
47                 // Holds the list of properties
48                 ArrayList properties;
49
50                 // Holds the list of enumerations
51                 ArrayList enums;
52
53                 // Holds the list of delegates
54                 ArrayList delegates;
55                 
56                 // Holds the list of constructors
57                 ArrayList instance_constructors;
58
59                 // Holds the list of fields
60                 ArrayList fields;
61
62                 // Holds a list of fields that have initializers
63                 ArrayList initialized_fields;
64
65                 // Holds a list of static fields that have initializers
66                 ArrayList initialized_static_fields;
67
68                 // Holds the list of constants
69                 ArrayList constants;
70
71                 // Holds the list of
72                 ArrayList interfaces;
73
74                 // Holds order in which interfaces must be closed
75                 ArrayList interface_order;
76                 
77                 // Holds the methods.
78                 ArrayList methods;
79
80                 // Holds the events
81                 ArrayList events;
82
83                 // Holds the indexers
84                 ArrayList indexers;
85
86                 // Holds the operators
87                 ArrayList operators;
88
89                 // The emit context for toplevel objects.
90                 EmitContext ec;
91                 
92                 //
93                 // Pointers to the default constructor and the default static constructor
94                 //
95                 Constructor default_constructor;
96                 Constructor default_static_constructor;
97
98                 //
99                 // Whether we have seen a static constructor for this class or not
100                 //
101                 public bool UserDefinedStaticConstructor = false;
102
103                 //
104                 // Whether we have at least one non-static field
105                 //
106                 bool have_nonstatic_fields = false;
107                 
108                 //
109                 // This one is computed after we can distinguish interfaces
110                 // from classes from the arraylist `type_bases' 
111                 //
112                 string     base_class_name;
113
114                 ArrayList type_bases;
115
116                 bool members_defined;
117                 bool members_defined_ok;
118
119                 // Information in the case we are an attribute type
120
121                 public AttributeTargets Targets = AttributeTargets.All;
122                 public bool AllowMultiple = false;
123                 public bool Inherited;
124
125                 // The interfaces we implement.
126                 TypeExpr [] ifaces;
127
128                 // The parent member container and our member cache
129                 IMemberContainer parent_container;
130                 MemberCache member_cache;
131
132                 //
133                 // The indexer name for this class
134                 //
135                 public string IndexerName;
136
137                 Type GenericType;
138
139                 public TypeContainer ():
140                         this (null, null, "", null, new Location (-1)) {
141                 }
142
143                 public TypeContainer (NamespaceEntry ns, TypeContainer parent, string name, Attributes attrs, Location l)
144                         : base (ns, parent, name, attrs, l)
145                 {
146                         types = new ArrayList ();
147
148                         base_class_name = null;
149                 }
150
151                 public AdditionResult AddConstant (Const constant)
152                 {
153                         AdditionResult res;
154                         string basename = constant.Name;
155                         string fullname = Name + "." + basename;
156
157                         if ((res = IsValid (basename, fullname)) != AdditionResult.Success)
158                                 return res;
159                         
160                         if (constants == null)
161                                 constants = new ArrayList ();
162
163                         constants.Add (constant);
164                         DefineName (fullname, constant);
165
166                         return AdditionResult.Success;
167                 }
168
169                 public AdditionResult AddEnum (Mono.CSharp.Enum e)
170                 {
171                         AdditionResult res;
172
173                         if ((res = IsValid (e.Basename, e.Name)) != AdditionResult.Success)
174                                 return res;
175
176                         if (enums == null)
177                                 enums = new ArrayList ();
178
179                         enums.Add (e);
180                         DefineName (e.Name, e);
181
182                         return AdditionResult.Success;
183                 }
184                 
185                 public AdditionResult AddClass (Class c)
186                 {
187                         AdditionResult res;
188                         string name = c.Basename;
189                         
190                         if ((res = IsValid (name, c.Name)) != AdditionResult.Success)
191                                 return res;
192
193                         DefineName (c.Name, c);
194                         types.Add (c);
195
196                         return AdditionResult.Success;
197                 }
198
199                 public AdditionResult AddStruct (Struct s)
200                 {
201                         AdditionResult res;
202                         string name = s.Basename;
203                         
204                         if ((res = IsValid (name, s.Name)) != AdditionResult.Success)
205                                 return res;
206
207                         DefineName (s.Name, s);
208                         types.Add (s);
209
210                         return AdditionResult.Success;
211                 }
212
213                 public AdditionResult AddDelegate (Delegate d)
214                 {
215                         AdditionResult res;
216                         string name = d.Basename;
217                         
218                         if ((res = IsValid (name, d.Name)) != AdditionResult.Success)
219                                 return res;
220
221                         if (delegates == null)
222                                 delegates = new ArrayList ();
223                         
224                         DefineName (d.Name, d);
225                         delegates.Add (d);
226
227                         return AdditionResult.Success;
228                 }
229
230                 public AdditionResult AddMethod (Method method)
231                 {
232                         string basename = method.Name;
233                         string fullname = Name + "." + basename;
234
235                         Object value = defined_names [fullname];
236
237                         if (value != null && (!(value is Method)))
238                                 return AdditionResult.NameExists;
239
240                         if (basename == Basename)
241                                 return AdditionResult.EnclosingClash;
242
243                         if (methods == null)
244                                 methods = new ArrayList ();
245
246                         if (method.Name.IndexOf ('.') != -1)
247                                 methods.Insert (0, method);
248                         else 
249                                 methods.Add (method);
250                         
251                         if (value == null)
252                                 DefineName (fullname, method);
253
254                         return AdditionResult.Success;
255                 }
256
257                 public AdditionResult AddConstructor (Constructor c)
258                 {
259                         if (c.Name != Basename) 
260                                 return AdditionResult.NotAConstructor;
261
262                         bool is_static = (c.ModFlags & Modifiers.STATIC) != 0;
263                         
264                         if (is_static){
265                                 UserDefinedStaticConstructor = true;
266                                 if (default_static_constructor != null)
267                                         return AdditionResult.MethodExists;
268
269                                 default_static_constructor = c;
270                         } else {
271                                 if (c.IsDefault ()){
272                                         if (default_constructor != null)
273                                                 return AdditionResult.MethodExists;
274                                         default_constructor = c;
275                                 }
276                                 
277                                 if (instance_constructors == null)
278                                         instance_constructors = new ArrayList ();
279                                 
280                                 instance_constructors.Add (c);
281                         }
282                         
283                         return AdditionResult.Success;
284                 }
285                 
286                 public AdditionResult AddInterface (Interface iface)
287                 {
288                         AdditionResult res;
289                         string name = iface.Basename;
290                         
291                         if ((res = IsValid (name, iface.Name)) != AdditionResult.Success)
292                                 return res;
293                         
294                         if (interfaces == null)
295                                 interfaces = new ArrayList ();
296                         interfaces.Add (iface);
297                         DefineName (iface.Name, iface);
298                         
299                         return AdditionResult.Success;
300                 }
301
302                 public AdditionResult AddField (Field field)
303                 {
304                         AdditionResult res;
305                         string basename = field.Name;
306                         string fullname = Name + "." + basename;
307
308                         if ((res = IsValid (basename, fullname)) != AdditionResult.Success)
309                                 return res;
310                         
311                         if (fields == null)
312                                 fields = new ArrayList ();
313                         
314                         fields.Add (field);
315                         
316                         if (field.HasInitializer){
317                                 if ((field.ModFlags & Modifiers.STATIC) != 0){
318                                         if (initialized_static_fields == null)
319                                                 initialized_static_fields = new ArrayList ();
320
321                                         initialized_static_fields.Add (field);
322
323                                 } else {
324                                         if (initialized_fields == null)
325                                                 initialized_fields = new ArrayList ();
326                                 
327                                         initialized_fields.Add (field);
328                                 }
329                         }
330
331                         if ((field.ModFlags & Modifiers.STATIC) == 0)
332                                 have_nonstatic_fields = true;
333
334                         DefineName (fullname, field);
335                         return AdditionResult.Success;
336                 }
337
338                 public AdditionResult AddProperty (Property prop)
339                 {
340                         AdditionResult res;
341
342                         if ((res = AddProperty (prop, prop.Name)) != AdditionResult.Success)
343                                 return res;
344
345                         if (prop.Get != null) {
346                                 if ((res = AddProperty (prop, "get_" + prop.Name)) != AdditionResult.Success)
347                                         return res;
348                         }
349
350                         if (prop.Set != null) {
351                                 if ((res = AddProperty (prop, "set_" + prop.Name)) != AdditionResult.Success)
352                                 return res;
353                         }
354
355                         if (properties == null)
356                                 properties = new ArrayList ();
357
358                         if (prop.Name.IndexOf ('.') != -1)
359                                 properties.Insert (0, prop);
360                         else
361                                 properties.Add (prop);
362
363                         return AdditionResult.Success;
364                 }
365
366                 AdditionResult AddProperty (Property prop, string basename)
367                 {
368                         AdditionResult res;
369                         string fullname = Name + "." + basename;
370
371                         if ((res = IsValid (basename, fullname)) != AdditionResult.Success)
372                                 return res;
373
374                         DefineName (fullname, prop);
375
376                         return AdditionResult.Success;
377                 }
378
379                 public AdditionResult AddEvent (Event e)
380                 {
381                         AdditionResult res;
382                         string basename = e.Name;
383                         string fullname = Name + "." + basename;
384
385                         if ((res = IsValid (basename, fullname)) != AdditionResult.Success)
386                                 return res;
387
388                         if (events == null)
389                                 events = new ArrayList ();
390                         
391                         events.Add (e);
392                         DefineName (fullname, e);
393
394                         return AdditionResult.Success;
395                 }
396
397                 public void AddIndexer (Indexer i)
398                 {
399                         if (indexers == null)
400                                 indexers = new ArrayList ();
401
402                         if (i.InterfaceType != null)
403                                 indexers.Insert (0, i);
404                         else
405                                 indexers.Add (i);
406                 }
407
408                 public AdditionResult AddOperator (Operator op)
409                 {
410                         if (operators == null)
411                                 operators = new ArrayList ();
412
413                         operators.Add (op);
414
415                         string basename = op.Name;
416                         string fullname = Name + "." + basename;
417                         if (!defined_names.Contains (fullname))
418                         {
419                                 DefineName (fullname, op);
420                         }
421                         return AdditionResult.Success;
422                 }
423
424                 public void RegisterOrder (Interface iface)
425                 {
426                         if (interface_order == null)
427                                 interface_order = new ArrayList ();
428
429                         interface_order.Add (iface);
430                 }
431                 
432                 public ArrayList Types {
433                         get {
434                                 return types;
435                         }
436                 }
437
438                 public ArrayList Methods {
439                         get {
440                                 return methods;
441                         }
442                 }
443
444                 public ArrayList Constants {
445                         get {
446                                 return constants;
447                         }
448                 }
449
450                 public ArrayList Interfaces {
451                         get {
452                                 return interfaces;
453                         }
454                 }
455                 
456                 public string Base {
457                         get {
458                                 return base_class_name;
459                         }
460                 }
461                 
462                 public ArrayList Bases {
463                         get {
464                                 return type_bases;
465                         }
466
467                         set {
468                                 type_bases = value;
469                         }
470                 }
471
472                 public ArrayList Fields {
473                         get {
474                                 return fields;
475                         }
476
477                         set {
478                                 fields = value;
479                         }
480                 }
481
482                 public ArrayList InstanceConstructors {
483                         get {
484                                 return instance_constructors;
485                         }
486                 }
487
488                 public ArrayList Properties {
489                         get {
490                                 return properties;
491                         }
492                 }
493
494                 public ArrayList Events {
495                         get {
496                                 return events;
497                         }
498                 }
499                 
500                 public ArrayList Enums {
501                         get {
502                                 return enums;
503                         }
504                 }
505
506                 public ArrayList Indexers {
507                         get {
508                                 return indexers;
509                         }
510                 }
511
512                 public ArrayList Operators {
513                         get {
514                                 return operators;
515                         }
516                 }
517
518                 public ArrayList Delegates {
519                         get {
520                                 return delegates;
521                         }
522                 }
523                 
524                 public virtual TypeAttributes TypeAttr {
525                         get {
526                                 return Modifiers.TypeAttr (ModFlags, this);
527                         }
528                 }
529
530                 //
531                 // Emits the instance field initializers
532                 //
533                 public bool EmitFieldInitializers (EmitContext ec)
534                 {
535                         ArrayList fields;
536                         Expression instance_expr;
537                         
538                         if (ec.IsStatic){
539                                 fields = initialized_static_fields;
540                                 instance_expr = null;
541                         } else {
542                                 fields = initialized_fields;
543                                 instance_expr = new This (Location.Null).Resolve (ec);
544                         }
545
546                         if (fields == null)
547                                 return true;
548
549                         foreach (Field f in fields){
550                                 Expression e = f.GetInitializerExpression (ec);
551                                 if (e == null)
552                                         return false;
553
554                                 Location l = f.Location;
555                                 FieldExpr fe = new FieldExpr (f.FieldBuilder, l);
556                                 fe.InstanceExpression = instance_expr;
557                                 ExpressionStatement a = new Assign (fe, e, l);
558
559                                 a = a.ResolveStatement (ec);
560                                 if (a == null)
561                                         return false;
562
563                                 a.EmitStatement (ec);
564                         }
565
566                         return true;
567                 }
568                 
569                 //
570                 // Defines the default constructors
571                 //
572                 void DefineDefaultConstructor (bool is_static)
573                 {
574                         Constructor c;
575
576                         // The default constructor is public
577                         // If the class is abstract, the default constructor is protected
578                         // The default static constructor is private
579
580                         int mods = Modifiers.PUBLIC;
581                         if (is_static)
582                                 mods = Modifiers.STATIC | Modifiers.PRIVATE;
583                         else if ((ModFlags & Modifiers.ABSTRACT) != 0)
584                                 mods = Modifiers.PROTECTED;
585
586                         c = new Constructor (this, Basename, mods, Parameters.EmptyReadOnlyParameters,
587                                              new ConstructorBaseInitializer (
588                                                      null, Parameters.EmptyReadOnlyParameters,
589                                                      Location),
590                                              Location);
591                         
592                         AddConstructor (c);
593                         
594                         c.Block = new ToplevelBlock (null, Location);
595                         
596                 }
597
598                 public void ReportStructInitializedInstanceError ()
599                 {
600                         string n = TypeBuilder.FullName;
601                         
602                         foreach (Field f in initialized_fields){
603                                 Report.Error (
604                                         573, Location,
605                                         "`" + n + "." + f.Name + "': can not have " +
606                                         "instance field initializers in structs");
607                         }
608                 }
609
610                 /// <remarks>
611                 ///  The pending methods that need to be implemented (interfaces or abstract methods)
612                 /// </remarks>
613                 public PendingImplementation Pending;
614
615                 /// <summary>
616                 ///   This function computes the Base class and also the
617                 ///   list of interfaces that the class or struct @c implements.
618                 ///   
619                 ///   The return value is an array (might be null) of
620                 ///   interfaces implemented (as Types).
621                 ///   
622                 ///   The @parent argument is set to the parent object or null
623                 ///   if this is `System.Object'. 
624                 /// </summary>
625                 TypeExpr [] GetClassBases (bool is_class, bool is_iface,
626                                            out TypeExpr parent, out bool error)
627                 {
628                         ArrayList bases = Bases;
629                         int count;
630                         int start, j, i;
631
632                         error = false;
633
634                         if (is_class || is_iface)
635                                 parent = null;
636                         else
637                                 parent = TypeManager.system_valuetype_expr;
638
639                         if (bases == null){
640                                 if (is_class){
641                                         if (RootContext.StdLib)
642                                                 parent = TypeManager.system_object_expr;
643                                         else if (Name != "System.Object")
644                                                 parent = TypeManager.system_object_expr;
645                                 } else {
646                                         //
647                                         // If we are compiling our runtime,
648                                         // and we are defining ValueType, then our
649                                         // parent is `System.Object'.
650                                         //
651                                         if (!RootContext.StdLib && Name == "System.ValueType")
652                                                 parent = TypeManager.system_object_expr;
653                                 }
654
655                                 return null;
656                         }
657
658                         //
659                         // Bases should be null if there are no bases at all
660                         //
661                         count = bases.Count;
662
663                         if (is_class){
664                                 TypeExpr name = ResolveTypeExpr ((Expression) bases [0], false, Location);
665
666                                 if (name == null){
667                                         error = true;
668                                         return null;
669                                 }
670
671                                 if (name is TypeParameterExpr){
672                                         Report.Error (
673                                                 689, name.Location,
674                                                 "Type parameter `{0}' can not be used as a " +
675                                                 "base class or interface", name.Name);
676                                         error = true;
677                                         return null;
678                                 }
679
680                                 if (IsGeneric && name.IsAttribute){
681                                         Report.Error (
682                                                 698, name.Location,
683                                                 "A generic type cannot derive from `{0}' " +
684                                                 "because it is an attribute class", name.Name);
685                                         error = true;
686                                         return null;
687                                 }
688
689                                 if (name.IsClass){
690                                         parent = name;
691                                         start = 1;
692                                 } else {
693                                         parent = TypeManager.system_object_expr;
694                                         start = 0;
695                                 }
696                                 if (name.IsSealed){
697                                         string detail = "";
698                                         
699                                         if (name.IsValueType)
700                                                 detail = " (a class can not inherit from a struct/enum)";
701                                         
702                                         Report.Error (509, "class `"+ Name +
703                                                       "': Cannot inherit from sealed class `"+
704                                                       name.Name + "'" + detail);
705                                         error = true;
706                                         return null;
707                                 }
708
709                                 if (!parent.CanInheritFrom ()){
710                                         Report.Error (644, Location,
711                                                       "`{0}' cannot inherit from special class `{1}'",
712                                                       Name, parent.Name);
713                                         error = true;
714                                         return null;
715                                 }
716
717                                 if (!parent.AsAccessible (this, ModFlags))
718                                         Report.Error (60, Location,
719                                                       "Inconsistent accessibility: base class `" +
720                                                       name.Name + "' is less accessible than class `" +
721                                                       Name + "'");
722
723                         } else {
724                                 start = 0;
725                         }
726
727                         if (parent != null)
728                                 base_class_name = parent.Name;
729
730                         TypeExpr [] ifaces = new TypeExpr [count-start];
731
732                         for (i = start, j = 0; i < count; i++, j++){
733                                 Expression name = (Expression) bases [i];
734                                 TypeExpr resolved = ResolveTypeExpr (name, false, Location);
735
736                                 if (resolved == null)
737                                         return null;
738                                 
739                                 bases [i] = resolved;
740
741                                 if (is_class == false && !resolved.IsInterface){
742                                         Report.Error (527, "In Struct `" + Name + "', type `"+
743                                                       name +"' is not an interface");
744                                         error = true;
745                                         return null;
746                                 }
747                                 
748                                 if (resolved.IsClass) {
749                                         if (parent != null){
750                                                 Report.Error (527, "In Class `" + Name + "', type `"+
751                                                               name+"' is not an interface");
752                                                 error = true;
753                                                 return null;
754                                         }
755                                 }
756
757                                 for (int x = 0; x < j; x++) {
758                                         if (resolved.Equals (ifaces [x])) {
759                                                 Report.Error (528, "`" + name + "' is already listed in interface list");
760                                                 error = true;
761                                                 return null;
762                                         }
763                                 }
764
765                                 if (is_iface &&
766                                     !resolved.AsAccessible (Parent, ModFlags))
767                                         Report.Error (61, Location,
768                                                       "Inconsistent accessibility: base interface `" +
769                                                       name + "' is less accessible than interface `" +
770                                                       Name + "'");
771
772                                 ifaces [j] = resolved;
773                         }
774
775                         return TypeManager.ExpandInterfaces (ifaces);
776                 }
777
778                 bool CheckGenericInterfaces (Type[] ifaces)
779                 {
780                         ArrayList already_checked = new ArrayList ();
781
782                         for (int i = 0; i < ifaces.Length; i++) {
783                                 Type iface = ifaces [i];
784                                 foreach (Type t in already_checked) {
785                                         if (iface == t)
786                                                 continue;
787
788                                         if (!TypeManager.MayBecomeEqualGenericInstances (iface, t))
789                                                 continue;
790
791                                         Report.Error (
792                                                 695, Location,
793                                                 "`{0}' cannot implement both `{1}' and `{2}' " +
794                                                 "because they may unify for some type " +
795                                                 "parameter substitutions",
796                                                 TypeManager.GetFullName (TypeBuilder),
797                                                 iface, t);
798                                         return false;
799                                 }
800
801                                 already_checked.Add (iface);
802                         }
803
804                         return true;
805                 }
806
807                 bool error = false;
808                 
809                 //
810                 // Defines the type in the appropriate ModuleBuilder or TypeBuilder.
811                 //
812                 public override TypeBuilder DefineType ()
813                 {
814                         TypeExpr parent;
815                         bool is_class, is_iface;
816
817                         if (TypeBuilder != null)
818                                 return TypeBuilder;
819
820                         if (error)
821                                 return null;
822                         
823                         if (InTransit) {
824                                 Report.Error (146, Location, "Class definition is circular: `{0}'", Name);
825                                 error = true;
826                                 return null;
827                         }
828                         
829                         InTransit = true;
830
831                         if (this is Interface) {
832                                 is_iface = true;
833                                 is_class = false;
834                         } else {
835                                 is_iface = false;
836                         if (this is Class)
837                                 is_class = true;
838                         else
839                                 is_class = false;
840                         }
841
842                         ec = new EmitContext (this, Mono.CSharp.Location.Null, null, null, ModFlags);
843
844                         ifaces = GetClassBases (is_class, is_iface, out parent, out error); 
845
846                         if (error)
847                                 return null;
848
849                         if (IsGeneric) {
850                                 foreach (TypeParameter type_param in TypeParameters)
851                                         if (!type_param.Resolve (this)) {
852                                                 error = true;
853                                                 return null;
854                                         }
855                         }
856                         
857                         if (!is_class && TypeManager.value_type == null)
858                                 throw new Exception ();
859
860                         TypeAttributes type_attributes = TypeAttr;
861
862                         Type ptype;
863                         ConstructedType constructed = parent as ConstructedType;
864                         if ((constructed == null) && (parent != null))
865                                 ptype = parent.ResolveType (ec);
866                         else
867                                 ptype = null;
868
869                         if (IsTopLevel){
870                                 if (TypeManager.NamespaceClash (Name, Location)) {
871                                         error = true;
872                                         return null;
873                                 }
874
875                                 ModuleBuilder builder = CodeGen.Module.Builder;
876                                 TypeBuilder = builder.DefineType (
877                                         Name, type_attributes, ptype, null);
878                                 
879                         } else {
880                                 TypeBuilder builder = Parent.DefineType ();
881                                 if (builder == null)
882                                         return null;
883                                 
884                                 TypeBuilder = builder.DefineNestedType (
885                                         Basename, type_attributes, ptype, null);
886                         }
887
888                         TypeManager.AddUserType (Name, TypeBuilder, this, ifaces);
889
890                         if (IsGeneric) {
891                                 CurrentType = new ConstructedType (
892                                         Name, TypeParameters, Location);
893
894                                 foreach (TypeParameter type_param in TypeParameters)
895                                         type_param.Define (TypeBuilder);
896                         }
897
898                         if (constructed != null) {
899                                 ptype = constructed.ResolveType (ec);
900                                 if (ptype == null)
901                                         return null;
902
903                                 TypeBuilder.SetParent (ptype);
904                         }
905
906                         if (IsGeneric) {
907                                 foreach (TypeParameter type_param in TypeParameters)
908                                         type_param.DefineType (ec, TypeBuilder);
909                         }
910
911                         //
912                         // Structs with no fields need to have at least one byte.
913                         // The right thing would be to set the PackingSize in a DefineType
914                         // but there are no functions that allow interfaces *and* the size to
915                         // be specified.
916                         //
917
918                         if (!is_class && !is_iface && !have_nonstatic_fields){
919                                 TypeBuilder.DefineField ("$PRIVATE$", TypeManager.byte_type,
920                                                          FieldAttributes.Private);
921                         }
922
923                         // add interfaces that were not added at type creation
924                         if (ifaces != null) {
925                                 Type[] itypes = new Type [ifaces.Length];
926                                 for (int i = 0; i < ifaces.Length; i++) {
927                                         itypes [i] = ifaces [i].ResolveType (ec);
928                                         if (itypes [i] == null)
929                                                 error = true;
930                                 }
931
932                                 if (error)
933                                         return null;
934
935                                 if (!CheckGenericInterfaces (itypes)) {
936                                         error = true;
937                                         return null;
938                                 }
939
940                                 for (int i = 0; i < ifaces.Length; i++)
941                                         TypeBuilder.AddInterfaceImplementation (itypes [i]);
942                         }
943
944                         //
945                         // Finish the setup for the EmitContext
946                         //
947                         ec.ContainerType = TypeBuilder;
948
949                         if ((parent != null) && parent.IsAttribute) {
950                                 RootContext.RegisterAttribute (this);
951                                 TypeManager.RegisterAttrType (TypeBuilder, this);
952                         } else
953                                 RootContext.RegisterOrder (this); 
954                                 
955                         if (Interfaces != null) {
956                                 foreach (Interface iface in Interfaces)
957                                         if (iface.DefineType () == null) {
958                                                 error = true;
959                                                 return null;
960                                         }
961                         }
962                         
963                         if (Types != null) {
964                                 foreach (TypeContainer tc in Types)
965                                         if (tc.DefineType () == null) {
966                                                 error = true;
967                                                 return null;
968                                         }
969                         }
970
971                         if (Delegates != null) {
972                                 foreach (Delegate d in Delegates)
973                                         if (d.DefineType () == null) {
974                                                 error = true;
975                                                 return null;
976                                         }
977                         }
978
979                         if (Enums != null) {
980                                 foreach (Enum en in Enums)
981                                         if (en.DefineType () == null) {
982                                                 error = true;
983                                                 return null;
984                                         }
985                         }
986
987                         InTransit = false;
988                         return TypeBuilder;
989                 }
990
991
992                 /// <summary>
993                 ///   Defines the MemberCore objects that are in the `list' Arraylist
994                 ///
995                 ///   The `defined_names' array contains a list of members defined in
996                 ///   a base class
997                 /// </summary>
998                 static ArrayList remove_list = new ArrayList ();
999                 void DefineMembers (ArrayList list, MemberInfo [] defined_names)
1000                 {
1001                         int idx;
1002                         
1003                         remove_list.Clear ();
1004
1005                         foreach (MemberCore mc in list){
1006
1007                                 if (defined_names != null)
1008                                         idx = Array.BinarySearch (defined_names, mc.Name, mif_compare);
1009                                 else
1010                                         idx = -1;
1011
1012                                 if (idx < 0){
1013                                         if (RootContext.WarningLevel >= 4){
1014                                                 if ((mc.ModFlags & Modifiers.NEW) != 0)
1015                                                         Warning_KeywordNewNotRequired (mc.Location, mc);
1016                                         }
1017                                 } else if (mc is MethodCore)
1018                                         ((MethodCore) mc).OverridesSomething = true;
1019
1020                                 if (!mc.Define (this)){
1021                                         remove_list.Add (mc);
1022                                         continue;
1023                                 }
1024                                                 
1025                                 if (idx < 0)
1026                                         continue;
1027
1028                                 MemberInfo match = defined_names [idx];
1029
1030                                 if (match is PropertyInfo && ((mc.ModFlags & Modifiers.OVERRIDE) != 0))
1031                                         continue;
1032
1033                                 //
1034                                 // If we are both methods, let the method resolution emit warnings
1035                                 //
1036                                 if (match is MethodBase && mc is MethodCore)
1037                                         continue; 
1038
1039                                 if ((mc.ModFlags & Modifiers.NEW) == 0) {
1040                                         if (mc is Event) {
1041                                                 if (!(match is EventInfo)) {
1042                                                         Error_EventCanOnlyOverrideEvent (mc.Location, defined_names [idx]);
1043                                                         return;
1044                                                 }
1045
1046                                                 if ((mc.ModFlags & Modifiers.OVERRIDE) != 0)
1047                                                         continue;
1048                                         }
1049
1050                                         Warning_KeywordNewRequired (mc.Location, defined_names [idx]);
1051                                 }
1052                         }
1053                         
1054                         foreach (object o in remove_list)
1055                                 list.Remove (o);
1056                         
1057                         remove_list.Clear ();
1058                 }
1059
1060                 //
1061                 // Defines the indexers, and also verifies that the IndexerNameAttribute in the
1062                 // class is consisten.  Either it is `Item' or it is the name defined by all the
1063                 // indexers with the `IndexerName' attribute.
1064                 //
1065                 // Turns out that the IndexerNameAttribute is applied to each indexer,
1066                 // but it is never emitted, instead a DefaultName attribute is attached
1067                 // to the class.
1068                 //
1069                 void DefineIndexers ()
1070                 {
1071                         string class_indexer_name = null;
1072
1073                         //
1074                         // If there's both an explicit and an implicit interface implementation, the
1075                         // explicit one actually implements the interface while the other one is just
1076                         // a normal indexer.  See bug #37714.
1077                         //
1078
1079                         ArrayList list = new ArrayList ();
1080                         foreach (Indexer i in Indexers){
1081                                 if (i.MemberName.Left != null)
1082                                         list.Add (i);
1083                         }
1084                         foreach (Indexer i in Indexers){
1085                                 if (i.MemberName.Left == null)
1086                                         list.Add (i);
1087                         }
1088
1089                         foreach (Indexer i in list){
1090                                 string name;
1091
1092                                 i.Define (this);
1093
1094                                 name = i.IndexerName;
1095
1096                                 if (i.InterfaceType != null)
1097                                         continue;
1098
1099                                 if (class_indexer_name == null){
1100                                         class_indexer_name = name;
1101                                         continue;
1102                                 }
1103                                 
1104                                 if (name == class_indexer_name)
1105                                         continue;
1106                                 
1107                                 Report.Error (
1108                                         668, "Two indexers have different names, " +
1109                                         " you should use the same name for all your indexers");
1110                         }
1111                         if (class_indexer_name == null)
1112                                 class_indexer_name = "Item";
1113                         IndexerName = class_indexer_name;
1114                 }
1115
1116                 static void Error_KeywordNotAllowed (Location loc)
1117                 {
1118                         Report.Error (1530, loc, "Keyword new not allowed for namespace elements");
1119                 }
1120
1121                 /// <summary>
1122                 ///   Populates our TypeBuilder with fields and methods
1123                 /// </summary>
1124                 public override bool DefineMembers (TypeContainer container)
1125                 {
1126                         if (members_defined)
1127                                 return members_defined_ok;
1128
1129                         members_defined_ok = DoDefineMembers ();
1130                         members_defined = true;
1131
1132                         return members_defined_ok;
1133                 }
1134
1135                 bool DoDefineMembers ()
1136                 {
1137                         MemberInfo [] defined_names = null;
1138
1139                         //
1140                         // We need to be able to use the member cache while we are checking/defining
1141                         //
1142 #if CACHE
1143                         if (TypeBuilder.BaseType != null)
1144                                 parent_container = TypeManager.LookupMemberContainer (TypeBuilder.BaseType);
1145 #endif
1146
1147                         if (interface_order != null){
1148                                 foreach (Interface iface in interface_order)
1149                                         if ((iface.ModFlags & Modifiers.NEW) == 0)
1150                                                 iface.DefineMembers (this);
1151                                         else
1152                                                 Error_KeywordNotAllowed (iface.Location);
1153                         }
1154
1155                         if (RootContext.WarningLevel > 1){
1156                                 Type ptype;
1157
1158                                 //
1159                                 // This code throws an exception in the comparer
1160                                 // I guess the string is not an object?
1161                                 //
1162                                 ptype = TypeBuilder.BaseType;
1163                                 if (ptype != null){
1164                                         defined_names = (MemberInfo []) FindMembers (
1165                                                 ptype, MemberTypes.All & ~MemberTypes.Constructor,
1166                                                 BindingFlags.Public | BindingFlags.Instance |
1167                                                 BindingFlags.Static, null, null);
1168
1169                                         Array.Sort (defined_names, mif_compare);
1170                                 }
1171                         }
1172
1173                         Class pclass = Parent as Class;
1174                         if (pclass != null) {
1175                                 string pname = null;
1176                                 Type ptype = null;
1177                                 Type t = pclass.TypeBuilder.BaseType;
1178                                 while ((t != null) && (ptype == null)) {
1179                                         pname = t.FullName + "." + Basename;
1180                                         ptype = RootContext.LookupType (this, pname, true, Location.Null);
1181                                         t = t.BaseType;
1182                                 }
1183
1184                                 if ((ModFlags & Modifiers.NEW) != 0) {
1185                                         if (ptype == null)
1186                                                 Report.Warning (109, Location, "The member '" + Name + "' does not hide an " +
1187                                                                 "inherited member. The keyword new is not required.");
1188                                 } else if (ptype != null) {
1189                                         Report.Warning (108, Location, "The keyword new is required on `" +
1190                                                         Name + "' because it hides inherited member '" +
1191                                                         pname + "'.");
1192                                 }
1193                         } else if ((ModFlags & Modifiers.NEW) != 0)
1194                                 Error_KeywordNotAllowed (Location);
1195
1196                         if (constants != null)
1197                                 DefineMembers (constants, defined_names);
1198
1199                         if (fields != null)
1200                                 DefineMembers (fields, defined_names);
1201
1202                         if (this is Class){
1203                                 if (instance_constructors == null){
1204                                         if (default_constructor == null)
1205                                                 DefineDefaultConstructor (false);
1206                                 }
1207
1208                                 if (initialized_static_fields != null &&
1209                                     default_static_constructor == null)
1210                                         DefineDefaultConstructor (true);
1211                         }
1212
1213                         if (this is Struct){
1214                                 //
1215                                 // Structs can not have initialized instance
1216                                 // fields
1217                                 //
1218                                 if (initialized_static_fields != null &&
1219                                     default_static_constructor == null)
1220                                         DefineDefaultConstructor (true);
1221
1222                                 if (initialized_fields != null)
1223                                         ReportStructInitializedInstanceError ();
1224                         }
1225
1226                         if (!(this is Interface))
1227                         Pending = PendingImplementation.GetPendingImplementations (this);
1228                         
1229                         //
1230                         // Constructors are not in the defined_names array
1231                         //
1232                         if (instance_constructors != null)
1233                                 DefineMembers (instance_constructors, null);
1234                 
1235                         if (default_static_constructor != null)
1236                                 default_static_constructor.Define (this);
1237                         
1238                         if (methods != null)
1239                                 DefineMembers (methods, defined_names);
1240
1241                         if (properties != null)
1242                                 DefineMembers (properties, defined_names);
1243
1244                         if (events != null)
1245                                 DefineMembers (events, defined_names);
1246
1247                         if (indexers != null) {
1248                                 DefineIndexers ();
1249                         } else
1250                                 IndexerName = "Item";
1251
1252                         if (operators != null){
1253                                 DefineMembers (operators, null);
1254
1255                                 CheckPairedOperators ();
1256                         }
1257
1258                         if (enums != null)
1259                                 DefineMembers (enums, defined_names);
1260                         
1261                         if (delegates != null)
1262                                 DefineMembers (delegates, defined_names);
1263
1264                         if (CurrentType != null) {
1265                                 GenericType = CurrentType.ResolveType (ec);
1266
1267                                 ec.ContainerType = GenericType;
1268                         }
1269
1270
1271 #if CACHE
1272                         member_cache = new MemberCache (this);
1273 #endif
1274
1275                         
1276                         return true;
1277                 }
1278
1279                 public override bool Define (TypeContainer container)
1280                 {
1281                         if (interface_order != null){
1282                                 foreach (Interface iface in interface_order)
1283                                         if ((iface.ModFlags & Modifiers.NEW) == 0)
1284                                                 iface.Define (this);
1285                         }
1286
1287                         return true;
1288                 }
1289
1290                 /// <summary>
1291                 ///   This function is based by a delegate to the FindMembers routine
1292                 /// </summary>
1293                 static bool AlwaysAccept (MemberInfo m, object filterCriteria)
1294                 {
1295                         return true;
1296                 }
1297
1298                 /// <summary>
1299                 ///   This filter is used by FindMembers, and we just keep
1300                 ///   a global for the filter to `AlwaysAccept'
1301                 /// </summary>
1302                 static MemberFilter accepting_filter;
1303
1304                 
1305                 /// <summary>
1306                 ///   A member comparission method based on name only
1307                 /// </summary>
1308                 static IComparer mif_compare;
1309
1310                 static TypeContainer ()
1311                 {
1312                         accepting_filter = new MemberFilter (AlwaysAccept);
1313                         mif_compare = new MemberInfoCompare ();
1314                 }
1315                 
1316                 public MethodInfo[] GetMethods ()
1317                 {
1318                         ArrayList members = new ArrayList ();
1319
1320                         DefineMembers (null);
1321
1322                         if (methods != null) {
1323                                 int len = methods.Count;
1324                                 for (int i = 0; i < len; i++) {
1325                                         Method m = (Method) methods [i];
1326
1327                                         members.Add (m.MethodBuilder);
1328                                 }
1329                         }
1330
1331                         if (operators != null) {
1332                                 int len = operators.Count;
1333                                 for (int i = 0; i < len; i++) {
1334                                         Operator o = (Operator) operators [i];
1335
1336                                         members.Add (o.OperatorMethodBuilder);
1337                                 }
1338                         }
1339
1340                         if (properties != null) {
1341                                 int len = properties.Count;
1342                                 for (int i = 0; i < len; i++) {
1343                                         Property p = (Property) properties [i];
1344
1345                                         if (p.GetBuilder != null)
1346                                                 members.Add (p.GetBuilder);
1347                                         if (p.SetBuilder != null)
1348                                                 members.Add (p.SetBuilder);
1349                                 }
1350                         }
1351                                 
1352                         if (indexers != null) {
1353                                 int len = indexers.Count;
1354                                 for (int i = 0; i < len; i++) {
1355                                         Indexer ix = (Indexer) indexers [i];
1356
1357                                         if (ix.GetBuilder != null)
1358                                                 members.Add (ix.GetBuilder);
1359                                         if (ix.SetBuilder != null)
1360                                                 members.Add (ix.SetBuilder);
1361                                 }
1362                         }
1363
1364                         if (events != null) {
1365                                 int len = events.Count;
1366                                 for (int i = 0; i < len; i++) {
1367                                         Event e = (Event) events [i];
1368
1369                                         if (e.AddBuilder != null)
1370                                                 members.Add (e.AddBuilder);
1371                                         if (e.RemoveBuilder != null)
1372                                                 members.Add (e.RemoveBuilder);
1373                                 }
1374                         }
1375
1376                         MethodInfo[] methods = new MethodInfo [members.Count];
1377                         members.CopyTo (methods, 0);
1378                         return methods;
1379                 }
1380                 
1381                 /// <summary>
1382                 ///   This method returns the members of this type just like Type.FindMembers would
1383                 ///   Only, we need to use this for types which are _being_ defined because MS' 
1384                 ///   implementation can't take care of that.
1385                 /// </summary>
1386                 //
1387                 // FIXME: return an empty static array instead of null, that cleans up
1388                 // some code and is consistent with some coding conventions I just found
1389                 // out existed ;-)
1390                 //
1391                 //
1392                 // Notice that in various cases we check if our field is non-null,
1393                 // something that would normally mean that there was a bug elsewhere.
1394                 //
1395                 // The problem happens while we are defining p-invoke methods, as those
1396                 // will trigger a FindMembers, but this happens before things are defined
1397                 //
1398                 // Since the whole process is a no-op, it is fine to check for null here.
1399                 //
1400                 public override MemberList FindMembers (MemberTypes mt, BindingFlags bf,
1401                                                         MemberFilter filter, object criteria)
1402                 {
1403                         ArrayList members = null;
1404
1405                         int modflags = 0;
1406                         if ((bf & BindingFlags.Public) != 0)
1407                                 modflags |= Modifiers.PUBLIC | Modifiers.PROTECTED |
1408                                         Modifiers.INTERNAL;
1409                         if ((bf & BindingFlags.NonPublic) != 0)
1410                                 modflags |= Modifiers.PRIVATE;
1411
1412                         int static_mask = 0, static_flags = 0;
1413                         switch (bf & (BindingFlags.Static | BindingFlags.Instance)) {
1414                         case BindingFlags.Static:
1415                                 static_mask = static_flags = Modifiers.STATIC;
1416                                 break;
1417
1418                         case BindingFlags.Instance:
1419                                 static_mask = Modifiers.STATIC;
1420                                 static_flags = 0;
1421                                 break;
1422
1423                         default:
1424                                 static_mask = static_flags = 0;
1425                                 break;
1426                         }
1427
1428                         Timer.StartTimer (TimerType.TcFindMembers);
1429
1430                         if (filter == null)
1431                                 filter = accepting_filter; 
1432
1433                         if ((mt & MemberTypes.Field) != 0) {
1434                                 if (fields != null) {
1435                                         int len = fields.Count;
1436                                         for (int i = 0; i < len; i++) {
1437                                                 Field f = (Field) fields [i];
1438                                                 
1439                                                 if ((f.ModFlags & modflags) == 0)
1440                                                         continue;
1441                                                 if ((f.ModFlags & static_mask) != static_flags)
1442                                                         continue;
1443
1444                                                 FieldBuilder fb = f.FieldBuilder;
1445                                                 if (fb != null && filter (fb, criteria) == true) {
1446                                                         if (members == null)
1447                                                                 members = new ArrayList ();
1448                                                         
1449                                                         members.Add (fb);
1450                                         }
1451                                 }
1452                                 }
1453
1454                                 if (constants != null) {
1455                                         int len = constants.Count;
1456                                         for (int i = 0; i < len; i++) {
1457                                                 Const con = (Const) constants [i];
1458                                                 
1459                                                 if ((con.ModFlags & modflags) == 0)
1460                                                         continue;
1461                                                 if ((con.ModFlags & static_mask) != static_flags)
1462                                                         continue;
1463
1464                                                 FieldBuilder fb = con.FieldBuilder;
1465                                                 if (fb != null && filter (fb, criteria) == true) {
1466                                                         if (members == null)
1467                                                                 members = new ArrayList ();
1468                                                         
1469                                                         members.Add (fb);
1470                                         }
1471                                 }
1472                         }
1473                         }
1474
1475                         if ((mt & MemberTypes.Method) != 0) {
1476                                 if (methods != null) {
1477                                         int len = methods.Count;
1478                                         for (int i = 0; i < len; i++) {
1479                                                 Method m = (Method) methods [i];
1480                                                 
1481                                                 if ((m.ModFlags & modflags) == 0)
1482                                                         continue;
1483                                                 if ((m.ModFlags & static_mask) != static_flags)
1484                                                         continue;
1485                                                 
1486                                                 MethodBuilder mb = m.MethodBuilder;
1487
1488                                                 if (mb != null && filter (mb, criteria) == true) {
1489                                                         if (members == null)
1490                                                                 members = new ArrayList ();
1491                                                         
1492                                                         members.Add (mb);
1493                                         }
1494                                 }
1495                                 }
1496
1497                                 if (operators != null) {
1498                                         int len = operators.Count;
1499                                         for (int i = 0; i < len; i++) {
1500                                                 Operator o = (Operator) operators [i];
1501
1502                                                 if ((o.ModFlags & modflags) == 0)
1503                                                         continue;
1504                                                 if ((o.ModFlags & static_mask) != static_flags)
1505                                                         continue;
1506                                                 
1507                                                 MethodBuilder ob = o.OperatorMethodBuilder;
1508                                                 if (ob != null && filter (ob, criteria) == true) {
1509                                                         if (members == null)
1510                                                                 members = new ArrayList ();
1511                                                         
1512                                                         members.Add (ob);
1513                                         }
1514                                 }
1515                                 }
1516
1517                                 if (properties != null) {
1518                                         int len = properties.Count;
1519                                         for (int i = 0; i < len; i++) {
1520                                                 Property p = (Property) properties [i];
1521
1522                                                 if ((p.ModFlags & modflags) == 0)
1523                                                         continue;
1524                                                 if ((p.ModFlags & static_mask) != static_flags)
1525                                                         continue;
1526                                                 
1527                                                 MethodBuilder b;
1528
1529                                                 b = p.GetBuilder;
1530                                                 if (b != null && filter (b, criteria) == true) {
1531                                                         if (members == null)
1532                                                                 members = new ArrayList ();
1533                                                         
1534                                                         members.Add (b);
1535                                                 }
1536
1537                                                 b = p.SetBuilder;
1538                                                 if (b != null && filter (b, criteria) == true) {
1539                                                         if (members == null)
1540                                                                 members = new ArrayList ();
1541                                                         
1542                                                         members.Add (b);
1543                                         }
1544                                 }
1545                                 }
1546                                 
1547                                 if (indexers != null) {
1548                                         int len = indexers.Count;
1549                                         for (int i = 0; i < len; i++) {
1550                                                 Indexer ix = (Indexer) indexers [i];
1551                                 
1552                                                 if ((ix.ModFlags & modflags) == 0)
1553                                                         continue;
1554                                                 if ((ix.ModFlags & static_mask) != static_flags)
1555                                                         continue;
1556                                                 
1557                                                 MethodBuilder b;
1558
1559                                                 b = ix.GetBuilder;
1560                                                 if (b != null && filter (b, criteria) == true) {
1561                                                         if (members == null)
1562                                                                 members = new ArrayList ();
1563                                                         
1564                                                         members.Add (b);
1565                                                 }
1566
1567                                                 b = ix.SetBuilder;
1568                                                 if (b != null && filter (b, criteria) == true) {
1569                                                         if (members == null)
1570                                                                 members = new ArrayList ();
1571                                                         
1572                                                         members.Add (b);
1573                                         }
1574                                 }
1575                         }
1576                         }
1577
1578                         if ((mt & MemberTypes.Event) != 0) {
1579                                 if (events != null) {
1580                                         int len = events.Count;
1581                                         for (int i = 0; i < len; i++) {
1582                                                 Event e = (Event) events [i];
1583                                                 
1584                                                 if ((e.ModFlags & modflags) == 0)
1585                                                         continue;
1586                                                 if ((e.ModFlags & static_mask) != static_flags)
1587                                                         continue;
1588
1589                                                 MemberInfo eb = e.EventBuilder;
1590                                                 if (eb != null && filter (eb, criteria) == true) {
1591                                                         if (members == null)
1592                                                                 members = new ArrayList ();
1593                                                         
1594                                                         members.Add (e.EventBuilder);
1595                                         }
1596                         }
1597                                 }
1598                         }
1599                         
1600                         if ((mt & MemberTypes.Property) != 0){
1601                                 if (properties != null) {
1602                                         int len = properties.Count;
1603                                         for (int i = 0; i < len; i++) {
1604                                                 Property p = (Property) properties [i];
1605                                                 
1606                                                 if ((p.ModFlags & modflags) == 0)
1607                                                         continue;
1608                                                 if ((p.ModFlags & static_mask) != static_flags)
1609                                                         continue;
1610
1611                                                 MemberInfo pb = p.PropertyBuilder;
1612                                                 if (pb != null && filter (pb, criteria) == true) {
1613                                                         if (members == null)
1614                                                                 members = new ArrayList ();
1615                                                         
1616                                                         members.Add (p.PropertyBuilder);
1617                                                 }
1618                                         }
1619                                 }
1620
1621                                 if (indexers != null) {
1622                                         int len = indexers.Count;
1623                                         for (int i = 0; i < len; i++) {
1624                                                 Indexer ix = (Indexer) indexers [i];
1625
1626                                                 if ((ix.ModFlags & modflags) == 0)
1627                                                         continue;
1628                                                 if ((ix.ModFlags & static_mask) != static_flags)
1629                                                         continue;
1630
1631                                                 MemberInfo ib = ix.PropertyBuilder;
1632                                                 if (ib != null && filter (ib, criteria) == true) {
1633                                                         if (members == null)
1634                                                                 members = new ArrayList ();
1635                                                         
1636                                                         members.Add (ix.PropertyBuilder);
1637                                                 }
1638                                         }
1639                         }
1640                         }
1641                         
1642                         if ((mt & MemberTypes.NestedType) != 0) {
1643                                 if (types != null) {
1644                                         int len = types.Count;
1645                                         for (int i = 0; i < len; i++) {
1646                                                 TypeContainer t = (TypeContainer) types [i];
1647                                                 
1648                                                 if ((t.ModFlags & modflags) == 0)
1649                                                         continue;
1650
1651                                                 TypeBuilder tb = t.TypeBuilder;
1652                                                 if (tb != null && (filter (tb, criteria) == true)) {
1653                                                         if (members == null)
1654                                                                 members = new ArrayList ();
1655                                                         
1656                                                                 members.Add (tb);
1657                                         }
1658                                 }
1659                                 }
1660
1661                                 if (enums != null) {
1662                                         int len = enums.Count;
1663                                         for (int i = 0; i < len; i++) {
1664                                                 Enum en = (Enum) enums [i];
1665
1666                                                 if ((en.ModFlags & modflags) == 0)
1667                                                         continue;
1668
1669                                                 TypeBuilder tb = en.TypeBuilder;
1670                                                 if (tb != null && (filter (tb, criteria) == true)) {
1671                                                         if (members == null)
1672                                                                 members = new ArrayList ();
1673                                                         
1674                                                         members.Add (tb);
1675                                         }
1676                                 }
1677                                 }
1678                                 
1679                                 if (delegates != null) {
1680                                         int len = delegates.Count;
1681                                         for (int i = 0; i < len; i++) {
1682                                                 Delegate d = (Delegate) delegates [i];
1683                                 
1684                                                 if ((d.ModFlags & modflags) == 0)
1685                                                         continue;
1686
1687                                                 TypeBuilder tb = d.TypeBuilder;
1688                                                 if (tb != null && (filter (tb, criteria) == true)) {
1689                                                         if (members == null)
1690                                                                 members = new ArrayList ();
1691                                                         
1692                                                         members.Add (tb);
1693                                         }
1694                                 }
1695                                 }
1696
1697                                 if (interfaces != null) {
1698                                         int len = interfaces.Count;
1699                                         for (int i = 0; i < len; i++) {
1700                                                 Interface iface = (Interface) interfaces [i];
1701
1702                                                 if ((iface.ModFlags & modflags) == 0)
1703                                                         continue;
1704
1705                                                 TypeBuilder tb = iface.TypeBuilder;
1706                                                 if (tb != null && (filter (tb, criteria) == true)) {
1707                                                         if (members == null)
1708                                                                 members = new ArrayList ();
1709                                                         
1710                                                         members.Add (tb);
1711                                         }
1712                                 }
1713                         }
1714                         }
1715
1716                         if ((mt & MemberTypes.Constructor) != 0){
1717                                 if (((bf & BindingFlags.Instance) != 0) && (instance_constructors != null)){
1718                                         int len = instance_constructors.Count;
1719                                         for (int i = 0; i < len; i++) {
1720                                                 Constructor c = (Constructor) instance_constructors [i];
1721                                                 
1722                                                 ConstructorBuilder cb = c.ConstructorBuilder;
1723                                                 if (cb != null && filter (cb, criteria) == true) {
1724                                                         if (members == null)
1725                                                                 members = new ArrayList ();
1726                                                         
1727                                                                 members.Add (cb);
1728                                         }
1729                                 }
1730                                 }
1731
1732                                 if (((bf & BindingFlags.Static) != 0) && (default_static_constructor != null)){
1733                                         ConstructorBuilder cb =
1734                                                 default_static_constructor.ConstructorBuilder;
1735                                         
1736                                         if (cb != null && filter (cb, criteria) == true) {
1737                                                 if (members == null)
1738                                                         members = new ArrayList ();
1739                                                 
1740                                                 members.Add (cb);
1741                                 }
1742                         }
1743                         }
1744
1745                         //
1746                         // Lookup members in parent if requested.
1747                         //
1748                         if (((bf & BindingFlags.DeclaredOnly) == 0) && (TypeBuilder.BaseType != null)) {
1749                                 MemberList list = FindMembers (TypeBuilder.BaseType, mt, bf, filter, criteria);
1750                                 if (list.Count > 0) {
1751                                         if (members == null)
1752                                                 members = new ArrayList ();
1753                                         
1754                                 members.AddRange (list);
1755                         }
1756                         }
1757
1758                         Timer.StopTimer (TimerType.TcFindMembers);
1759
1760                         if (members == null)
1761                                 return MemberList.Empty;
1762                         else
1763                         return new MemberList (members);
1764                 }
1765
1766                 public override MemberCache MemberCache {
1767                         get {
1768                                 return member_cache;
1769                         }
1770                 }
1771
1772                 public static MemberList FindMembers (Type t, MemberTypes mt, BindingFlags bf,
1773                                                       MemberFilter filter, object criteria)
1774                 {
1775                         DeclSpace ds = TypeManager.LookupDeclSpace (t);
1776
1777                         if (ds != null)
1778                                 return ds.FindMembers (mt, bf, filter, criteria);
1779                         else
1780                                 return new MemberList (t.FindMembers (mt, bf, filter, criteria));
1781                 }
1782
1783                 //
1784                 // FindMethods will look for methods not only in the type `t', but in
1785                 // any interfaces implemented by the type.
1786                 //
1787                 public static MethodInfo [] FindMethods (Type t, BindingFlags bf,
1788                                                          MemberFilter filter, object criteria)
1789                 {
1790                         return null;
1791                 }
1792
1793                 /// <summary>
1794                 ///   Emits the values for the constants
1795                 /// </summary>
1796                 public void EmitConstants ()
1797                 {
1798                         if (constants != null)
1799                                 foreach (Const con in constants)
1800                                         con.Emit (this);
1801                         return;
1802                 }
1803
1804                 /// <summary>
1805                 ///   Emits the code, this step is performed after all
1806                 ///   the types, enumerations, constructors
1807                 /// </summary>
1808                 public void Emit ()
1809                 {
1810                         if (instance_constructors != null)
1811                                 foreach (Constructor c in instance_constructors)
1812                                         c.Emit (this);
1813
1814                         if (default_static_constructor != null)
1815                                 default_static_constructor.Emit (this);
1816                         
1817                         if (methods != null)
1818                                 foreach (Method m in methods)
1819                                         m.Emit (this);
1820
1821                         if (operators != null)
1822                                 foreach (Operator o in operators)
1823                                         o.Emit (this);
1824
1825                         if (properties != null)
1826                                 foreach (Property p in properties)
1827                                         p.Emit (this);
1828
1829                         if (indexers != null){
1830                                 foreach (Indexer ix in indexers)
1831                                         ix.Emit (this);
1832                                 
1833                                 CustomAttributeBuilder cb = EmitDefaultMemberAttr ();
1834                                 TypeBuilder.SetCustomAttribute (cb);
1835                         }
1836                         
1837                         if (fields != null)
1838                                 foreach (Field f in fields)
1839                                         f.Emit (this);
1840
1841                         if (events != null){
1842                                 foreach (Event e in Events)
1843                                         e.Emit (this);
1844                         }
1845
1846                         if (Pending != null)
1847                                 if (Pending.VerifyPendingMethods ())
1848                                         return;
1849                         
1850                         Attribute.ApplyAttributes (ec, TypeBuilder, this, OptAttributes);
1851
1852                         //
1853                         // Check for internal or private fields that were never assigned
1854                         //
1855                         if (RootContext.WarningLevel >= 3) {
1856                                 if (fields != null){
1857                                         foreach (Field f in fields) {
1858                                                 if ((f.ModFlags & Modifiers.Accessibility) != Modifiers.PRIVATE)
1859                                                         continue;
1860                                                 
1861                                                 if ((f.status & Field.Status.USED) == 0){
1862                                                         Report.Warning (
1863                                                                 169, f.Location, "Private field " +
1864                                                                 MakeName (f.Name) + " is never used");
1865                                                         continue;
1866                                                 }
1867                                                 
1868                                                 //
1869                                                 // Only report 649 on level 4
1870                                                 //
1871                                                 if (RootContext.WarningLevel < 4)
1872                                                         continue;
1873                                                 
1874                                                 if ((f.status & Field.Status.ASSIGNED) != 0)
1875                                                         continue;
1876                                                 
1877                                                 Report.Warning (
1878                                                         649, f.Location,
1879                                                         "Field " + MakeName (f.Name) + " is never assigned " +
1880                                                         " to and will always have its default value");
1881                                         }
1882                                 }
1883
1884                                 if (events != null){
1885                                         foreach (Event e in events){
1886                                                 if (e.status == 0)
1887                                                         Report.Warning (67, "The event " + MakeName (e.Name) + " is never used");
1888                                         }
1889                                 }
1890                         }
1891                         
1892 //                      if (types != null)
1893 //                              foreach (TypeContainer tc in types)
1894 //                                      tc.Emit ();
1895                 }
1896                 
1897                 CustomAttributeBuilder EmitDefaultMemberAttr ()
1898                 {
1899                         EmitContext ec = new EmitContext (this, Location, null, null, ModFlags);
1900
1901                         Expression ml = Expression.MemberLookup (ec, TypeManager.default_member_type,
1902                                                                  ".ctor", MemberTypes.Constructor,
1903                                                                  BindingFlags.Public | BindingFlags.Instance,
1904                                                                  Location.Null);
1905                         
1906                         MethodGroupExpr mg = (MethodGroupExpr) ml;
1907
1908                         MethodBase constructor = mg.Methods [0];
1909
1910                         string [] vals = { IndexerName };
1911
1912                         CustomAttributeBuilder cb = null;
1913                         try {
1914                                 cb = new CustomAttributeBuilder ((ConstructorInfo) constructor, vals);
1915                         } catch {
1916                                 Report.Warning (-100, "Can not set the indexer default member attribute");
1917                         }
1918
1919                         return cb;
1920                 }
1921
1922                 public override void CloseType ()
1923                 {
1924                         if (Created)
1925                                 return;
1926                         
1927                         try {
1928                                         Created = true;
1929                                         TypeBuilder.CreateType ();
1930                         } catch (TypeLoadException){
1931                                 //
1932                                 // This is fine, the code still created the type
1933                                 //
1934 //                              Report.Warning (-20, "Exception while creating class: " + TypeBuilder.Name);
1935 //                              Console.WriteLine (e.Message);
1936                         } catch {
1937                                 Console.WriteLine ("In type: " + Name);
1938                                 throw;
1939                         }
1940                         
1941                         if (Enums != null)
1942                                 foreach (Enum en in Enums)
1943                                         en.CloseType ();
1944
1945                         if (interface_order != null){
1946                                 foreach (Interface iface in interface_order)
1947                                         iface.CloseType ();
1948                         }
1949                         
1950                         if (Types != null){
1951                                 foreach (TypeContainer tc in Types)
1952                                         if (tc is Struct)
1953                                                 tc.CloseType ();
1954
1955                                 foreach (TypeContainer tc in Types)
1956                                         if (!(tc is Struct))
1957                                                 tc.CloseType ();
1958                         }
1959
1960                         if (Delegates != null)
1961                                 foreach (Delegate d in Delegates)
1962                                         d.CloseType ();
1963                         
1964                         types = null;
1965                         properties = null;
1966                         enums = null;
1967                         delegates = null;
1968                         fields = null;
1969                         initialized_fields = null;
1970                         initialized_static_fields = null;
1971                         constants = null;
1972                         interfaces = null;
1973                         interface_order = null;
1974                         methods = null;
1975                         events = null;
1976                         indexers = null;
1977                         operators = null;
1978                         ec = null;
1979                         default_constructor = null;
1980                         default_static_constructor = null;
1981                         type_bases = null;
1982                         OptAttributes = null;
1983                         ifaces = null;
1984                         parent_container = null;
1985                         member_cache = null;
1986                 }
1987
1988                 public string MakeName (string n)
1989                 {
1990                         return "`" + Name + "." + n + "'";
1991                 }
1992
1993                 public void Warning_KeywordNewRequired (Location l, MemberInfo mi)
1994                 {
1995                         Report.Warning (
1996                                 108, l, "The keyword new is required on " + 
1997                                 MakeName (mi.Name) + " because it hides `" +
1998                                 mi.ReflectedType.Name + "." + mi.Name + "'");
1999                 }
2000
2001                 public void Warning_KeywordNewNotRequired (Location l, MemberCore mc)
2002                 {
2003                         Report.Warning (
2004                                 109, l, "The member " + MakeName (mc.Name) + " does not hide an " +
2005                                 "inherited member, the keyword new is not required");
2006                 }
2007
2008                 public void Error_EventCanOnlyOverrideEvent (Location l, MemberInfo mi)
2009                 {
2010                         Report.Error (
2011                                 72, l, MakeName (mi.Name) + " : cannot override; `" +
2012                                 mi.ReflectedType.Name + "." + mi.Name + "' is not an event");
2013                 }
2014                 
2015                 public static int CheckMember (string name, MemberInfo mi, int ModFlags)
2016                 {
2017                         return 0;
2018                 }
2019
2020                 //
2021                 // Performs the validation on a Method's modifiers (properties have
2022                 // the same properties).
2023                 //
2024                 public bool MethodModifiersValid (int flags, string n, Location loc)
2025                 {
2026                         const int vao = (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE);
2027                         const int va = (Modifiers.VIRTUAL | Modifiers.ABSTRACT);
2028                         const int nv = (Modifiers.NEW | Modifiers.VIRTUAL);
2029                         bool ok = true;
2030                         
2031                         //
2032                         // At most one of static, virtual or override
2033                         //
2034                         if ((flags & Modifiers.STATIC) != 0){
2035                                 if ((flags & vao) != 0){
2036                                         Report.Error (
2037                                                 112, loc, "static method " + MakeName (n) + "can not be marked " +
2038                                                 "as virtual, abstract or override");
2039                                         ok = false;
2040                                 }
2041                         }
2042
2043                         if (this is Struct){
2044                                 if ((flags & va) != 0){
2045                                         Modifiers.Error_InvalidModifier (loc, "virtual or abstract");
2046                                         ok = false;
2047                                 }
2048                         }
2049
2050                         if ((flags & Modifiers.OVERRIDE) != 0 && (flags & nv) != 0){
2051                                 Report.Error (
2052                                         113, loc, MakeName (n) +
2053                                         " marked as override cannot be marked as new or virtual");
2054                                 ok = false;
2055                         }
2056
2057                         //
2058                         // If the declaration includes the abstract modifier, then the
2059                         // declaration does not include static, virtual or extern
2060                         //
2061                         if ((flags & Modifiers.ABSTRACT) != 0){
2062                                 if ((flags & Modifiers.EXTERN) != 0){
2063                                         Report.Error (
2064                                                 180, loc, MakeName (n) + " can not be both abstract and extern");
2065                                         ok = false;
2066                                 }
2067
2068                                 if ((flags & Modifiers.VIRTUAL) != 0){
2069                                         Report.Error (
2070                                                 503, loc, MakeName (n) + " can not be both abstract and virtual");
2071                                         ok = false;
2072                                 }
2073
2074                                 if ((ModFlags & Modifiers.ABSTRACT) == 0){
2075                                         Report.Error (
2076                                                 513, loc, MakeName (n) +
2077                                                 " is abstract but its container class is not");
2078                                         ok = false;
2079
2080                                 }
2081                         }
2082
2083                         if ((flags & Modifiers.PRIVATE) != 0){
2084                                 if ((flags & vao) != 0){
2085                                         Report.Error (
2086                                                 621, loc, MakeName (n) +
2087                                                 " virtual or abstract members can not be private");
2088                                         ok = false;
2089                                 }
2090                         }
2091
2092                         if ((flags & Modifiers.SEALED) != 0){
2093                                 if ((flags & Modifiers.OVERRIDE) == 0){
2094                                         Report.Error (
2095                                                 238, loc, MakeName (n) +
2096                                                 " cannot be sealed because it is not an override");
2097                                         ok = false;
2098                                 }
2099                         }
2100
2101                         return ok;
2102                 }
2103
2104                 Hashtable builder_and_args;
2105                 
2106                 public bool RegisterMethod (MethodBuilder mb, InternalParameters ip, Type [] args)
2107                 {
2108                         if (builder_and_args == null)
2109                                 builder_and_args = new Hashtable ();
2110                         return true;
2111                 }
2112
2113                 /// <summary>
2114                 ///   Performs checks for an explicit interface implementation.  First it
2115                 ///   checks whether the `interface_type' is a base inteface implementation.
2116                 ///   Then it checks whether `name' exists in the interface type.
2117                 /// </summary>
2118                 public bool VerifyImplements (Type interface_type, string full, string name, Location loc)
2119                 {
2120                         bool found = false;
2121
2122                         if (ifaces != null){
2123                                 foreach (TypeExpr t in ifaces){
2124                                         if (t.Type == interface_type){
2125                                                 found = true;
2126                                                 break;
2127                                         }
2128                                 }
2129                         }
2130                         
2131                         if (!found){
2132                                 Report.Error (540, "`" + full + "': containing class does not implement interface `" + interface_type.FullName + "'");
2133                                 return false;
2134                         }
2135
2136                         return true;
2137                 }
2138
2139                 //
2140                 // IMemberContainer
2141                 //
2142
2143                 string IMemberContainer.Name {
2144                         get {
2145                                 return Name;
2146                         }
2147                 }
2148
2149                 Type IMemberContainer.Type {
2150                         get {
2151                                 return TypeBuilder;
2152                         }
2153                 }
2154
2155                 IMemberContainer IMemberContainer.Parent {
2156                         get {
2157                                 return parent_container;
2158                         }
2159                 }
2160
2161                 MemberCache IMemberContainer.MemberCache {
2162                         get {
2163                                 return member_cache;
2164                         }
2165                 }
2166
2167                 bool IMemberContainer.IsInterface {
2168                         get {
2169                                 return this is Interface;
2170                         }
2171                 }
2172
2173                 MemberList IMemberContainer.GetMembers (MemberTypes mt, BindingFlags bf)
2174                 {
2175                         BindingFlags new_bf = bf | BindingFlags.DeclaredOnly;
2176
2177                         if (GenericType != null)
2178                                 return TypeManager.FindMembers (GenericType, mt, new_bf,
2179                                                                 null, null);
2180                         else
2181                                 return FindMembers (mt, new_bf, null, null);
2182                 }
2183
2184                 //
2185                 // Operator pair checking
2186                 //
2187
2188                 class OperatorEntry {
2189                         public int flags;
2190                         public Type ret_type;
2191                         public Type type1, type2;
2192                         public Operator op;
2193                         public Operator.OpType ot;
2194                         
2195                         public OperatorEntry (int f, Operator o)
2196                         {
2197                                 flags = f;
2198
2199                                 ret_type = o.OperatorMethod.GetReturnType ();
2200                                 Type [] pt = o.OperatorMethod.ParameterTypes;
2201                                 type1 = pt [0];
2202                                 type2 = pt [1];
2203                                 op = o;
2204                                 ot = o.OperatorType;
2205                         }
2206
2207                         public override int GetHashCode ()
2208                         {       
2209                                 return ret_type.GetHashCode ();
2210                         }
2211
2212                         public override bool Equals (object o)
2213                         {
2214                                 OperatorEntry other = (OperatorEntry) o;
2215
2216                                 if (other.ret_type != ret_type)
2217                                         return false;
2218                                 if (other.type1 != type1)
2219                                         return false;
2220                                 if (other.type2 != type2)
2221                                         return false;
2222                                 return true;
2223                         }
2224                 }
2225                                 
2226                 //
2227                 // Checks that some operators come in pairs:
2228                 //  == and !=
2229                 // > and <
2230                 // >= and <=
2231                 // true and false
2232                 //
2233                 // They are matched based on the return type and the argument types
2234                 //
2235                 void CheckPairedOperators ()
2236                 {
2237                         Hashtable pairs = new Hashtable (null, null);
2238                         Operator true_op = null;
2239                         Operator false_op = null;
2240                         bool has_equality_or_inequality = false;
2241                         
2242                         // Register all the operators we care about.
2243                         foreach (Operator op in operators){
2244                                 int reg = 0;
2245                                 
2246                                 switch (op.OperatorType){
2247                                 case Operator.OpType.Equality:
2248                                         reg = 1;
2249                                         has_equality_or_inequality = true;
2250                                         break;
2251                                 case Operator.OpType.Inequality:
2252                                         reg = 2;
2253                                         has_equality_or_inequality = true;
2254                                         break;
2255
2256                                 case Operator.OpType.True:
2257                                         true_op = op;
2258                                         break;
2259                                 case Operator.OpType.False:
2260                                         false_op = op;
2261                                         break;
2262                                         
2263                                 case Operator.OpType.GreaterThan:
2264                                         reg = 1; break;
2265                                 case Operator.OpType.LessThan:
2266                                         reg = 2; break;
2267                                         
2268                                 case Operator.OpType.GreaterThanOrEqual:
2269                                         reg = 1; break;
2270                                 case Operator.OpType.LessThanOrEqual:
2271                                         reg = 2; break;
2272                                 }
2273                                 if (reg == 0)
2274                                         continue;
2275
2276                                 OperatorEntry oe = new OperatorEntry (reg, op);
2277
2278                                 object o = pairs [oe];
2279                                 if (o == null)
2280                                         pairs [oe] = oe;
2281                                 else {
2282                                         oe = (OperatorEntry) o;
2283                                         oe.flags |= reg;
2284                                 }
2285                         }
2286
2287                         if (true_op != null){
2288                                 if (false_op == null)
2289                                         Report.Error (216, true_op.Location, "operator true requires a matching operator false");
2290                         } else if (false_op != null)
2291                                 Report.Error (216, false_op.Location, "operator false requires a matching operator true");
2292                         
2293                         //
2294                         // Look for the mistakes.
2295                         //
2296                         foreach (DictionaryEntry de in pairs){
2297                                 OperatorEntry oe = (OperatorEntry) de.Key;
2298
2299                                 if (oe.flags == 3)
2300                                         continue;
2301
2302                                 string s = "";
2303                                 switch (oe.ot){
2304                                 case Operator.OpType.Equality:
2305                                         s = "!=";
2306                                         break;
2307                                 case Operator.OpType.Inequality: 
2308                                         s = "==";
2309                                         break;
2310                                 case Operator.OpType.GreaterThan: 
2311                                         s = "<";
2312                                         break;
2313                                 case Operator.OpType.LessThan:
2314                                         s = ">";
2315                                         break;
2316                                 case Operator.OpType.GreaterThanOrEqual:
2317                                         s = "<=";
2318                                         break;
2319                                 case Operator.OpType.LessThanOrEqual:
2320                                         s = ">=";
2321                                         break;
2322                                 }
2323                                 Report.Error (216, oe.op.Location,
2324                                               "The operator `" + oe.op + "' requires a matching operator `" + s + "' to also be defined");
2325                         }
2326
2327                         if ((has_equality_or_inequality) && (RootContext.WarningLevel >= 2)) {
2328                                 MethodSignature equals_ms = new MethodSignature (
2329                                         "Equals", TypeManager.bool_type, new Type [] { TypeManager.object_type });
2330                                 MethodSignature hash_ms = new MethodSignature (
2331                                         "GetHashCode", TypeManager.int32_type, new Type [0]);
2332
2333                                 MemberList equals_ml = FindMembers (MemberTypes.Method, BindingFlags.Public | BindingFlags.Instance |
2334                                                                     BindingFlags.DeclaredOnly, MethodSignature.method_signature_filter,
2335                                                                     equals_ms);
2336                                 MemberList hash_ml = FindMembers (MemberTypes.Method, BindingFlags.Public | BindingFlags.Instance |
2337                                                                   BindingFlags.DeclaredOnly, MethodSignature.method_signature_filter,
2338                                                                   hash_ms);
2339
2340                                 bool equals_ok = false;
2341                                 if ((equals_ml != null) && (equals_ml.Count == 1))
2342                                         equals_ok = equals_ml [0].DeclaringType == TypeBuilder;
2343                                 bool hash_ok = false;
2344                                 if ((hash_ml != null) && (hash_ml.Count == 1))
2345                                         hash_ok = hash_ml [0].DeclaringType == TypeBuilder;
2346
2347                                 if (!equals_ok)
2348                                         Report.Warning (660, Location, "`" + Name + "' defines operator == or operator != but does " +
2349                                                         "not override Object.Equals (object o)");
2350                                 if (!hash_ok)
2351                                         Report.Warning (661, Location, "`" + Name + "' defines operator == or operator != but does " +
2352                                                         "not override Object.GetHashCode ()");
2353                         }
2354                 }
2355                 
2356         }
2357
2358         public class Class : TypeContainer {
2359                 // <summary>
2360                 //   Modifiers allowed in a class declaration
2361                 // </summary>
2362                 public const int AllowedModifiers =
2363                         Modifiers.NEW |
2364                         Modifiers.PUBLIC |
2365                         Modifiers.PROTECTED |
2366                         Modifiers.INTERNAL |
2367                         Modifiers.PRIVATE |
2368                         Modifiers.ABSTRACT |
2369                         Modifiers.SEALED |
2370                         Modifiers.UNSAFE;
2371
2372                 public Class (NamespaceEntry ns, TypeContainer parent, string name, int mod,
2373                               Attributes attrs, Location l)
2374                         : base (ns, parent, name, attrs, l)
2375                 {
2376                         int accmods;
2377
2378                         if (parent.Parent == null)
2379                                 accmods = Modifiers.INTERNAL;
2380                         else
2381                                 accmods = Modifiers.PRIVATE;
2382
2383                         this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
2384                 }
2385
2386                 //
2387                 // FIXME: How do we deal with the user specifying a different
2388                 // layout?
2389                 //
2390                 public override TypeAttributes TypeAttr {
2391                         get {
2392                                 return base.TypeAttr | TypeAttributes.AutoLayout | TypeAttributes.Class;
2393                         }
2394                 }
2395         }
2396
2397         public class Struct : TypeContainer {
2398                 // <summary>
2399                 //   Modifiers allowed in a struct declaration
2400                 // </summary>
2401                 public const int AllowedModifiers =
2402                         Modifiers.NEW       |
2403                         Modifiers.PUBLIC    |
2404                         Modifiers.PROTECTED |
2405                         Modifiers.INTERNAL  |
2406                         Modifiers.UNSAFE    |
2407                         Modifiers.PRIVATE;
2408
2409                 public Struct (NamespaceEntry ns, TypeContainer parent, string name, int mod, Attributes attrs, Location l)
2410                         : base (ns, parent, name, attrs, l)
2411                 {
2412                         int accmods;
2413                         
2414                         if (parent.Parent == null)
2415                                 accmods = Modifiers.INTERNAL;
2416                         else
2417                                 accmods = Modifiers.PRIVATE;
2418                         
2419                         this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
2420
2421                         this.ModFlags |= Modifiers.SEALED;
2422                 }
2423
2424                 //
2425                 // FIXME: Allow the user to specify a different set of attributes
2426                 // in some cases (Sealed for example is mandatory for a class,
2427                 // but what SequentialLayout can be changed
2428                 //
2429                 public override TypeAttributes TypeAttr {
2430                         get {
2431                                 return base.TypeAttr |
2432                                         TypeAttributes.SequentialLayout |
2433                                         TypeAttributes.Sealed |
2434                                         TypeAttributes.BeforeFieldInit;
2435                         }
2436                 }
2437         }
2438
2439         /// <summary>
2440         ///   Interfaces
2441         /// </summary>
2442         public class Interface : TypeContainer, IMemberContainer {
2443                 /// <summary>
2444                 ///   Modifiers allowed in a class declaration
2445                 /// </summary>
2446                 public const int AllowedModifiers =
2447                         Modifiers.NEW       |
2448                         Modifiers.PUBLIC    |
2449                         Modifiers.PROTECTED |
2450                         Modifiers.INTERNAL  |
2451                         Modifiers.UNSAFE    |
2452                         Modifiers.PRIVATE;
2453
2454                 public Interface (NamespaceEntry ns, TypeContainer parent, string name, int mod,
2455                                   Attributes attrs, Location l)
2456                         : base (ns, parent, name, attrs, l)
2457                 {
2458                         int accmods;
2459
2460                         if (parent.Parent == null)
2461                                 accmods = Modifiers.INTERNAL;
2462                         else
2463                                 accmods = Modifiers.PRIVATE;
2464
2465                         this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
2466                 }
2467
2468                 public override TypeAttributes TypeAttr {
2469                         get {
2470                                 return base.TypeAttr |
2471                                         TypeAttributes.AutoLayout |
2472                                         TypeAttributes.Abstract |
2473                                         TypeAttributes.Interface;
2474                         }
2475                 }
2476         }
2477
2478         public abstract class MethodCore : MemberBase {
2479                 public readonly Parameters Parameters;
2480                 protected Block block;
2481                 protected DeclSpace ds;
2482                 
2483                 //
2484                 // Parameters, cached for semantic analysis.
2485                 //
2486                 protected InternalParameters parameter_info;
2487                 protected Type [] parameter_types;
2488
2489                 // <summary>
2490                 //   This is set from TypeContainer.DefineMembers if this method overrides something.
2491                 // </summary>
2492                 public bool OverridesSomething;
2493
2494                 // Whether this is an operator method.
2495                 public bool IsOperator;
2496
2497                 public MethodCore (DeclSpace ds, Expression type, int mod, int allowed_mod,
2498                                    bool is_interface, MemberName name, Attributes attrs,
2499                                    Parameters parameters, Location loc)
2500                         : base (type, mod, allowed_mod, Modifiers.PRIVATE, name, attrs, loc)
2501                 {
2502                         Parameters = parameters;
2503                         IsInterface = is_interface;
2504                         this.ds = ds;
2505                 }
2506                 
2507                 //
2508                 //  Returns the System.Type array for the parameters of this method
2509                 //
2510                 public Type [] ParameterTypes {
2511                         get {
2512                                 return parameter_types;
2513                         }
2514                 }
2515
2516                 public InternalParameters ParameterInfo
2517                 {
2518                         get {
2519                                 return parameter_info;
2520                         }
2521                 }
2522                 
2523                 public Block Block {
2524                         get {
2525                                 return block;
2526                         }
2527
2528                         set {
2529                                 block = value;
2530                         }
2531                 }
2532
2533                 protected virtual bool DoDefineParameters ()
2534                 {
2535                         // Check if arguments were correct
2536                         parameter_types = Parameters.GetParameterInfo (ds);
2537                         if ((parameter_types == null) || !CheckParameters (ds, parameter_types))
2538                                 return false;
2539
2540                         parameter_info = new InternalParameters (ds, Parameters);
2541
2542                         Parameter array_param = Parameters.ArrayParameter;
2543                         if ((array_param != null) &&
2544                             (!array_param.ParameterType.IsArray ||
2545                              (array_param.ParameterType.GetArrayRank () != 1))) {
2546                                 Report.Error (225, Location, "params parameter has to be a single dimensional array");
2547                                 return false;
2548                         }
2549
2550                         return true;
2551                 }
2552
2553                 void error_425 (Type old, Type t, string name)
2554                 {
2555                         Report.Error (425, Location,
2556                                       "The constraints of type parameter `{0}' " +
2557                                       "of method `{1}' must match the constraints for " +
2558                                       "type parameter `{2}' of method `{3}'",
2559                                       TypeManager.CSharpName (old), Name,
2560                                       TypeManager.CSharpName (t), name);
2561                 }
2562
2563                 protected override bool CheckGenericOverride (MethodInfo method, string name)
2564                 {
2565                         ParameterData pd = Invocation.GetParameterData (method);
2566
2567                         for (int i = 0; i < ParameterTypes.Length; i++) {
2568                                 GenericConstraints ogc = pd.GenericConstraints (i);
2569                                 GenericConstraints gc = ParameterInfo.GenericConstraints (i);
2570
2571                                 if ((gc == null) && (ogc == null))
2572                                         continue;
2573
2574                                 Type ot = pd.ParameterType (i);
2575                                 Type t = ParameterTypes [i];
2576
2577                                 if (!((gc != null) && (ogc != null))) {
2578                                         error_425 (ot, t, name);
2579                                         return false;
2580                                 }
2581
2582                                 if (gc.HasConstructor != ogc.HasConstructor) {
2583                                         error_425 (ot, t, name);
2584                                         return false;
2585                                 }
2586
2587                                 Type[] oct = ogc.Types;
2588                                 Type[] ct = gc.Types;
2589
2590                                 if (oct.Length != ct.Length) {
2591                                         error_425 (ot, t, name);
2592                                         return false;
2593                                 }
2594
2595                                 for (int j = 0; j < oct.Length; j++)
2596                                         if (!oct [j].Equals (ct [j])) {
2597                                                 error_425 (ot, t, name);
2598                                                 return false;
2599                                         }
2600                         }
2601
2602                         return true;
2603                 }
2604
2605                 protected bool IsDuplicateImplementation (TypeContainer tc, MethodCore method)
2606                 {
2607                         if ((method == this) || (method.Name != Name))
2608                                 return false;
2609
2610                         Type[] param_types = method.ParameterTypes;
2611                         if (param_types == null)
2612                                 return false;
2613
2614                         if (param_types.Length != ParameterTypes.Length)
2615                                 return false;
2616
2617                         bool equal = true;
2618                         bool may_unify;
2619
2620                         Type[] infered_types = new Type [param_types.Length];
2621                         may_unify = Invocation.InferTypeArguments (
2622                                 param_types, ParameterTypes, ref infered_types);
2623
2624                         if (!may_unify) {
2625                                 infered_types = new Type [param_types.Length];
2626                                 may_unify = Invocation.InferTypeArguments (
2627                                         ParameterTypes, param_types, ref infered_types);
2628                         }
2629
2630                         for (int i = 0; i < param_types.Length; i++) {
2631                                 Type a = param_types [i];
2632                                 Type b = ParameterTypes [i];
2633
2634                                 if (a != b)
2635                                         equal = false;
2636                         }
2637
2638                         if (equal) {
2639                                 Report.Error (111, Location,
2640                                               "Class `{0}' already defines a member called " +
2641                                               "`{1}' with the same parameter types",
2642                                               tc.Name, Name);
2643                                 return true;
2644                         } else if (may_unify) {
2645                                 Report.Error (408, Location,
2646                                               "`{0}' cannot define overload members that " +
2647                                               "may unify for some type parameter substitutions",
2648                                               tc.Name);
2649                                 return true;
2650                         }
2651
2652                         return false;
2653                 }
2654
2655                 public CallingConventions GetCallingConvention (bool is_class)
2656                 {
2657                         CallingConventions cc = 0;
2658                         
2659                         cc = Parameters.GetCallingConvention ();
2660
2661                         if (is_class)
2662                                 if ((ModFlags & Modifiers.STATIC) == 0)
2663                                         cc |= CallingConventions.HasThis;
2664
2665                         // FIXME: How is `ExplicitThis' used in C#?
2666                         
2667                         return cc;
2668                 }
2669
2670                 //
2671                 // The method's attributes are passed in because we need to extract
2672                 // the "return:" attribute from there to apply on the return type
2673                 //
2674                 static public void LabelParameters (EmitContext ec,
2675                                                     MethodBase builder,
2676                                                     Parameters parameters,
2677                                                     Attributes method_attrs,
2678                                                     Location loc)
2679                 {
2680                         //
2681                         // Define each type attribute (in/out/ref) and
2682                         // the argument names.
2683                         //
2684                         Parameter [] p = parameters.FixedParameters;
2685                         int i = 0;
2686                         
2687                         MethodBuilder mb = null;
2688                         ConstructorBuilder cb = null;
2689
2690                         if (builder is MethodBuilder)
2691                                 mb = (MethodBuilder) builder;
2692                         else
2693                                 cb = (ConstructorBuilder) builder;
2694
2695                         if (p != null){
2696                                 for (i = 0; i < p.Length; i++) {
2697                                         ParameterBuilder pb;
2698                                         ParameterAttributes par_attr = p [i].Attributes;
2699                                         
2700                                         if (mb == null)
2701                                                 pb = cb.DefineParameter (
2702                                                         i + 1, par_attr, p [i].Name);
2703                                         else 
2704                                                 pb = mb.DefineParameter (
2705                                                         i + 1, par_attr, p [i].Name);
2706                                         
2707                                         Attributes attr = p [i].OptAttributes;
2708                                         if (attr != null){
2709                                                 Attribute.ApplyAttributes (ec, pb, pb, attr);
2710
2711                                                 if (par_attr == ParameterAttributes.Out){
2712                                                         if (attr.Contains (TypeManager.in_attribute_type))
2713                                                                 Report.Error (36, loc,
2714                                                                     "Can not use [In] attribute on out parameter");
2715                                                 }
2716                                         }
2717                                 }
2718                         }
2719
2720                         if (parameters.ArrayParameter != null){
2721                                 ParameterBuilder pb;
2722                                 Parameter array_param = parameters.ArrayParameter;
2723
2724                                 if (mb == null)
2725                                         pb = cb.DefineParameter (
2726                                                 i + 1, array_param.Attributes,
2727                                                 array_param.Name);
2728                                 else
2729                                         pb = mb.DefineParameter (
2730                                                 i + 1, array_param.Attributes,
2731                                                 array_param.Name);
2732                                         
2733                                 CustomAttributeBuilder a = new CustomAttributeBuilder (
2734                                         TypeManager.cons_param_array_attribute, new object [0]);
2735                                 
2736                                 pb.SetCustomAttribute (a);
2737                         }
2738
2739                         //
2740                         // And now for the return type attribute decoration
2741                         //
2742                         ParameterBuilder ret_pb;
2743                         Attributes ret_attrs = null;
2744                                 
2745                         if (mb == null || method_attrs == null)
2746                                 return;
2747
2748                         foreach (AttributeSection asec in method_attrs.AttributeSections) {
2749
2750                                 if (asec.Target != "return")
2751                                         continue;
2752
2753                                 if (ret_attrs == null)
2754                                         ret_attrs = new Attributes (asec);
2755                                 else
2756                                         ret_attrs.AddAttributeSection (asec);
2757                         }
2758
2759                         if (ret_attrs != null) {
2760                                 try {
2761                                         ret_pb = mb.DefineParameter (0, ParameterAttributes.None, "");
2762                                         Attribute.ApplyAttributes (ec, ret_pb, ret_pb, ret_attrs);
2763
2764                                 } catch (ArgumentOutOfRangeException) {
2765                                         Report.Warning (
2766                                                 -24, loc,
2767                                                 ".NET SDK 1.0 does not permit setting custom attributes" +
2768                                                 " on the return type of a method");
2769                                 }
2770                         }
2771                 }
2772         }
2773
2774         public class Method : MethodCore, IIteratorContainer {
2775                 public MethodBuilder MethodBuilder;
2776                 public MethodData MethodData;
2777                 public readonly GenericMethod GenericMethod;
2778
2779                 /// <summary>
2780                 ///   Modifiers allowed in a class declaration
2781                 /// </summary>
2782                 const int AllowedModifiers =
2783                         Modifiers.NEW |
2784                         Modifiers.PUBLIC |
2785                         Modifiers.PROTECTED |
2786                         Modifiers.INTERNAL |
2787                         Modifiers.PRIVATE |
2788                         Modifiers.STATIC |
2789                         Modifiers.VIRTUAL |
2790                         Modifiers.SEALED |
2791                         Modifiers.OVERRIDE |
2792                         Modifiers.ABSTRACT |
2793                         Modifiers.UNSAFE |
2794                         Modifiers.METHOD_YIELDS | 
2795                         Modifiers.EXTERN;
2796
2797                 const int AllowedInterfaceModifiers =
2798                         Modifiers.NEW;
2799
2800                 //
2801                 // return_type can be "null" for VOID values.
2802                 //
2803                 public Method (DeclSpace ds, Expression return_type, int mod, bool is_iface,
2804                                MemberName name, Parameters parameters, Attributes attrs,
2805                                Location l)
2806                         : base (ds, return_type, mod,
2807                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
2808                                 is_iface, name, attrs, parameters, l)
2809                 {
2810                 }
2811
2812                 //
2813                 // return_type can be "null" for VOID values.
2814                 //
2815                 public Method (GenericMethod generic, Expression return_type, int mod,
2816                                bool is_iface, MemberName name, Parameters parameters,
2817                                Attributes attrs, Location l)
2818                         : this ((DeclSpace) generic, return_type, mod, is_iface, name,
2819                                 parameters, attrs, l)
2820                 {
2821                         GenericMethod = generic;
2822                 }
2823
2824                 //
2825                 // Returns the `System.Type' for the ReturnType of this
2826                 // function.  Provides a nice cache.  (used between semantic analysis
2827                 // and actual code generation
2828                 //
2829                 public Type GetReturnType ()
2830                 {
2831                         return MemberType;
2832                 }
2833
2834                 void DuplicateEntryPoint (MethodInfo b, Location location)
2835                 {
2836                         Report.Error (
2837                                 17, location,
2838                                 "Program `" + CodeGen.FileName +
2839                                 "'  has more than one entry point defined: `" +
2840                                 TypeManager.CSharpSignature(b) + "'");
2841                 }
2842
2843                 void Report28 (MethodInfo b)
2844                 {
2845                         Report.Warning (
2846                                 28, Location,
2847                                 "`" + TypeManager.CSharpSignature(b) +
2848                                 "' has the wrong signature to be an entry point");
2849                 }
2850
2851                 public bool IsEntryPoint (MethodBuilder b, InternalParameters pinfo)
2852                 {
2853                         if (b.ReturnType != TypeManager.void_type &&
2854                             b.ReturnType != TypeManager.int32_type)
2855                                 return false;
2856
2857                         if (pinfo.Count == 0)
2858                                 return true;
2859
2860                         if (pinfo.Count > 1)
2861                                 return false;
2862
2863                         Type t = pinfo.ParameterType(0);
2864                         if (t.IsArray &&
2865                             (t.GetArrayRank() == 1) &&
2866                             (TypeManager.GetElementType(t) == TypeManager.string_type) &&
2867                             (pinfo.ParameterModifier(0) == Parameter.Modifier.NONE))
2868                                 return true;
2869                         else
2870                                 return false;
2871                 }
2872
2873                 //
2874                 // Checks our base implementation if any
2875                 //
2876                 protected override bool CheckBase (TypeContainer container)
2877                 {
2878                         base.CheckBase (container);
2879                         
2880                         // Check whether arguments were correct.
2881                         if (!DoDefineParameters ())
2882                                 return false;
2883
2884                         MethodSignature ms = new MethodSignature (Name, null, ParameterTypes);
2885                         if (IsOperator) {
2886                                 flags |= MethodAttributes.SpecialName | MethodAttributes.HideBySig;
2887                         } else {
2888                                 //
2889                                 // Check in our class for dups
2890                                 //
2891                                 ArrayList ar = container.Methods;
2892                                 if (ar != null) {
2893                                         int arLen = ar.Count;
2894
2895                                         for (int i = 0; i < arLen; i++) {
2896                                                 Method m = (Method) ar [i];
2897                                                 if (IsDuplicateImplementation (container, m))
2898                                                         return false;
2899                                         }
2900                                 }
2901                         }
2902
2903
2904                         //
2905                         // Verify if the parent has a type with the same name, and then
2906                         // check whether we have to create a new slot for it or not.
2907                         //
2908                         Type ptype = container.TypeBuilder.BaseType;
2909
2910                         // ptype is only null for System.Object while compiling corlib.
2911                         if (ptype != null) {
2912                                 
2913                                 //
2914                                 // Explicit implementations do not have `parent' methods, however,
2915                                 // the member cache stores them there. Without this check, we get
2916                                 // an incorrect warning in corlib.
2917                                 //
2918                                 if (! IsExplicitImpl) {
2919                                         parent_method = (MethodInfo)((IMemberContainer)container).Parent.MemberCache.FindMemberToOverride (
2920                                                 container.TypeBuilder, Name, ParameterTypes, false);
2921                                 }
2922                                 
2923                                 if (parent_method != null) {
2924                                         string name = parent_method.DeclaringType.Name + "." +
2925                                                 parent_method.Name;
2926
2927                                         if (!CheckMethodAgainstBase (container, flags, parent_method, name))
2928                                                 return false;
2929
2930                                         if ((ModFlags & Modifiers.NEW) == 0) {
2931                                                 Type parent_ret = TypeManager.TypeToCoreType (
2932                                                         parent_method.ReturnType);
2933
2934                                                 if (!parent_ret.Equals (MemberType)) {
2935                                                         Report.Error (
2936                                                                 508, Location, container.MakeName (Name) + ": cannot " +
2937                                                                 "change return type when overriding " +
2938                                                                 "inherited member " + name);
2939                                                         return false;
2940                                                 }
2941                                         }
2942                                 } else {
2943                                         if (!OverridesSomething && ((ModFlags & Modifiers.NEW) != 0))
2944                                                 WarningNotHiding (container);
2945
2946                                         if ((ModFlags & Modifiers.OVERRIDE) != 0){
2947                                                 Report.Error (115, Location,
2948                                                               container.MakeName (Name) +
2949                                                               " no suitable methods found to override");
2950                                         }
2951                                 }
2952                         } else if ((ModFlags & Modifiers.NEW) != 0)
2953                                 WarningNotHiding (container);
2954
2955                         return true;
2956                 }
2957
2958                 //
2959                 // Creates the type
2960                 //
2961                 public override bool Define (TypeContainer container)
2962                 {
2963                         DeclSpace decl;
2964                         MethodBuilder mb = null;
2965                         if (GenericMethod != null) {
2966                                 mb = container.TypeBuilder.DefineGenericMethod (Name, flags);
2967                                 if (!GenericMethod.Define (container, mb))
2968                                         return false;
2969                                 decl = GenericMethod;
2970                         } else
2971                                 decl = container;
2972
2973                         if (!DoDefine (decl, container))
2974                                 return false;
2975
2976                         if (!CheckBase (container))
2977                                 return false;
2978
2979                         CallingConventions cc = GetCallingConvention (container is Class);
2980
2981                         MethodData = new MethodData (ds, this, null, MemberType,
2982                                                      ParameterTypes, ParameterInfo, cc,
2983                                                      OptAttributes, ModFlags, flags, true,
2984                                                      mb, GenericMethod);
2985
2986                         if (!MethodData.Define (container))
2987                                 return false;
2988
2989                         //
2990                         // Setup iterator if we are one
2991                         //
2992                         if ((ModFlags & Modifiers.METHOD_YIELDS) != 0){
2993                                 IteratorHandler ih = new  IteratorHandler (
2994                                             Name, container, MemberType,
2995                                             ParameterTypes, ParameterInfo,
2996                                             ModFlags, Location);
2997
2998                                 Block new_block = ih.Setup (block);
2999                                 if (new_block == null)
3000                                         return false;
3001                                 block = new_block;
3002                         }
3003
3004                         MethodBuilder = MethodData.MethodBuilder;
3005
3006                         //
3007                         // This is used to track the Entry Point,
3008                         //
3009                         if (Name == "Main" &&
3010                             ((ModFlags & Modifiers.STATIC) != 0) && RootContext.NeedsEntryPoint && 
3011                             (RootContext.MainClass == null ||
3012                              RootContext.MainClass == container.TypeBuilder.FullName)){
3013                                 if (IsEntryPoint (MethodBuilder, ParameterInfo)) {
3014                                         if (RootContext.EntryPoint == null) {
3015                                                 if (container.IsGeneric){
3016                                                         Report.Error (-201, Location,
3017                                                                       "Entry point can not be defined in a generic class");
3018                                                 }
3019                                                 
3020                                                 RootContext.EntryPoint = MethodBuilder;
3021                                                 RootContext.EntryPointLocation = Location;
3022                                         } else {
3023                                                 DuplicateEntryPoint (RootContext.EntryPoint, RootContext.EntryPointLocation);
3024                                                 DuplicateEntryPoint (MethodBuilder, Location);
3025                                         }
3026                                 } else                                  
3027                                         Report28(MethodBuilder);
3028                         }
3029
3030                         return true;
3031                 }
3032
3033                 //
3034                 // Emits the code
3035                 // 
3036                 public void Emit (TypeContainer container)
3037                 {
3038                         MethodData.Emit (container, Block, this);
3039                         Block = null;
3040                         MethodData = null;
3041                 }
3042
3043                 void IIteratorContainer.SetYields ()
3044                 {
3045                         ModFlags |= Modifiers.METHOD_YIELDS;
3046                 }
3047         }
3048
3049         public abstract class ConstructorInitializer {
3050                 ArrayList argument_list;
3051                 ConstructorInfo parent_constructor;
3052                 Parameters parameters;
3053                 Location loc;
3054                 
3055                 public ConstructorInitializer (ArrayList argument_list, Parameters parameters,
3056                                                Location loc)
3057                 {
3058                         this.argument_list = argument_list;
3059                         this.parameters = parameters;
3060                         this.loc = loc;
3061                 }
3062
3063                 public ArrayList Arguments {
3064                         get {
3065                                 return argument_list;
3066                         }
3067                 }
3068
3069                 public bool Resolve (ConstructorBuilder caller_builder, EmitContext ec)
3070                 {
3071                         Expression parent_constructor_group;
3072                         Type t;
3073
3074                         ec.CurrentBlock = new ToplevelBlock (Block.Flags.Implicit, parameters, loc);
3075
3076                         if (argument_list != null){
3077                                 foreach (Argument a in argument_list){
3078                                         if (!a.Resolve (ec, loc))
3079                                                 return false;
3080                                 }
3081                         }
3082                         ec.CurrentBlock = null;
3083
3084                         if (this is ConstructorBaseInitializer) {
3085                                 if (ec.ContainerType.BaseType == null)
3086                                         return true;
3087
3088                                 t = ec.ContainerType.BaseType;
3089                                 if (ec.ContainerType.IsValueType) {
3090                                         Report.Error (522, loc,
3091                                                 "structs cannot call base class constructors");
3092                                         return false;
3093                                 }
3094                         } else
3095                                 t = ec.ContainerType;
3096
3097                         parent_constructor_group = Expression.MemberLookup (
3098                                 ec, t, null, t, ".ctor", 0, 
3099                                 MemberTypes.Constructor,
3100                                 BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
3101                                 loc);
3102                         
3103                         if (parent_constructor_group == null){
3104                                 Report.Error (1501, loc,
3105                                        "Can not find a constructor for this argument list");
3106                                 return false;
3107                         }
3108                         
3109                         parent_constructor = (ConstructorInfo) Invocation.OverloadResolve (
3110                                 ec, (MethodGroupExpr) parent_constructor_group, argument_list,
3111                                 false, loc);
3112                         
3113                         if (parent_constructor == null){
3114                                 Report.Error (1501, loc,
3115                                        "Can not find a constructor for this argument list");
3116                                 return false;
3117                         }
3118                         
3119                         if (parent_constructor == caller_builder){
3120                                 Report.Error (515, String.Format ("Constructor `{0}' can not call itself", TypeManager.CSharpSignature (caller_builder)));
3121                                 return false;
3122                         }
3123                         
3124                         return true;
3125                 }
3126
3127                 public void Emit (EmitContext ec)
3128                 {
3129                         if (parent_constructor != null){
3130                                 ec.Mark (loc, false);
3131                                 if (ec.IsStatic)
3132                                         Invocation.EmitCall (ec, true, true, null, parent_constructor, argument_list, loc);
3133                                 else
3134                                         Invocation.EmitCall (ec, true, false, ec.GetThis (loc), parent_constructor, argument_list, loc);
3135                         }
3136                 }
3137         }
3138
3139         public class ConstructorBaseInitializer : ConstructorInitializer {
3140                 public ConstructorBaseInitializer (ArrayList argument_list, Parameters pars, Location l) :
3141                         base (argument_list, pars, l)
3142                 {
3143                 }
3144         }
3145
3146         public class ConstructorThisInitializer : ConstructorInitializer {
3147                 public ConstructorThisInitializer (ArrayList argument_list, Parameters pars, Location l) :
3148                         base (argument_list, pars, l)
3149                 {
3150                 }
3151         }
3152         
3153         public class Constructor : MethodCore {
3154                 public ConstructorBuilder ConstructorBuilder;
3155                 public ConstructorInitializer Initializer;
3156
3157                 // <summary>
3158                 //   Modifiers allowed for a constructor.
3159                 // </summary>
3160                 public const int AllowedModifiers =
3161                         Modifiers.PUBLIC |
3162                         Modifiers.PROTECTED |
3163                         Modifiers.INTERNAL |
3164                         Modifiers.STATIC |
3165                         Modifiers.UNSAFE |
3166                         Modifiers.EXTERN |              
3167                         Modifiers.PRIVATE;
3168
3169                 //
3170                 // The spec claims that static is not permitted, but
3171                 // my very own code has static constructors.
3172                 //
3173                 public Constructor (DeclSpace ds, string name, int mod, Parameters args,
3174                                     ConstructorInitializer init, Location l)
3175                         : base (ds, null, mod, AllowedModifiers, false,
3176                                 new MemberName (name), null, args, l)
3177                 {
3178                         Initializer = init;
3179                 }
3180
3181                 //
3182                 // Returns true if this is a default constructor
3183                 //
3184                 public bool IsDefault ()
3185                 {
3186                         if ((ModFlags & Modifiers.STATIC) != 0)
3187                                 return  (Parameters.FixedParameters == null ? true : Parameters.Empty) &&
3188                                         (Parameters.ArrayParameter == null ? true : Parameters.Empty);
3189                         
3190                         else
3191                                 return  (Parameters.FixedParameters == null ? true : Parameters.Empty) &&
3192                                         (Parameters.ArrayParameter == null ? true : Parameters.Empty) &&
3193                                         (Initializer is ConstructorBaseInitializer) &&
3194                                         (Initializer.Arguments == null);
3195                 }
3196
3197                 protected override bool CheckBase (TypeContainer container)
3198                 {
3199                         base.CheckBase (container);
3200                         
3201                         // Check whether arguments were correct.
3202                         if (!DoDefineParameters ())
3203                                 return false;
3204                         
3205                         if ((ModFlags & Modifiers.STATIC) != 0)
3206                                 return true;
3207                         
3208                         if (container is Struct && ParameterTypes.Length == 0) {
3209                                 Report.Error (568, Location, 
3210                                         "Structs can not contain explicit parameterless " +
3211                                         "constructors");
3212                                 return false;
3213                         }
3214                                 
3215                         //
3216                         // Check in our class for dups
3217                         //
3218                         ArrayList ar = container.InstanceConstructors;
3219                         if (ar != null) {
3220                                 int arLen = ar.Count;
3221                                         
3222                                 for (int i = 0; i < arLen; i++) {
3223                                         Constructor m = (Constructor) ar [i];
3224                                         if (IsDuplicateImplementation (container, m))
3225                                                 return false;
3226                                 }
3227                         }
3228                         
3229                         return true;
3230                 }
3231                 
3232                 //
3233                 // Creates the ConstructorBuilder
3234                 //
3235                 public override bool Define (TypeContainer container)
3236                 {
3237                         MethodAttributes ca = (MethodAttributes.RTSpecialName |
3238                                                MethodAttributes.SpecialName);
3239
3240                         if ((ModFlags & Modifiers.STATIC) != 0){
3241                                 ca |= MethodAttributes.Static | MethodAttributes.Private;
3242                         } else {
3243                                 ca |= MethodAttributes.HideBySig;
3244
3245                                 if ((ModFlags & Modifiers.PUBLIC) != 0)
3246                                         ca |= MethodAttributes.Public;
3247                                 else if ((ModFlags & Modifiers.PROTECTED) != 0){
3248                                         if ((ModFlags & Modifiers.INTERNAL) != 0)
3249                                                 ca |= MethodAttributes.FamORAssem;
3250                                         else 
3251                                                 ca |= MethodAttributes.Family;
3252                                 } else if ((ModFlags & Modifiers.INTERNAL) != 0)
3253                                         ca |= MethodAttributes.Assembly;
3254                                 else if (IsDefault ())
3255                                         ca |= MethodAttributes.Public;
3256                                 else
3257                                         ca |= MethodAttributes.Private;
3258                         }
3259
3260                         // Check if arguments were correct.
3261                         if (!CheckBase (container))
3262                                 return false;
3263
3264                         ConstructorBuilder = container.TypeBuilder.DefineConstructor (
3265                                 ca, GetCallingConvention (container is Class), ParameterTypes);
3266
3267                         if ((ModFlags & Modifiers.UNSAFE) != 0)
3268                                 ConstructorBuilder.InitLocals = false;
3269                         
3270                         //
3271                         // HACK because System.Reflection.Emit is lame
3272                         //
3273                         TypeManager.RegisterMethod (ConstructorBuilder, ParameterInfo, ParameterTypes);
3274
3275                         return true;
3276                 }
3277
3278                 //
3279                 // Emits the code
3280                 //
3281                 public void Emit (TypeContainer container)
3282                 {
3283                         ILGenerator ig = ConstructorBuilder.GetILGenerator ();
3284                         EmitContext ec = new EmitContext (container, Location, ig, null, ModFlags, true);
3285
3286                         //
3287                         // extern methods have no bodies
3288                         //
3289                         if ((ModFlags & Modifiers.EXTERN) != 0) {
3290                                 if ((block != null) && ((ModFlags & Modifiers.EXTERN) != 0)) {
3291                                         Report.Error (
3292                                                 179, Location, "External constructor `" +
3293                                                 TypeManager.CSharpSignature (ConstructorBuilder) +
3294                                                 "' can not have a body");
3295                                         return;
3296                                 }
3297                         } else if (block == null) {
3298                                 Report.Error (
3299                                         501, Location, "Constructor `" +
3300                                         TypeManager.CSharpSignature (ConstructorBuilder) +
3301                                         "' must declare a body since it is not marked extern");
3302                                 return;
3303                         }
3304
3305                         if ((ModFlags & Modifiers.STATIC) == 0){
3306                                 if (container is Class && Initializer == null)
3307                                         Initializer = new ConstructorBaseInitializer (
3308                                                 null, Parameters.EmptyReadOnlyParameters, Location);
3309
3310
3311                                 //
3312                                 // Spec mandates that Initializers will not have
3313                                 // `this' access
3314                                 //
3315                                 ec.IsStatic = true;
3316                                 if (Initializer != null && !Initializer.Resolve (ConstructorBuilder, ec))
3317                                         return;
3318                                 ec.IsStatic = false;
3319                         }
3320
3321                         MethodCore.LabelParameters (ec, ConstructorBuilder,
3322                                                     Parameters, OptAttributes, Location);
3323                         
3324                         SymbolWriter sw = CodeGen.SymbolWriter;
3325                         bool generate_debugging = false;
3326
3327                         if ((sw != null) && (block != null) &&
3328                                 !Location.IsNull (Location) &&
3329                                 !Location.IsNull (block.EndLocation) &&
3330                                 (Location.SymbolDocument != null)) {
3331                                 sw.OpenMethod (container, ConstructorBuilder, Location, block.EndLocation);
3332
3333                                 generate_debugging = true;
3334                         }
3335
3336                         //
3337                         // Classes can have base initializers and instance field initializers.
3338                         //
3339                         if (container is Class){
3340                                 if ((ModFlags & Modifiers.STATIC) == 0){
3341
3342                                         //
3343                                         // If we use a "this (...)" constructor initializer, then
3344                                         // do not emit field initializers, they are initialized in the other constructor
3345                                         //
3346                                         if (!(Initializer != null && Initializer is ConstructorThisInitializer))
3347                                                 container.EmitFieldInitializers (ec);
3348                                 }
3349                         }
3350                         if (Initializer != null)
3351                                 Initializer.Emit (ec);
3352                         
3353                         if ((ModFlags & Modifiers.STATIC) != 0)
3354                                 container.EmitFieldInitializers (ec);
3355
3356                         Attribute.ApplyAttributes (ec, ConstructorBuilder, this, OptAttributes);
3357
3358                         // If this is a non-static `struct' constructor and doesn't have any
3359                         // initializer, it must initialize all of the struct's fields.
3360                         if ((container is Struct) && ((ModFlags & Modifiers.STATIC) == 0) && (Initializer == null))
3361                                 Block.AddThisVariable (container, Location);
3362
3363                         ec.EmitTopBlock (block, ParameterInfo, Location);
3364
3365                         if (generate_debugging)
3366                                 sw.CloseMethod ();
3367
3368                         block = null;
3369                 }
3370         }
3371
3372         //
3373         // Encapsulates most of the Method's state
3374         //
3375         public class MethodData {
3376                 //
3377                 // The return type of this method
3378                 //
3379                 public readonly Type ReturnType;
3380                 public readonly Type[] ParameterTypes;
3381                 public readonly GenericMethod GenericMethod;
3382                 public readonly InternalParameters ParameterInfo;
3383                 public readonly CallingConventions CallingConventions;
3384                 public readonly Attributes OptAttributes;
3385                 public readonly Location Location;
3386
3387                 //
3388                 // Are we implementing an interface ?
3389                 //
3390                 public bool IsImplementing = false;
3391
3392                 //
3393                 // Protected data.
3394                 //
3395                 protected DeclSpace ds;
3396                 protected MemberBase member;
3397                 protected int modifiers;
3398                 protected MethodAttributes flags;
3399                 protected bool is_method;
3400                 protected string accessor_name;
3401                 protected Type declaring_type;
3402
3403                 //
3404                 // It can either hold a string with the condition, or an arraylist of conditions.
3405                 object conditionals;
3406                 EmitContext ec;
3407
3408                 MethodBuilder builder = null;
3409                 public MethodBuilder MethodBuilder {
3410                         get {
3411                                 return builder;
3412                         }
3413                 }
3414
3415                 public Type DeclaringType {
3416                         get {
3417                                 return declaring_type;
3418                         }
3419                 }
3420
3421                 public MethodData (DeclSpace ds, MemberBase member, string name, Type return_type,
3422                                    Type [] parameter_types, InternalParameters parameters,
3423                                    CallingConventions cc, Attributes opt_attrs,
3424                                    int modifiers, MethodAttributes flags, bool is_method)
3425                 {
3426                         this.ds = ds;
3427                         this.member = member;
3428                         this.accessor_name = name;
3429                         this.ReturnType = return_type;
3430                         this.ParameterTypes = parameter_types;
3431                         this.ParameterInfo = parameters;
3432                         this.CallingConventions = cc;
3433                         this.OptAttributes = opt_attrs;
3434                         this.modifiers = modifiers;
3435                         this.flags = flags;
3436                         this.is_method = is_method;
3437                         this.Location = member.Location;
3438                         this.conditionals = null;
3439                 }
3440
3441                 public MethodData (DeclSpace ds, MemberBase member, string name, Type return_type,
3442                                    Type [] parameter_types, InternalParameters parameters,
3443                                    CallingConventions cc, Attributes opt_attrs,
3444                                    int modifiers, MethodAttributes flags, bool is_method,
3445                                    MethodBuilder builder, GenericMethod generic)
3446                         : this (ds, member, name, return_type, parameter_types, parameters,
3447                                 cc, opt_attrs, modifiers, flags, is_method)
3448                 {
3449                         this.builder = builder;
3450                         this.GenericMethod = generic;
3451                 }
3452
3453                 //
3454                 // Attributes.
3455                 //
3456                 Attribute dllimport_attribute = null;
3457                 string obsolete = null;
3458                 bool obsolete_error = false;
3459
3460                 public virtual bool ApplyAttributes (Attributes opt_attrs, bool is_method)
3461                 {
3462                         if ((opt_attrs == null) || (opt_attrs.AttributeSections == null))
3463                                 return true;
3464
3465                         foreach (AttributeSection asec in opt_attrs.AttributeSections) {
3466                                 if (asec.Attributes == null)
3467                                         continue;
3468                                         
3469                                 foreach (Attribute a in asec.Attributes) {
3470                                         if (a.Name == "Conditional") {
3471                                                 if (!ApplyConditionalAttribute (a))
3472                                                         return false;
3473                                         } else if (a.Name == "Obsolete") {
3474                                                 if (!ApplyObsoleteAttribute (a))
3475                                                         return false;
3476                                         } else if (a.Name.IndexOf ("DllImport") != -1) {
3477                                                 if (!is_method) {
3478                                                         a.Type = TypeManager.dllimport_type;
3479                                                         Attribute.Error_AttributeNotValidForElement (a, Location);
3480                                                         return false;
3481                                                 }
3482                                                 if (!ApplyDllImportAttribute (a))
3483                                                         return false;
3484                                         }
3485                                 }
3486                         }
3487
3488                         return true;
3489                 }
3490
3491                 //
3492                 // Applies the `DllImport' attribute to the method.
3493                 //
3494                 protected virtual bool ApplyDllImportAttribute (Attribute a)
3495                 {
3496                         const int extern_static = Modifiers.EXTERN | Modifiers.STATIC;
3497                         if ((modifiers & extern_static) != extern_static) {
3498                                 Report.Error (601, Location,
3499                                               "The DllImport attribute must be specified on a method " +
3500                                               "marked `static' and `extern'.");
3501                                 return false;
3502                         }
3503
3504                         flags |= MethodAttributes.PinvokeImpl;
3505                         dllimport_attribute = a;
3506                         return true;
3507                 }
3508
3509                 //
3510                 // Applies the `Obsolete' attribute to the method.
3511                 //
3512                 protected virtual bool ApplyObsoleteAttribute (Attribute a)
3513                 {
3514                         if (obsolete != null) {
3515                                 Report.Error (579, Location, "Duplicate `Obsolete' attribute");
3516                                 return false;
3517                         }
3518
3519                         obsolete = a.Obsolete_GetObsoleteMessage (out obsolete_error);
3520                         return obsolete != null;
3521                 }
3522
3523                 //
3524                 // Applies the `Conditional' attribute to the method.
3525                 //
3526                 protected virtual bool ApplyConditionalAttribute (Attribute a)
3527                 {
3528                         // The Conditional attribute is only valid on methods.
3529                         if (!is_method) {
3530                                 Attribute.Error_AttributeNotValidForElement (a, Location);
3531                                 return false;
3532                         }
3533
3534                         string condition = a.Conditional_GetConditionName ();
3535
3536                         if (condition == null)
3537                                 return false;
3538
3539                         if (ReturnType != TypeManager.void_type) {
3540                                 Report.Error (578, Location,
3541                                               "Conditional not valid on `" + member.Name + "' " +
3542                                               "because its return type is not void");
3543                                 return false;
3544                         }
3545
3546                         if ((modifiers & Modifiers.OVERRIDE) != 0) {
3547                                 Report.Error (243, Location,
3548                                               "Conditional not valid on `" + member.Name + "' " +
3549                                               "because it is an override method");
3550                                 return false;
3551                         }
3552
3553                         if (member.IsExplicitImpl) {
3554                                 Report.Error (577, Location,
3555                                               "Conditional not valid on `" + member.Name + "' " +
3556                                               "because it is an explicit interface implementation");
3557                                 return false;
3558                         }
3559
3560                         if (IsImplementing) {
3561                                 Report.Error (623, Location,
3562                                               "Conditional not valid on `" + member.Name + "' " +
3563                                               "because it is an interface method");
3564                                 return false;
3565                         }
3566
3567                         //
3568                         // The likelyhood that the conditional will be more than 1 is very slim
3569                         //
3570                         if (conditionals == null)
3571                                 conditionals = condition;
3572                         else if (conditionals is string){
3573                                 string s = (string) conditionals;
3574                                 conditionals = new ArrayList ();
3575                                 ((ArrayList)conditionals).Add (s);
3576                         } else
3577                                 ((ArrayList)conditionals).Add (condition);
3578
3579                         return true;
3580                 }
3581
3582                 //
3583                 // Checks whether this method should be ignored due to its Conditional attributes.
3584                 //
3585                 bool ShouldIgnore (Location loc)
3586                 {
3587                         // When we're overriding a virtual method, we implicitly inherit the
3588                         // Conditional attributes from our parent.
3589                         if (member.ParentMethod != null) {
3590                                 TypeManager.MethodFlags flags = TypeManager.GetMethodFlags (
3591                                         member.ParentMethod, loc);
3592
3593                                 if ((flags & TypeManager.MethodFlags.ShouldIgnore) != 0)
3594                                         return true;
3595                         }
3596
3597                         if (conditionals != null){
3598                                 if (conditionals is string){
3599                                         if (RootContext.AllDefines [conditionals] == null)
3600                                                 return true;
3601                                 } else {
3602                                         foreach (string condition in (ArrayList) conditionals)
3603                                         if (RootContext.AllDefines [condition] == null)
3604                                                 return true;
3605                                 }
3606                         }
3607                         return false;
3608                 }
3609
3610                 //
3611                 // Returns the TypeManager.MethodFlags for this method.
3612                 // This emits an error 619 / warning 618 if the method is obsolete.
3613                 // In the former case, TypeManager.MethodFlags.IsObsoleteError is returned.
3614                 //
3615                 public virtual TypeManager.MethodFlags GetMethodFlags (Location loc)
3616                 {
3617                         TypeManager.MethodFlags flags = 0;
3618
3619                         if (obsolete != null) {
3620                                 if (obsolete_error) {
3621                                         Report.Error (619, loc, "Method `" + member.Name +
3622                                                       "' is obsolete: `" + obsolete + "'");
3623                                         return TypeManager.MethodFlags.IsObsoleteError;
3624                                 } else
3625                                         Report.Warning (618, loc, "Method `" + member.Name +
3626                                                         "' is obsolete: `" + obsolete + "'");
3627
3628                                 flags |= TypeManager.MethodFlags.IsObsolete;
3629                         }
3630
3631                         if (ShouldIgnore (loc))
3632                                 flags |= TypeManager.MethodFlags.ShouldIgnore;
3633
3634                         return flags;
3635                 }
3636
3637                 public virtual bool Define (TypeContainer container)
3638                 {
3639                         MethodInfo implementing = null;
3640                         string method_name, name, prefix;
3641
3642                         if (OptAttributes != null)
3643                                 if (!ApplyAttributes (OptAttributes, is_method))
3644                                         return false;
3645
3646                         if (member.IsExplicitImpl)
3647                                 prefix = member.InterfaceType.FullName + ".";
3648                         else
3649                                 prefix = "";
3650
3651                         if (accessor_name != null)
3652                                 name = accessor_name + "_" + member.ShortName;
3653                         else
3654                                 name = member.ShortName;
3655                         method_name = prefix + name;
3656
3657                         if (container.Pending != null){
3658                                 if (member is Indexer)
3659                                         implementing = container.Pending.IsInterfaceIndexer (
3660                                                 member.InterfaceType, ReturnType, ParameterTypes);
3661                                 else
3662                                         implementing = container.Pending.IsInterfaceMethod (
3663                                                 member.InterfaceType, name, ReturnType, ParameterTypes);
3664
3665                                 if (member.InterfaceType != null && implementing == null){
3666                                         Report.Error (539, Location, "'{0}' in explicit interface declaration is not an interface", method_name);
3667                                         return false;
3668                                 }
3669                         }
3670
3671                         //
3672                         // For implicit implementations, make sure we are public, for
3673                         // explicit implementations, make sure we are private.
3674                         //
3675                         if (implementing != null){
3676                                 //
3677                                 // Setting null inside this block will trigger a more
3678                                 // verbose error reporting for missing interface implementations
3679                                 //
3680                                 // The "candidate" function has been flagged already
3681                                 // but it wont get cleared
3682                                 //
3683                                 if (member.IsExplicitImpl){
3684                                         if ((modifiers & (Modifiers.PUBLIC | Modifiers.ABSTRACT | Modifiers.VIRTUAL)) != 0){
3685                                                 Modifiers.Error_InvalidModifier (Location, "public, virtual or abstract");
3686                                                 implementing = null;
3687                                         }
3688                                 } else if ((flags & MethodAttributes.MemberAccessMask) != MethodAttributes.Public){
3689                                         if (TypeManager.IsInterfaceType (implementing.DeclaringType)){
3690                                                 //
3691                                                 // If this is an interface method implementation,
3692                                                 // check for public accessibility
3693                                                 //
3694                                                 implementing = null;
3695                                         } else if ((flags & MethodAttributes.MemberAccessMask) == MethodAttributes.Private){
3696                                                 // We may never be private.
3697                                                 implementing = null;
3698                                         } else if ((modifiers & Modifiers.OVERRIDE) == 0){
3699                                                 //
3700                                                 // We may be protected if we're overriding something.
3701                                                 //
3702                                                 implementing = null;
3703                                         }
3704                                 } 
3705                                         
3706                                 //
3707                                 // Static is not allowed
3708                                 //
3709                                 if ((modifiers & Modifiers.STATIC) != 0){
3710                                         implementing = null;
3711                                         Modifiers.Error_InvalidModifier (Location, "static");
3712                                 }
3713                         }
3714                         
3715                         //
3716                         // If implementing is still valid, set flags
3717                         //
3718                         if (implementing != null){
3719                                 //
3720                                 // When implementing interface methods, set NewSlot
3721                                 // unless, we are overwriting a method.
3722                                 //
3723                                 if (implementing.DeclaringType.IsInterface){
3724                                         if ((modifiers & Modifiers.OVERRIDE) == 0)
3725                                                 flags |= MethodAttributes.NewSlot;
3726                                 }
3727                                 flags |=
3728                                         MethodAttributes.Virtual |
3729                                         MethodAttributes.HideBySig;
3730
3731                                 // Set Final unless we're virtual, abstract or already overriding a method.
3732                                 if ((modifiers & (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE)) == 0)
3733                                         flags |= MethodAttributes.Final;
3734
3735                                 // Get the method name from the explicit interface.
3736                                 if (member.InterfaceType != null) {
3737                                         name = implementing.Name;
3738                                         method_name = prefix + name;
3739                                 }
3740
3741                                 IsImplementing = true;
3742                         }
3743
3744                         ec = new EmitContext (
3745                                 container, ds, Location, null, ReturnType, modifiers, false);
3746
3747                         //
3748                         // Create the MethodBuilder for the method
3749                         //
3750                         if ((flags & MethodAttributes.PinvokeImpl) != 0) {
3751                                 if ((modifiers & Modifiers.STATIC) == 0) {
3752                                         Report.Error (601, Location,
3753                                                       "The DllImport attribute must be specified on " +
3754                                                       "a method marked 'static' and 'extern'.");
3755                                         return false;
3756                                 }
3757                                 builder = dllimport_attribute.DefinePInvokeMethod (
3758                                         ec, container.TypeBuilder, method_name, flags,
3759                                         ReturnType, ParameterTypes);
3760                         } else if (builder == null)
3761                                 builder = container.TypeBuilder.DefineMethod (
3762                                         method_name, flags, CallingConventions,
3763                                         ReturnType, ParameterTypes);
3764                         else
3765                                 builder.SetGenericMethodSignature (
3766                                         flags, CallingConventions,
3767                                         ReturnType, ParameterTypes);
3768
3769                         if (builder == null)
3770                                 return false;
3771
3772                         if (GenericMethod != null) {
3773                                 if (!GenericMethod.DefineType (ec, builder))
3774                                         return false;
3775                         }
3776
3777                         if (container.CurrentType != null)
3778                                 declaring_type = container.CurrentType.ResolveType (ec);
3779                         else
3780                                 declaring_type = container.TypeBuilder;
3781
3782                         if ((modifiers & Modifiers.UNSAFE) != 0)
3783                                 builder.InitLocals = false;
3784
3785                         if (IsImplementing){
3786                                 //
3787                                 // clear the pending implemntation flag
3788                                 //
3789                                 if (member is Indexer) {
3790                                         container.Pending.ImplementIndexer (
3791                                                 member.InterfaceType, builder, ReturnType,
3792                                                 ParameterTypes, true);
3793                                 } else
3794                                         container.Pending.ImplementMethod (
3795                                                 member.InterfaceType, name, ReturnType,
3796                                                 ParameterTypes, member.IsExplicitImpl);
3797
3798                                 if (member.IsExplicitImpl)
3799                                         container.TypeBuilder.DefineMethodOverride (
3800                                                 builder, implementing);
3801
3802                         }
3803
3804                         if (!TypeManager.RegisterMethod (builder, ParameterInfo, ParameterTypes)) {
3805                                 Report.Error (111, Location,
3806                                               "Class `" + container.Name +
3807                                               "' already contains a definition with the " +
3808                                               "same return value and parameter types as the " +
3809                                               "'get' method of property `" + member.Name + "'");
3810                                 return false;
3811                         }
3812
3813                         TypeManager.AddMethod (builder, this);
3814
3815                         return true;
3816                 }
3817
3818                 //
3819                 // Emits the code
3820                 // 
3821                 public virtual void Emit (TypeContainer container, Block block, object kind)
3822                 {
3823                         ILGenerator ig;
3824                         EmitContext ec;
3825
3826                         if ((flags & MethodAttributes.PinvokeImpl) == 0)
3827                                 ig = builder.GetILGenerator ();
3828                         else
3829                                 ig = null;
3830
3831                         ec = new EmitContext (container, ds, Location, ig, ReturnType, modifiers, false);
3832
3833                         if (OptAttributes != null)
3834                                 Attribute.ApplyAttributes (ec, builder, kind, OptAttributes);
3835
3836                         if (member is MethodCore)
3837                                 MethodCore.LabelParameters (ec, MethodBuilder,
3838                                                             ((MethodCore) member).Parameters,
3839                                                             OptAttributes,
3840                                                             Location);
3841                         
3842                         SymbolWriter sw = CodeGen.SymbolWriter;
3843                         
3844                         //
3845                         // abstract or extern methods have no bodies
3846                         //
3847                         if ((modifiers & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0){
3848                                 if (block == null) {
3849                                         if ((sw != null) && ((modifiers & Modifiers.EXTERN) != 0) &&
3850                                             !Location.IsNull (Location) &&
3851                                             (Location.SymbolDocument != null)) {
3852                                                 sw.OpenMethod (container, MethodBuilder, Location, Location);
3853                                                 sw.CloseMethod ();
3854                                         }
3855
3856                                         return;
3857                                 }
3858
3859                                 //
3860                                 // abstract or extern methods have no bodies.
3861                                 //
3862                                 if ((modifiers & Modifiers.ABSTRACT) != 0)
3863                                         Report.Error (
3864                                                 500, Location, "Abstract method `" +
3865                                                 TypeManager.CSharpSignature (builder) +
3866                                                 "' can not have a body");
3867
3868                                 if ((modifiers & Modifiers.EXTERN) != 0)
3869                                         Report.Error (
3870                                                 179, Location, "External method `" +
3871                                                 TypeManager.CSharpSignature (builder) +
3872                                                 "' can not have a body");
3873
3874                                 return;
3875                         }
3876
3877                         //
3878                         // Methods must have a body unless they're extern or abstract
3879                         //
3880                         if (block == null) {
3881                                 Report.Error (
3882                                         501, Location, "Method `" +
3883                                         TypeManager.CSharpSignature (builder) +
3884                                         "' must declare a body since it is not marked " +
3885                                         "abstract or extern");
3886                                 return;
3887                         }
3888
3889                         //
3890                         // Handle destructors specially
3891                         //
3892                         // FIXME: This code generates buggy code
3893                         //
3894                                 if ((sw != null) && !Location.IsNull (Location) &&
3895                             !Location.IsNull (block.EndLocation) &&
3896                             (Location.SymbolDocument != null)) {
3897                                         sw.OpenMethod (container, MethodBuilder, Location, block.EndLocation);
3898
3899                                 if (member is Destructor)
3900                                         EmitDestructor (ec, block);
3901                                 else
3902                                         ec.EmitTopBlock (block, ParameterInfo, Location);
3903
3904                                         sw.CloseMethod ();
3905                         } else {
3906                                 if (member is Destructor)
3907                                         EmitDestructor (ec, block);
3908                                 else
3909                                         ec.EmitTopBlock (block, ParameterInfo, Location);
3910                         }
3911                 }
3912
3913                 void EmitDestructor (EmitContext ec, Block block)
3914                 {
3915                         ILGenerator ig = ec.ig;
3916                         
3917                         Label finish = ig.DefineLabel ();
3918
3919                         block.SetDestructor ();
3920                         
3921                         ig.BeginExceptionBlock ();
3922                         ec.ReturnLabel = finish;
3923                         ec.HasReturnLabel = true;
3924                         ec.EmitTopBlock (block, null, Location);
3925                         
3926                         // ig.MarkLabel (finish);
3927                         ig.BeginFinallyBlock ();
3928                         
3929                         if (ec.ContainerType.BaseType != null) {
3930                                 Expression member_lookup = Expression.MemberLookup (
3931                                         ec, ec.ContainerType.BaseType, null, ec.ContainerType.BaseType,
3932                                         "Finalize", 0, MemberTypes.Method, Expression.AllBindingFlags, Location);
3933
3934                                 if (member_lookup != null){
3935                                         MethodGroupExpr parent_destructor = ((MethodGroupExpr) member_lookup);
3936                                 
3937                                         ig.Emit (OpCodes.Ldarg_0);
3938                                         ig.Emit (OpCodes.Call, (MethodInfo) parent_destructor.Methods [0]);
3939                                 }
3940                         }
3941                         
3942                         ig.EndExceptionBlock ();
3943                         //ig.MarkLabel (ec.ReturnLabel);
3944                         ig.Emit (OpCodes.Ret);
3945                 }
3946         }
3947
3948         public class Destructor : Method {
3949
3950                 public Destructor (DeclSpace ds, Expression return_type, int mod, string name,
3951                                    Parameters parameters, Attributes attrs, Location l)
3952                         : base (ds, return_type, mod, false, new MemberName (name),
3953                                 parameters, attrs, l)
3954                 { }
3955
3956         }
3957         
3958         abstract public class MemberBase : MemberCore {
3959                 public Expression Type;
3960
3961                 protected MethodAttributes flags;
3962
3963                 protected readonly int explicit_mod_flags;
3964
3965                 public readonly MemberName MemberName;
3966
3967                 //
3968                 // The "short" name of this property / indexer / event.  This is the
3969                 // name without the explicit interface.
3970                 //
3971                 public string ShortName;
3972
3973                 //
3974                 // The type of this property / indexer / event
3975                 //
3976                 public Type MemberType;
3977
3978                 //
3979                 // If true, this is an explicit interface implementation
3980                 //
3981                 public bool IsExplicitImpl = false;
3982
3983                 //
3984                 // The name of the interface we are explicitly implementing
3985                 //
3986                 public Expression ExplicitInterfaceName = null;
3987
3988                 //
3989                 // Whether this is an interface member.
3990                 //
3991                 public bool IsInterface;
3992
3993                 //
3994                 // If true, the interface type we are explicitly implementing
3995                 //
3996                 public Type InterfaceType = null;
3997
3998                 //
3999                 // The method we're overriding if this is an override method.
4000                 //
4001                 protected MethodInfo parent_method = null;
4002                 public MethodInfo ParentMethod {
4003                         get {
4004                                 return parent_method;
4005                         }
4006                 }
4007
4008                 //
4009                 // The constructor is only exposed to our children
4010                 //
4011                 protected MemberBase (Expression type, int mod, int allowed_mod, int def_mod,
4012                                       MemberName name, Attributes attrs, Location loc)
4013                         : base (name.GetMemberName (), attrs, loc)
4014                 {
4015                         explicit_mod_flags = mod;
4016                         Type = type;
4017                         MemberName = name;
4018                         ModFlags = Modifiers.Check (allowed_mod, mod, def_mod, loc);
4019                 }
4020
4021                 protected virtual bool CheckBase (TypeContainer container)
4022                 {
4023                         if ((container is Struct) || (RootContext.WarningLevel > 3)){
4024                                 if ((ModFlags & Modifiers.PROTECTED) != 0 && (container.ModFlags & Modifiers.SEALED) != 0){
4025                                         if (container is Struct){
4026                                                 Report.Error (666, Location, "Protected member in struct declaration");
4027                                                 return false;
4028                                         } else
4029                                                 Report.Warning (628, Location, "Member " + container.MakeName (Name) + " protected in sealed class");
4030                                 }
4031                         }
4032                         return true;
4033                 }
4034
4035                 protected void WarningNotHiding (TypeContainer parent)
4036                 {
4037                         Report.Warning (
4038                                 109, Location,
4039                                 "The member " + parent.MakeName (Name) + " does not hide an " +
4040                                 "inherited member.  The keyword new is not required");
4041                                                            
4042                 }
4043
4044                 void Error_CannotChangeAccessModifiers (TypeContainer parent, MethodInfo parent_method,
4045                                                         string name)
4046                 {
4047                         //
4048                         // FIXME: report the old/new permissions?
4049                         //
4050                         Report.Error (
4051                                 507, Location, parent.MakeName (Name) +
4052                                 ": can't change the access modifiers when overriding inherited " +
4053                                 "member `" + name + "'");
4054                 }
4055
4056                 protected abstract bool CheckGenericOverride (MethodInfo method, string name);
4057                 
4058                 //
4059                 // Performs various checks on the MethodInfo `mb' regarding the modifier flags
4060                 // that have been defined.
4061                 //
4062                 // `name' is the user visible name for reporting errors (this is used to
4063                 // provide the right name regarding method names and properties)
4064                 //
4065                 protected bool CheckMethodAgainstBase (TypeContainer parent, MethodAttributes my_attrs,
4066                                                        MethodInfo mb, string name)
4067                 {
4068                         bool ok = true;
4069                         
4070                         if ((ModFlags & Modifiers.OVERRIDE) != 0){
4071                                 if (!(mb.IsAbstract || mb.IsVirtual)){
4072                                         Report.Error (
4073                                                 506, Location, parent.MakeName (Name) +
4074                                                 ": cannot override inherited member `" +
4075                                                 name + "' because it is not " +
4076                                                 "virtual, abstract or override");
4077                                         ok = false;
4078                                 }
4079                                 
4080                                 // Now we check that the overriden method is not final
4081                                 
4082                                 if (mb.IsFinal) {
4083                                         // This happens when implementing interface methods.
4084                                         if (mb.IsHideBySig && mb.IsVirtual) {
4085                                                 Report.Error (
4086                                                         506, Location, parent.MakeName (Name) +
4087                                                         ": cannot override inherited member `" +
4088                                                         name + "' because it is not " +
4089                                                         "virtual, abstract or override");
4090                                         } else
4091                                                 Report.Error (239, Location, parent.MakeName (Name) + " : cannot " +
4092                                                               "override inherited member `" + name +
4093                                                               "' because it is sealed.");
4094                                         ok = false;
4095                                 }
4096
4097                                 //
4098                                 // Check that the constraints match when overriding a
4099                                 // generic method.
4100                                 //
4101
4102                                 if (!CheckGenericOverride (mb, name))
4103                                         ok = false;
4104
4105                                 //
4106                                 // Check that the permissions are not being changed
4107                                 //
4108                                 MethodAttributes thisp = my_attrs & MethodAttributes.MemberAccessMask;
4109                                 MethodAttributes parentp = mb.Attributes & MethodAttributes.MemberAccessMask;
4110
4111                                 //
4112                                 // special case for "protected internal"
4113                                 //
4114
4115                                 if ((parentp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
4116                                         //
4117                                         // when overriding protected internal, the method can be declared
4118                                         // protected internal only within the same assembly
4119                                         //
4120
4121                                         if ((thisp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
4122                                                 if (parent.TypeBuilder.Assembly != mb.DeclaringType.Assembly){
4123                                                         //
4124                                                         // assemblies differ - report an error
4125                                                         //
4126                                                         
4127                                                         Error_CannotChangeAccessModifiers (parent, mb, name);
4128                                                     ok = false;
4129                                                 } else if (thisp != parentp) {
4130                                                         //
4131                                                         // same assembly, but other attributes differ - report an error
4132                                                         //
4133                                                         
4134                                                         Error_CannotChangeAccessModifiers (parent, mb, name);
4135                                                         ok = false;
4136                                                 };
4137                                         } else if ((thisp & MethodAttributes.Family) != MethodAttributes.Family) {
4138                                                 //
4139                                                 // if it's not "protected internal", it must be "protected"
4140                                                 //
4141
4142                                                 Error_CannotChangeAccessModifiers (parent, mb, name);
4143                                                 ok = false;
4144                                         } else if (parent.TypeBuilder.Assembly == mb.DeclaringType.Assembly) {
4145                                                 //
4146                                                 // protected within the same assembly - an error
4147                                                 //
4148                                                 Error_CannotChangeAccessModifiers (parent, mb, name);
4149                                                 ok = false;
4150                                         } else if ((thisp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem)) != 
4151                                                    (parentp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem))) {
4152                                                 //
4153                                                 // protected ok, but other attributes differ - report an error
4154                                                 //
4155                                                 Error_CannotChangeAccessModifiers (parent, mb, name);
4156                                                 ok = false;
4157                                         }
4158                                 } else {
4159                                         if (thisp != parentp){
4160                                                 Error_CannotChangeAccessModifiers (parent, mb, name);
4161                                                 ok = false;
4162                                         }
4163                                 }
4164                         }
4165
4166                         if (mb.IsVirtual || mb.IsAbstract){
4167                                 if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE)) == 0){
4168                                         if (Name != "Finalize"){
4169                                                 Report.Warning (
4170                                                         114, 2, Location, parent.MakeName (Name) + 
4171                                                         " hides inherited member `" + name +
4172                                                         "'.  To make the current member override that " +
4173                                                         "implementation, add the override keyword, " +
4174                                                         "otherwise use the new keyword");
4175                                                 ModFlags |= Modifiers.NEW;
4176                                         }
4177                                 }
4178                         } else {
4179                                 if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE)) == 0){
4180                                         if (Name != "Finalize"){
4181                                                 Report.Warning (
4182                                                         108, 1, Location, "The keyword new is required on " +
4183                                                         parent.MakeName (Name) + " because it hides " +
4184                                                         "inherited member `" + name + "'");
4185                                                 ModFlags |= Modifiers.NEW;
4186                                         }
4187                                 }
4188                         }
4189
4190                         return ok;
4191                 }
4192
4193                 protected virtual bool CheckParameters (DeclSpace ds, Type [] parameters)
4194                 {
4195                         bool error = false;
4196
4197                         foreach (Type partype in parameters){
4198                                 if (partype.IsPointer){
4199                                         if (!UnsafeOK (ds))
4200                                                 error = true;
4201                                         if (!TypeManager.VerifyUnManaged (TypeManager.GetElementType (partype), Location))
4202                                                 error = true;
4203                                 }
4204
4205                                 if (ds.AsAccessible (partype, ModFlags))
4206                                         continue;
4207
4208                                 if (this is Indexer)
4209                                         Report.Error (55, Location,
4210                                                       "Inconsistent accessibility: parameter type `" +
4211                                                       TypeManager.CSharpName (partype) + "' is less " +
4212                                                       "accessible than indexer `" + Name + "'");
4213                                 else if ((this is Method) && ((Method) this).IsOperator)
4214                                         Report.Error (57, Location,
4215                                                       "Inconsistent accessibility: parameter type `" +
4216                                                       TypeManager.CSharpName (partype) + "' is less " +
4217                                                       "accessible than operator `" + Name + "'");
4218                                 else
4219                                         Report.Error (51, Location,
4220                                                       "Inconsistent accessibility: parameter type `" +
4221                                                       TypeManager.CSharpName (partype) + "' is less " +
4222                                                       "accessible than method `" + Name + "'");
4223                                 error = true;
4224                         }
4225
4226                         return !error;
4227                 }
4228
4229                 protected virtual bool DoDefine (DeclSpace decl, TypeContainer container)
4230                 {
4231                         if (Name == null)
4232                                 Name = "this";
4233
4234                         if (IsInterface) {
4235                                 ModFlags = Modifiers.PUBLIC |
4236                                         Modifiers.ABSTRACT |
4237                                         Modifiers.VIRTUAL;
4238
4239                                 flags = MethodAttributes.Public |
4240                                         MethodAttributes.Abstract |
4241                                         MethodAttributes.HideBySig |
4242                                         MethodAttributes.NewSlot |
4243                                         MethodAttributes.Virtual;
4244                         } else {
4245                         if (!container.MethodModifiersValid (ModFlags, Name, Location))
4246                                 return false;
4247
4248                         flags = Modifiers.MethodAttr (ModFlags);
4249                         }
4250
4251                         // Lookup Type, verify validity
4252                         MemberType = decl.ResolveType (Type, false, Location);
4253                         if (MemberType == null)
4254                                 return false;
4255
4256                         if ((container.ModFlags & Modifiers.SEALED) != 0){
4257                                 if ((ModFlags & (Modifiers.VIRTUAL|Modifiers.ABSTRACT)) != 0){
4258                                         Report.Error (549, Location, "Virtual method can not be contained in sealed class");
4259                                         return false;
4260                                 }
4261                         }
4262                         
4263                         // verify accessibility
4264                         if (!container.AsAccessible (MemberType, ModFlags)) {
4265                                 if (this is Property)
4266                                         Report.Error (53, Location,
4267                                                       "Inconsistent accessibility: property type `" +
4268                                                       TypeManager.CSharpName (MemberType) + "' is less " +
4269                                                       "accessible than property `" + Name + "'");
4270                                 else if (this is Indexer)
4271                                         Report.Error (54, Location,
4272                                                       "Inconsistent accessibility: indexer return type `" +
4273                                                       TypeManager.CSharpName (MemberType) + "' is less " +
4274                                                       "accessible than indexer `" + Name + "'");
4275                                 else if (this is Method) {
4276                                         if (((Method) this).IsOperator)
4277                                                 Report.Error (56, Location,
4278                                                               "Inconsistent accessibility: return type `" +
4279                                                               TypeManager.CSharpName (MemberType) + "' is less " +
4280                                                               "accessible than operator `" + Name + "'");
4281                                         else
4282                                                 Report.Error (50, Location,
4283                                                               "Inconsistent accessibility: return type `" +
4284                                                               TypeManager.CSharpName (MemberType) + "' is less " +
4285                                                               "accessible than method `" + Name + "'");
4286                                 } else
4287                                         Report.Error (52, Location,
4288                                                       "Inconsistent accessibility: field type `" +
4289                                                       TypeManager.CSharpName (MemberType) + "' is less " +
4290                                                       "accessible than field `" + Name + "'");
4291                                 return false;
4292                         }
4293
4294                         if (MemberType.IsPointer && !UnsafeOK (container))
4295                                 return false;
4296                         
4297                         //
4298                         // Check for explicit interface implementation
4299                         //
4300                         if (MemberName.Left != null) {
4301                                 ExplicitInterfaceName = MemberName.Left.GetTypeExpression (Location);
4302                                 ShortName = MemberName.Name;
4303                         } else
4304                                 ShortName = Name;
4305
4306                         if (ExplicitInterfaceName != null) {
4307                                 InterfaceType = container.ResolveType (
4308                                         ExplicitInterfaceName, false, Location);
4309                                 if (InterfaceType == null)
4310                                         return false;
4311
4312                                 if (InterfaceType.IsClass) {
4313                                         Report.Error (538, Location, "'{0}' in explicit interface declaration is not an interface", ExplicitInterfaceName);
4314                                         return false;
4315                                 }
4316
4317                                 // Compute the full name that we need to export.
4318                                 Name = InterfaceType.FullName + "." + ShortName;
4319                                 
4320                                 if (!container.VerifyImplements (InterfaceType, ShortName, Name, Location))
4321                                         return false;
4322                                 
4323                                 Modifiers.Check (Modifiers.AllowedExplicitImplFlags, explicit_mod_flags, 0, Location);
4324                                 
4325                                 IsExplicitImpl = true;
4326                         } else
4327                                 IsExplicitImpl = false;
4328
4329                         return true;
4330                 }
4331         }
4332
4333         //
4334         // Fields and Events both generate FieldBuilders, we use this to share 
4335         // their common bits.  This is also used to flag usage of the field
4336         //
4337         abstract public class FieldBase : MemberBase {
4338                 public FieldBuilder  FieldBuilder;
4339                 public Status status;
4340
4341                 [Flags]
4342                 public enum Status : byte { ASSIGNED = 1, USED = 2 }
4343
4344                 //
4345                 // The constructor is only exposed to our children
4346                 //
4347                 protected FieldBase (Expression type, int mod, int allowed_mod, MemberName name,
4348                                      object init, Attributes attrs, Location loc)
4349                         : base (type, mod, allowed_mod, Modifiers.PRIVATE, name, attrs, loc)
4350                 {
4351                         this.init = init;
4352                 }
4353
4354                 //
4355                 // Whether this field has an initializer.
4356                 //
4357                 public bool HasInitializer {
4358                         get {
4359                                 return init != null;
4360                         }
4361                 }
4362
4363                 protected readonly Object init;
4364                 // Private.
4365                 Expression init_expr;
4366                 bool init_expr_initialized = false;
4367
4368                 protected override bool CheckGenericOverride (MethodInfo method, string name)
4369                 {
4370                         return true;
4371                 }
4372
4373                 //
4374                 // Resolves and returns the field initializer.
4375                 //
4376                 public Expression GetInitializerExpression (EmitContext ec)
4377                 {
4378                         if (init_expr_initialized)
4379                                 return init_expr;
4380
4381                         Expression e;
4382                         if (init is Expression)
4383                                 e = (Expression) init;
4384                         else
4385                                 e = new ArrayCreation (Type, "", (ArrayList)init, Location);
4386
4387                         ec.IsFieldInitializer = true;
4388                         e = e.DoResolve (ec);
4389                         ec.IsFieldInitializer = false;
4390
4391                         init_expr = e;
4392                         init_expr_initialized = true;
4393
4394                         return init_expr;
4395                 }
4396
4397                 public void SetAssigned ()
4398                 {
4399                         status |= Status.ASSIGNED;
4400                 }
4401         }
4402
4403         //
4404         // The Field class is used to represents class/struct fields during parsing.
4405         //
4406         public class Field : FieldBase {
4407                 // <summary>
4408                 //   Modifiers allowed in a class declaration
4409                 // </summary>
4410                 const int AllowedModifiers =
4411                         Modifiers.NEW |
4412                         Modifiers.PUBLIC |
4413                         Modifiers.PROTECTED |
4414                         Modifiers.INTERNAL |
4415                         Modifiers.PRIVATE |
4416                         Modifiers.STATIC |
4417                         Modifiers.VOLATILE |
4418                         Modifiers.UNSAFE |
4419                         Modifiers.READONLY;
4420
4421                 public Field (Expression type, int mod, string name, Object expr_or_array_init,
4422                               Attributes attrs, Location loc)
4423                         : base (type, mod, AllowedModifiers, new MemberName (name),
4424                                 expr_or_array_init, attrs, loc)
4425                 {
4426                 }
4427
4428                 public override bool Define (TypeContainer container)
4429                 {
4430                         Type t = container.ResolveType (Type, false, Location);
4431                         
4432                         if (t == null)
4433                                 return false;
4434
4435                         CheckBase (container);
4436                         
4437                         if (!container.AsAccessible (t, ModFlags)) {
4438                                 Report.Error (52, Location,
4439                                               "Inconsistent accessibility: field type `" +
4440                                               TypeManager.CSharpName (t) + "' is less " +
4441                                               "accessible than field `" + Name + "'");
4442                                 return false;
4443                         }
4444
4445                         if (t.IsPointer && !UnsafeOK (container))
4446                                 return false;
4447                         
4448                         if (RootContext.WarningLevel > 1){
4449                                 Type ptype = container.TypeBuilder.BaseType;
4450
4451                                 // ptype is only null for System.Object while compiling corlib.
4452                                 if (ptype != null){
4453                                         TypeContainer.FindMembers (
4454                                                 ptype, MemberTypes.Method,
4455                                                 BindingFlags.Public |
4456                                                 BindingFlags.Static | BindingFlags.Instance,
4457                                                 System.Type.FilterName, Name);
4458                                 }
4459                         }
4460
4461                         if ((ModFlags & Modifiers.VOLATILE) != 0){
4462                                 if (!t.IsClass){
4463                                         Type vt = t;
4464                                         
4465                                         if (TypeManager.IsEnumType (vt))
4466                                                 vt = TypeManager.EnumToUnderlying (t);
4467
4468                                         if (!((vt == TypeManager.bool_type) ||
4469                                               (vt == TypeManager.sbyte_type) ||
4470                                               (vt == TypeManager.byte_type) ||
4471                                               (vt == TypeManager.short_type) ||    
4472                                               (vt == TypeManager.ushort_type) ||
4473                                               (vt == TypeManager.int32_type) ||    
4474                                               (vt == TypeManager.uint32_type) ||    
4475                                               (vt == TypeManager.char_type) ||    
4476                                               (vt == TypeManager.float_type))){
4477                                                 Report.Error (
4478                                                         677, Location, container.MakeName (Name) +
4479                                                         " A volatile field can not be of type `" +
4480                                                         TypeManager.CSharpName (vt) + "'");
4481                                                 return false;
4482                                         }
4483                                 }
4484
4485                                 if ((ModFlags & Modifiers.READONLY) != 0){
4486                                         Report.Error (
4487                                                       678, Location,
4488                                                       "A field can not be both volatile and readonly");
4489                                         return false;
4490                                 }
4491                         }
4492
4493                         FieldAttributes fa = Modifiers.FieldAttr (ModFlags);
4494
4495                         if (container is Struct && 
4496                             ((fa & FieldAttributes.Static) == 0) &&
4497                             t == container.TypeBuilder &&
4498                             !TypeManager.IsBuiltinType (t)){
4499                                 Report.Error (523, Location, "Struct member `" + container.Name + "." + Name + 
4500                                               "' causes a cycle in the structure layout");
4501                                 return false;
4502                         }
4503
4504                         try {
4505                         FieldBuilder = container.TypeBuilder.DefineField (
4506                                 Name, t, Modifiers.FieldAttr (ModFlags));
4507
4508                         TypeManager.RegisterFieldBase (FieldBuilder, this);
4509                         }
4510                         catch (ArgumentException) {
4511                                 Report.Warning (-24, Location, "The Microsoft runtime is unable to use [void|void*] as a field type, try using the Mono runtime.");
4512                                 return false;
4513                         }
4514
4515                         return true;
4516                 }
4517
4518                 public void Emit (TypeContainer tc)
4519                 {
4520                         EmitContext ec = new EmitContext (tc, Location, null,
4521                                                           FieldBuilder.FieldType, ModFlags);
4522
4523                         Attribute.ApplyAttributes (ec, FieldBuilder, this, OptAttributes);
4524                 }
4525         }
4526
4527         //
4528         // `set' and `get' accessors are represented with an Accessor.
4529         // 
4530         public class Accessor {
4531                 //
4532                 // Null if the accessor is empty, or a Block if not
4533                 //
4534                 public Block Block;
4535                 public Attributes OptAttributes;
4536                 
4537                 public Accessor (Block b, Attributes attrs)
4538                 {
4539                         Block = b;
4540                         OptAttributes = attrs;
4541                 }
4542         }
4543
4544         //
4545         // Properties and Indexers both generate PropertyBuilders, we use this to share 
4546         // their common bits.
4547         //
4548         abstract public class PropertyBase : MethodCore {
4549                 public Accessor Get, Set;
4550                 public PropertyBuilder PropertyBuilder;
4551                 public MethodBuilder GetBuilder, SetBuilder;
4552                 public MethodData GetData, SetData;
4553
4554                 protected EmitContext ec;
4555
4556                 public PropertyBase (DeclSpace ds, Expression type, int mod_flags,
4557                                      int allowed_mod, bool is_iface, MemberName name,
4558                                      Parameters parameters, Attributes attrs,
4559                                      Accessor get_block, Accessor set_block,
4560                                      Location loc)
4561                         : base (ds, type, mod_flags, allowed_mod, is_iface, name,
4562                                 attrs, parameters, loc)
4563                 {
4564                         Get = get_block;
4565                         Set = set_block;
4566                 }
4567
4568                 protected override bool DoDefine (DeclSpace decl, TypeContainer container)
4569                 {
4570                         if (!base.DoDefine (decl, container))
4571                                 return false;
4572
4573                         ec = new EmitContext (container, Location, null, MemberType, ModFlags);
4574
4575                         return true;
4576                 }
4577
4578                 //
4579                 // Checks our base implementation if any
4580                 //
4581                 protected override bool CheckBase (TypeContainer container)
4582                 {
4583                         base.CheckBase (container);
4584                         
4585                         // Check whether arguments were correct.
4586                         if (!DoDefineParameters ())
4587                                 return false;
4588
4589                         if (IsExplicitImpl)
4590                                 return true;
4591
4592                         //
4593                         // Check in our class for dups
4594                         //
4595                         ArrayList ar = container.Properties;
4596                         if (ar != null) {
4597                                 int arLen = ar.Count;
4598                                         
4599                                 for (int i = 0; i < arLen; i++) {
4600                                         Property m = (Property) ar [i];
4601                                         if (IsDuplicateImplementation (container, m))
4602                                                 return false;
4603                                 }
4604                         }
4605
4606                         if (IsInterface)
4607                                 return true;
4608
4609                         string report_name;
4610                         MethodSignature ms, base_ms;
4611                         if (this is Indexer) {
4612                                 string name, base_name;
4613
4614                                 report_name = "this";
4615                                 name = TypeManager.IndexerPropertyName (container.TypeBuilder);
4616                                 ms = new MethodSignature (name, null, ParameterTypes);
4617                                 base_name = TypeManager.IndexerPropertyName (container.TypeBuilder.BaseType);
4618                                 base_ms = new MethodSignature (base_name, null, ParameterTypes);
4619                         } else {
4620                                 report_name = Name;
4621                                 ms = base_ms = new MethodSignature (Name, null, ParameterTypes);
4622                         }
4623
4624                         //
4625                         // Verify if the parent has a type with the same name, and then
4626                         // check whether we have to create a new slot for it or not.
4627                         //
4628                         Type ptype = container.TypeBuilder.BaseType;
4629
4630                         // ptype is only null for System.Object while compiling corlib.
4631                         if (ptype == null) {
4632                                 if ((ModFlags & Modifiers.NEW) != 0)
4633                                         WarningNotHiding (container);
4634
4635                                 return true;
4636                         }
4637
4638                         PropertyInfo parent_property = null;
4639                         
4640                         //
4641                         // Explicit implementations do not have `parent' methods, however,
4642                         // the member cache stores them there. Without this check, we get
4643                         // an incorrect warning in corlib.
4644                         //
4645                         if (! IsExplicitImpl) {
4646                                 parent_property = (PropertyInfo) ((IMemberContainer)container).Parent.MemberCache.FindMemberToOverride (
4647                                         container.TypeBuilder, Name, ParameterTypes, true);
4648                         }
4649
4650                         if (parent_property != null) {
4651                                 string name = parent_property.DeclaringType.Name + "." +
4652                                         parent_property.Name;
4653
4654                                 MethodInfo get, set, parent_method;
4655                                 get = parent_property.GetGetMethod (true);
4656                                 set = parent_property.GetSetMethod (true);
4657
4658                                 if (get != null)
4659                                         parent_method = get;
4660                                 else if (set != null)
4661                                         parent_method = set;
4662                                 else
4663                                         throw new Exception ("Internal error!");
4664
4665                                 if (!CheckMethodAgainstBase (container, flags, parent_method, name))
4666                                         return false;
4667
4668                                 if ((ModFlags & Modifiers.NEW) == 0) {
4669                                         Type parent_type = TypeManager.TypeToCoreType (
4670                                                 parent_property.PropertyType);
4671
4672                                         if (parent_type != MemberType) {
4673                                                 Report.Error (
4674                                                         508, Location, container.MakeName (Name) + ": cannot " +
4675                                                         "change return type when overriding " +
4676                                                         "inherited member " + name);
4677                                                 return false;
4678                                         }
4679                                 }
4680                         } else {
4681                                 if ((ModFlags & Modifiers.NEW) != 0)
4682                                         WarningNotHiding (container);
4683
4684                                 if ((ModFlags & Modifiers.OVERRIDE) != 0){
4685                                         if (this is Indexer)
4686                                                 Report.Error (115, Location,
4687                                                               container.MakeName (Name) +
4688                                                               " no suitable indexers found to override");
4689                                         else
4690                                                 Report.Error (115, Location,
4691                                                               container.MakeName (Name) +
4692                                                               " no suitable properties found to override");
4693                                         return false;
4694                                 }
4695                         }
4696                         return true;
4697                 }
4698
4699                 public void Emit (TypeContainer tc)
4700                 {
4701                         //
4702                         // The PropertyBuilder can be null for explicit implementations, in that
4703                         // case, we do not actually emit the ".property", so there is nowhere to
4704                         // put the attribute
4705                         //
4706                         if (PropertyBuilder != null)
4707                                 Attribute.ApplyAttributes (ec, PropertyBuilder, this, OptAttributes);
4708
4709                         if (GetData != null) {
4710                                 GetData.Emit (tc, Get.Block, Get);
4711                                 Get.Block = null;
4712                         }
4713
4714                         if (SetData != null) {
4715                                 SetData.Emit (tc, Set.Block, Set);
4716                                 Set.Block = null;
4717                         }
4718                 }
4719         }
4720                         
4721         public class Property : PropertyBase, IIteratorContainer {
4722                 const int AllowedModifiers =
4723                         Modifiers.NEW |
4724                         Modifiers.PUBLIC |
4725                         Modifiers.PROTECTED |
4726                         Modifiers.INTERNAL |
4727                         Modifiers.PRIVATE |
4728                         Modifiers.STATIC |
4729                         Modifiers.SEALED |
4730                         Modifiers.OVERRIDE |
4731                         Modifiers.ABSTRACT |
4732                         Modifiers.UNSAFE |
4733                         Modifiers.EXTERN |
4734                         Modifiers.METHOD_YIELDS |
4735                         Modifiers.VIRTUAL;
4736
4737                 const int AllowedInterfaceModifiers =
4738                         Modifiers.NEW;
4739
4740                 public Property (DeclSpace ds, Expression type, int mod_flags, bool is_iface,
4741                                  MemberName name, Attributes attrs, Accessor get_block,
4742                                  Accessor set_block, Location loc)
4743                         : base (ds, type, mod_flags,
4744                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
4745                                 is_iface, name, Parameters.EmptyReadOnlyParameters, attrs,
4746                                 get_block, set_block, loc)
4747                 {
4748                 }
4749
4750                 public override bool Define (TypeContainer container)
4751                 {
4752                         if (!DoDefine (container, container))
4753                                 return false;
4754
4755                         if (!CheckBase (container))
4756                                 return false;
4757
4758                         flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
4759
4760                         if (Get != null) {
4761                                 Type [] parameters = TypeManager.NoTypes;
4762
4763                                 InternalParameters ip = new InternalParameters (
4764                                         container, Parameters.EmptyReadOnlyParameters);
4765
4766                                 GetData = new MethodData (container, this, "get", MemberType,
4767                                                           parameters, ip, CallingConventions.Standard,
4768                                                           Get.OptAttributes, ModFlags, flags, false);
4769
4770                                 //
4771                                 // Setup iterator if we are one
4772                                 //
4773                                 if ((ModFlags & Modifiers.METHOD_YIELDS) != 0){
4774                                         IteratorHandler ih = new  IteratorHandler (
4775                                                                                    "get", container, MemberType,
4776                                                                                    parameters, ip, ModFlags, Location);
4777                                         
4778                                         Block new_block = ih.Setup (block);
4779                                         if (new_block == null)
4780                                                 return false;
4781                                         block = new_block;
4782                                 }
4783                                 
4784                                 if (!GetData.Define (container))
4785                                         return false;
4786
4787                                 GetBuilder = GetData.MethodBuilder;
4788                         }
4789
4790                         if (Set != null) {
4791                                 Type [] parameters = new Type [1];
4792                                 parameters [0] = MemberType;
4793
4794                                 Parameter [] parms = new Parameter [1];
4795                                 parms [0] = new Parameter (Type, "value", Parameter.Modifier.NONE, null);
4796                                 InternalParameters ip = new InternalParameters (
4797                                         container, new Parameters (parms, null, Location));
4798
4799                                 SetData = new MethodData (container, this, "set", TypeManager.void_type,
4800                                                           parameters, ip, CallingConventions.Standard,
4801                                                           Set.OptAttributes, ModFlags, flags, false);
4802
4803                                 if (!SetData.Define (container))
4804                                         return false;
4805
4806                                 SetBuilder = SetData.MethodBuilder;
4807                                 SetBuilder.DefineParameter (1, ParameterAttributes.None, "value"); 
4808                         }
4809
4810                         // FIXME - PropertyAttributes.HasDefault ?
4811                         
4812                         PropertyAttributes prop_attr = PropertyAttributes.None;
4813                         if (!IsInterface)
4814                                 prop_attr |= PropertyAttributes.RTSpecialName |
4815                         PropertyAttributes.SpecialName;
4816
4817                         if (!IsExplicitImpl){
4818                                 PropertyBuilder = container.TypeBuilder.DefineProperty (
4819                                         Name, prop_attr, MemberType, null);
4820                                 
4821                                 if (Get != null)
4822                                         PropertyBuilder.SetGetMethod (GetBuilder);
4823                                 
4824                                 if (Set != null)
4825                                         PropertyBuilder.SetSetMethod (SetBuilder);
4826
4827                                 //
4828                                 // HACK for the reasons exposed above
4829                                 //
4830                                 if (!TypeManager.RegisterProperty (PropertyBuilder, GetBuilder, SetBuilder)) {
4831                                         Report.Error (
4832                                                 111, Location,
4833                                                 "Class `" + container.Name +
4834                                                 "' already contains a definition for the property `" +
4835                                                 Name + "'");
4836                                         return false;
4837                                 }
4838                         }
4839                         return true;
4840                 }
4841
4842                 public void SetYields ()
4843                 {
4844                         ModFlags |= Modifiers.METHOD_YIELDS;
4845                 }
4846         }
4847
4848         /// </summary>
4849         ///  Gigantic workaround  for lameness in SRE follows :
4850         ///  This class derives from EventInfo and attempts to basically
4851         ///  wrap around the EventBuilder so that FindMembers can quickly
4852         ///  return this in it search for members
4853         /// </summary>
4854         public class MyEventBuilder : EventInfo {
4855                 
4856                 //
4857                 // We use this to "point" to our Builder which is
4858                 // not really a MemberInfo
4859                 //
4860                 EventBuilder MyBuilder;
4861                 
4862                 //
4863                 // We "catch" and wrap these methods
4864                 //
4865                 MethodInfo raise, remove, add;
4866
4867                 EventAttributes attributes;
4868                 Type declaring_type, reflected_type, event_type;
4869                 string name;
4870
4871                 Event my_event;
4872
4873                 public MyEventBuilder (Event ev, TypeBuilder type_builder, string name, EventAttributes event_attr, Type event_type)
4874                 {
4875                         MyBuilder = type_builder.DefineEvent (name, event_attr, event_type);
4876
4877                         // And now store the values in our own fields.
4878                         
4879                         declaring_type = type_builder;
4880
4881                         reflected_type = type_builder;
4882                         
4883                         attributes = event_attr;
4884                         this.name = name;
4885                         my_event = ev;
4886                         this.event_type = event_type;
4887                 }
4888                 
4889                 //
4890                 // Methods that you have to override.  Note that you only need 
4891                 // to "implement" the variants that take the argument (those are
4892                 // the "abstract" methods, the others (GetAddMethod()) are 
4893                 // regular.
4894                 //
4895                 public override MethodInfo GetAddMethod (bool nonPublic)
4896                 {
4897                         return add;
4898                 }
4899                 
4900                 public override MethodInfo GetRemoveMethod (bool nonPublic)
4901                 {
4902                         return remove;
4903                 }
4904                 
4905                 public override MethodInfo GetRaiseMethod (bool nonPublic)
4906                 {
4907                         return raise;
4908                 }
4909                 
4910                 //
4911                 // These methods make "MyEventInfo" look like a Builder
4912                 //
4913                 public void SetRaiseMethod (MethodBuilder raiseMethod)
4914                 {
4915                         raise = raiseMethod;
4916                         MyBuilder.SetRaiseMethod (raiseMethod);
4917                 }
4918
4919                 public void SetRemoveOnMethod (MethodBuilder removeMethod)
4920                 {
4921                         remove = removeMethod;
4922                         MyBuilder.SetRemoveOnMethod (removeMethod);
4923                 }
4924
4925                 public void SetAddOnMethod (MethodBuilder addMethod)
4926                 {
4927                         add = addMethod;
4928                         MyBuilder.SetAddOnMethod (addMethod);
4929                 }
4930
4931                 public void SetCustomAttribute (CustomAttributeBuilder cb)
4932                 {
4933                         MyBuilder.SetCustomAttribute (cb);
4934                 }
4935                 
4936                 public override object [] GetCustomAttributes (bool inherit)
4937                 {
4938                         // FIXME : There's nothing which can be seemingly done here because
4939                         // we have no way of getting at the custom attribute objects of the
4940                         // EventBuilder !
4941                         return null;
4942                 }
4943
4944                 public override object [] GetCustomAttributes (Type t, bool inherit)
4945                 {
4946                         // FIXME : Same here !
4947                         return null;
4948                 }
4949
4950                 public override bool IsDefined (Type t, bool b)
4951                 {
4952                         return true;
4953                 }
4954
4955                 public override EventAttributes Attributes {
4956                         get {
4957                                 return attributes;
4958                         }
4959                 }
4960
4961                 public override string Name {
4962                         get {
4963                                 return name;
4964                         }
4965                 }
4966
4967                 public override Type DeclaringType {
4968                         get {
4969                                 return declaring_type;
4970                         }
4971                 }
4972
4973                 public override Type ReflectedType {
4974                         get {
4975                                 return reflected_type;
4976                         }
4977                 }
4978
4979                 public Type EventType {
4980                         get {
4981                                 return event_type;
4982                         }
4983                 }
4984                 
4985                 public void SetUsed ()
4986                 {
4987                         if (my_event != null)
4988                                 my_event.status = (FieldBase.Status.ASSIGNED | FieldBase.Status.USED);
4989                 }
4990         }
4991         
4992         public class Event : FieldBase {
4993                 const int AllowedModifiers =
4994                         Modifiers.NEW |
4995                         Modifiers.PUBLIC |
4996                         Modifiers.PROTECTED |
4997                         Modifiers.INTERNAL |
4998                         Modifiers.PRIVATE |
4999                         Modifiers.STATIC |
5000                         Modifiers.VIRTUAL |
5001                         Modifiers.SEALED |
5002                         Modifiers.OVERRIDE |
5003                         Modifiers.UNSAFE |
5004                         Modifiers.ABSTRACT;
5005
5006                 const int AllowedInterfaceModifiers =
5007                         Modifiers.NEW;
5008
5009                 public readonly Accessor  Add;
5010                 public readonly Accessor  Remove;
5011                 public MyEventBuilder     EventBuilder;
5012
5013                 public MethodBuilder AddBuilder, RemoveBuilder;
5014                 MethodData AddData, RemoveData;
5015                 
5016                 public Event (Expression type, int mod_flags, bool is_iface, MemberName name,
5017                               Object init, Attributes attrs, Accessor add, Accessor remove,
5018                               Location loc)
5019                         : base (type, mod_flags,
5020                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
5021                                 name, init, attrs, loc)
5022                 {
5023                         Add = add;
5024                         Remove = remove;
5025                         IsInterface = is_iface;
5026                 }
5027
5028                 public override bool Define (TypeContainer container)
5029                 {
5030                         EventAttributes e_attr = EventAttributes.RTSpecialName | EventAttributes.SpecialName;
5031                         MethodAttributes m_attr = MethodAttributes.HideBySig | MethodAttributes.SpecialName
5032 ;
5033                         if (!DoDefine (container, container))
5034                                 return false;
5035
5036                         if (init != null && ((ModFlags & Modifiers.ABSTRACT) != 0)){
5037                                 Report.Error (74, Location, "'" + container.Name + "." + Name +
5038                                               "': abstract event can not have an initializer");
5039                                 return false;
5040                         }
5041
5042                         if (!TypeManager.IsDelegateType (MemberType)) {
5043                                 Report.Error (66, Location, "'" + container.Name + "." + Name +
5044                                               "' : event must be of a delegate type");
5045                                 return false;
5046                         }
5047
5048                         Type [] parameter_types = new Type [1];
5049                         parameter_types [0] = MemberType;
5050
5051                         Parameter [] parms = new Parameter [1];
5052                         parms [0] = new Parameter (Type, "value", Parameter.Modifier.NONE, null);
5053                         InternalParameters ip = new InternalParameters (
5054                                 container, new Parameters (parms, null, Location)); 
5055
5056                         if (!CheckBase (container))
5057                                 return false;
5058
5059                         //
5060                         // Now define the accessors
5061                         //
5062                         AddData = new MethodData (container, this, "add", TypeManager.void_type,
5063                                                   parameter_types, ip, CallingConventions.Standard,
5064                                                   (Add != null) ? Add.OptAttributes : null,
5065                                                   ModFlags, flags | m_attr, false);
5066
5067                         if (!AddData.Define (container))
5068                                 return false;
5069
5070                         AddBuilder = AddData.MethodBuilder;
5071                         AddBuilder.DefineParameter (1, ParameterAttributes.None, "value");
5072
5073                         RemoveData = new MethodData (container, this, "remove", TypeManager.void_type,
5074                                                      parameter_types, ip, CallingConventions.Standard,
5075                                                      (Remove != null) ? Remove.OptAttributes : null,
5076                                                      ModFlags, flags | m_attr, false);
5077
5078                         if (!RemoveData.Define (container))
5079                                 return false;
5080
5081                         RemoveBuilder = RemoveData.MethodBuilder;
5082                         RemoveBuilder.DefineParameter (1, ParameterAttributes.None, "value");
5083
5084                         if (!IsExplicitImpl){
5085                                 EventBuilder = new MyEventBuilder (this,
5086                                         container.TypeBuilder, Name, e_attr, MemberType);
5087                                         
5088                                 if (Add == null && Remove == null) {
5089                                         FieldBuilder = container.TypeBuilder.DefineField (
5090                                                 Name, MemberType,
5091                                                 FieldAttributes.Private | ((ModFlags & Modifiers.STATIC) != 0 ? FieldAttributes.Static : 0));
5092                                         TypeManager.RegisterPrivateFieldOfEvent (
5093                                                 (EventInfo) EventBuilder, FieldBuilder);
5094                                         TypeManager.RegisterFieldBase (FieldBuilder, this);
5095                                 }
5096                         
5097                                 EventBuilder.SetAddOnMethod (AddBuilder);
5098                                 EventBuilder.SetRemoveOnMethod (RemoveBuilder);
5099
5100                                 if (!TypeManager.RegisterEvent (EventBuilder, AddBuilder, RemoveBuilder)) {
5101                                         Report.Error (111, Location,
5102                                                       "Class `" + container.Name +
5103                                                       "' already contains a definition for the event `" +
5104                                                       Name + "'");
5105                                         return false;
5106                                 }
5107                         }
5108                         
5109                         return true;
5110                 }
5111
5112                 void EmitDefaultMethod (EmitContext ec, bool is_add)
5113                 {
5114                         ILGenerator ig = ec.ig;
5115                         MethodInfo method = null;
5116                         
5117                         if (is_add)
5118                                 method = TypeManager.delegate_combine_delegate_delegate;
5119                         else
5120                                 method = TypeManager.delegate_remove_delegate_delegate;
5121
5122                         if ((ModFlags & Modifiers.STATIC) != 0) {
5123                                 ig.Emit (OpCodes.Ldsfld, (FieldInfo) FieldBuilder);
5124                                 ig.Emit (OpCodes.Ldarg_0);
5125                                 ig.Emit (OpCodes.Call, method);
5126                                 ig.Emit (OpCodes.Castclass, MemberType);
5127                                 ig.Emit (OpCodes.Stsfld, (FieldInfo) FieldBuilder);
5128                         } else {
5129                                 ig.Emit (OpCodes.Ldarg_0);
5130                                 ig.Emit (OpCodes.Ldarg_0);
5131                                 ig.Emit (OpCodes.Ldfld, (FieldInfo) FieldBuilder);
5132                                 ig.Emit (OpCodes.Ldarg_1);
5133                                 ig.Emit (OpCodes.Call, method);
5134                                 ig.Emit (OpCodes.Castclass, MemberType);
5135                                 ig.Emit (OpCodes.Stfld, (FieldInfo) FieldBuilder);
5136                         }
5137                         ig.Emit (OpCodes.Ret);
5138                 }
5139
5140                 public void Emit (TypeContainer tc)
5141                 {
5142                         EmitContext ec;
5143
5144                         ec = new EmitContext (tc, Location, null, MemberType, ModFlags);
5145                         Attribute.ApplyAttributes (ec, EventBuilder, this, OptAttributes);
5146
5147                         if (Add != null) {
5148                                 AddData.Emit (tc, Add.Block, Add);
5149                                 Add.Block = null;
5150                         } else {
5151                                 ILGenerator ig = AddData.MethodBuilder.GetILGenerator ();
5152                                 ec = new EmitContext (tc, Location, ig, TypeManager.void_type, ModFlags);
5153                                 EmitDefaultMethod (ec, true);
5154                         }
5155
5156                         if (Remove != null) {
5157                                 RemoveData.Emit (tc, Remove.Block, Remove);
5158                                 Remove.Block = null;
5159                         } else {
5160                                 ILGenerator ig = RemoveData.MethodBuilder.GetILGenerator ();
5161                                 ec = new EmitContext (tc, Location, ig, TypeManager.void_type, ModFlags);
5162                                 EmitDefaultMethod (ec, false);
5163                         }
5164                 }
5165                 
5166         }
5167
5168         //
5169         // FIXME: This does not handle:
5170         //
5171         //   int INTERFACENAME [ args ]
5172         //   Does not 
5173         //
5174         // Only:
5175         // 
5176         // int this [ args ]
5177  
5178         public class Indexer : PropertyBase {
5179
5180                 const int AllowedModifiers =
5181                         Modifiers.NEW |
5182                         Modifiers.PUBLIC |
5183                         Modifiers.PROTECTED |
5184                         Modifiers.INTERNAL |
5185                         Modifiers.PRIVATE |
5186                         Modifiers.VIRTUAL |
5187                         Modifiers.SEALED |
5188                         Modifiers.OVERRIDE |
5189                         Modifiers.UNSAFE |
5190                         Modifiers.EXTERN |
5191                         Modifiers.ABSTRACT;
5192
5193                 const int AllowedInterfaceModifiers =
5194                         Modifiers.NEW;
5195
5196                 public string IndexerName;
5197                 public string InterfaceIndexerName;
5198
5199                 //
5200                 // Are we implementing an interface ?
5201                 //
5202                 public Indexer (DeclSpace ds, Expression type, int mod_flags, bool is_iface,
5203                                 MemberName name, Parameters parameters, Attributes attrs,
5204                                 Accessor get_block, Accessor set_block, Location loc)
5205                         : base (ds, type, mod_flags,
5206                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
5207                                 is_iface, name, parameters, attrs, get_block, set_block, loc)
5208                 {
5209                 }
5210
5211                 public override bool Define (TypeContainer container)
5212                 {
5213                         PropertyAttributes prop_attr =
5214                                 PropertyAttributes.RTSpecialName |
5215                                 PropertyAttributes.SpecialName;
5216                         
5217                         if (!DoDefine (container, container))
5218                                 return false;
5219
5220                         IndexerName = Attribute.ScanForIndexerName (ec, OptAttributes);
5221                         if (IndexerName == null)
5222                                 IndexerName = "Item";
5223                         else if (IsExplicitImpl)
5224                                 Report.Error (592, Location,
5225                                               "Attribute 'IndexerName' is not valid on this declaration " +
5226                                               "type. It is valid on `property' declarations only.");
5227
5228                         ShortName = IndexerName;
5229                         if (IsExplicitImpl) {
5230                                 InterfaceIndexerName = TypeManager.IndexerPropertyName (InterfaceType);
5231                                 Name = InterfaceType.FullName + "." + IndexerName;
5232                         } else {
5233                                 InterfaceIndexerName = IndexerName;
5234                                 Name = ShortName;
5235                         }
5236
5237                         if (!CheckNameCollision (container))
5238                                 return false;
5239
5240                         if (!CheckBase (container))
5241                                 return false;
5242
5243                         flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
5244                         if (Get != null){
5245                                 InternalParameters ip = new InternalParameters (container, Parameters);
5246
5247                                 GetData = new MethodData (container, this, "get", MemberType,
5248                                                           ParameterTypes, ip, CallingConventions.Standard,
5249                                                           Get.OptAttributes, ModFlags, flags, false);
5250
5251                                 if (!GetData.Define (container))
5252                                         return false;
5253
5254                                 GetBuilder = GetData.MethodBuilder;
5255                         }
5256                         
5257                         if (Set != null){
5258                                 int top = ParameterTypes.Length;
5259                                 Type [] set_pars = new Type [top + 1];
5260                                 ParameterTypes.CopyTo (set_pars, 0);
5261                                 set_pars [top] = MemberType;
5262
5263                                 Parameter [] fixed_parms = Parameters.FixedParameters;
5264
5265                                 if (fixed_parms == null){
5266                                         throw new Exception ("We currently do not support only array arguments in an indexer at: " + Location);
5267                                         // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
5268                                         // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
5269                                         //
5270                                         // Here is the problem: the `value' parameter has
5271                                         // to come *after* the array parameter in the declaration
5272                                         // like this:
5273                                         // X (object [] x, Type value)
5274                                         // .param [0]
5275                                         //
5276                                         // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
5277                                         // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
5278                                         
5279                                 }
5280                                 
5281                                 Parameter [] tmp = new Parameter [fixed_parms.Length + 1];
5282
5283
5284                                 fixed_parms.CopyTo (tmp, 0);
5285                                 tmp [fixed_parms.Length] = new Parameter (
5286                                         Type, "value", Parameter.Modifier.NONE, null);
5287
5288                                 Parameters set_formal_params = new Parameters (tmp, null, Location);
5289                                 
5290                                 InternalParameters ip = new InternalParameters (container, set_formal_params);
5291
5292                                 SetData = new MethodData (container, this, "set", TypeManager.void_type,
5293                                                           set_pars, ip, CallingConventions.Standard,
5294                                                           Set.OptAttributes, ModFlags, flags, false);
5295
5296                                 if (!SetData.Define (container))
5297                                         return false;
5298
5299                                 SetBuilder = SetData.MethodBuilder;
5300                         }
5301
5302                         //
5303                         // Now name the parameters
5304                         //
5305                         Parameter [] p = Parameters.FixedParameters;
5306                         if (p != null) {
5307                                 int i;
5308                                 
5309                                 for (i = 0; i < p.Length; ++i) {
5310                                         if (Get != null)
5311                                                 GetBuilder.DefineParameter (
5312                                                         i + 1, p [i].Attributes, p [i].Name);
5313
5314                                         if (Set != null)
5315                                                 SetBuilder.DefineParameter (
5316                                                         i + 1, p [i].Attributes, p [i].Name);
5317                                 }
5318
5319                                 if (Set != null)
5320                                         SetBuilder.DefineParameter (
5321                                                 i + 1, ParameterAttributes.None, "value");
5322                                         
5323                                 if (i != ParameterTypes.Length) {
5324                                         Parameter array_param = Parameters.ArrayParameter;
5325
5326                                         SetBuilder.DefineParameter (
5327                                                 i + 1, array_param.Attributes, array_param.Name);
5328                                 }
5329                         }
5330
5331                         //
5332                         // Define the PropertyBuilder if one of the following conditions are met:
5333                         // a) we're not implementing an interface indexer.
5334                         // b) the indexer has a different IndexerName and this is no
5335                         //    explicit interface implementation.
5336                         //
5337                         if (!IsExplicitImpl) {
5338                                 PropertyBuilder = container.TypeBuilder.DefineProperty (
5339                                         IndexerName, prop_attr, MemberType, ParameterTypes);
5340
5341                                 if (GetData != null)
5342                                         PropertyBuilder.SetGetMethod (GetBuilder);
5343
5344                                 if (SetData != null)
5345                                         PropertyBuilder.SetSetMethod (SetBuilder);
5346                                 
5347                                 TypeManager.RegisterIndexer (PropertyBuilder, GetBuilder, SetBuilder,
5348                                                              ParameterTypes);
5349                         }
5350
5351                         return true;
5352                 }
5353
5354                 bool CheckNameCollision (TypeContainer container) {
5355                         switch (VerifyName (container)){
5356                                 case DeclSpace.AdditionResult.NameExists:
5357                                         Report.Error (102, Location, "The container '{0}' already contains a definition for '{1}'", container.GetSignatureForError (), Name);
5358                                         return false;
5359
5360                                 case DeclSpace.AdditionResult.Success:
5361                                         return true;
5362                         }
5363                         throw new NotImplementedException ();
5364                 }
5365
5366                 DeclSpace.AdditionResult VerifyName (TypeContainer container) {
5367                         if (!AddIndexer (container, container.Name + "." + Name))
5368                                 return DeclSpace.AdditionResult.NameExists;
5369
5370                         if (Get != null) {
5371                                 if (!AddIndexer (container, container.Name + ".get_" + Name))
5372                                         return DeclSpace.AdditionResult.NameExists;
5373                         }
5374
5375                         if (Set != null) {
5376                                 if (!AddIndexer (container, container.Name + ".set_" + Name))
5377                                         return DeclSpace.AdditionResult.NameExists;
5378                         }
5379                         return DeclSpace.AdditionResult.Success;
5380                 }
5381
5382                 bool AddIndexer (TypeContainer container, string fullname)
5383                 {
5384                         object value = container.GetDefinition (fullname);
5385
5386                         if (value != null) {
5387                                 return value.GetType () != GetType () ? false : true;
5388                         }
5389
5390                         container.DefineName (fullname, this);
5391                         return true;
5392                 }
5393
5394                 public override string GetSignatureForError () {
5395                         return TypeManager.CSharpSignature (PropertyBuilder, true);
5396                 }
5397         }
5398
5399         public class Operator : MemberBase, IIteratorContainer {
5400
5401                 const int AllowedModifiers =
5402                         Modifiers.PUBLIC |
5403                         Modifiers.UNSAFE |
5404                         Modifiers.EXTERN |
5405                         Modifiers.STATIC;
5406
5407                 const int RequiredModifiers =
5408                         Modifiers.PUBLIC |
5409                         Modifiers.STATIC;
5410
5411                 public enum OpType : byte {
5412
5413                         // Unary operators
5414                         LogicalNot,
5415                         OnesComplement,
5416                         Increment,
5417                         Decrement,
5418                         True,
5419                         False,
5420
5421                         // Unary and Binary operators
5422                         Addition,
5423                         Subtraction,
5424
5425                         UnaryPlus,
5426                         UnaryNegation,
5427                         
5428                         // Binary operators
5429                         Multiply,
5430                         Division,
5431                         Modulus,
5432                         BitwiseAnd,
5433                         BitwiseOr,
5434                         ExclusiveOr,
5435                         LeftShift,
5436                         RightShift,
5437                         Equality,
5438                         Inequality,
5439                         GreaterThan,
5440                         LessThan,
5441                         GreaterThanOrEqual,
5442                         LessThanOrEqual,
5443
5444                         // Implicit and Explicit
5445                         Implicit,
5446                         Explicit
5447                 };
5448
5449                 public readonly OpType OperatorType;
5450                 public readonly Expression ReturnType;
5451                 public readonly Expression FirstArgType, SecondArgType;
5452                 public readonly string FirstArgName, SecondArgName;
5453                 public Block           Block;
5454                 public MethodBuilder   OperatorMethodBuilder;
5455                 
5456                 public string MethodName;
5457                 public Method OperatorMethod;
5458
5459                 public Operator (OpType type, Expression ret_type, int mod_flags,
5460                                  Expression arg1type, string arg1name,
5461                                  Expression arg2type, string arg2name,
5462                                  Block block, Attributes attrs, Location loc)
5463                         : base (ret_type, mod_flags, AllowedModifiers, Modifiers.PUBLIC,
5464                                 MemberName.Null, attrs, loc)
5465                 {
5466                         OperatorType = type;
5467                         Name = "op_" + OperatorType;
5468                         ReturnType = ret_type;
5469                         FirstArgType = arg1type;
5470                         FirstArgName = arg1name;
5471                         SecondArgType = arg2type;
5472                         SecondArgName = arg2name;
5473                         Block = block;
5474                 }
5475
5476                 string Prototype (TypeContainer container)
5477                 {
5478                         return container.Name + ".operator " + OperatorType + " (" + FirstArgType + "," +
5479                                 SecondArgType + ")";
5480                 }
5481                 
5482                 protected override bool CheckGenericOverride (MethodInfo method,  string name)
5483                 {
5484                         return true;
5485                 }
5486
5487                 public override bool Define (TypeContainer container)
5488                 {
5489                         int length = 1;
5490                         MethodName = "op_" + OperatorType;
5491                         
5492                         if (SecondArgType != null)
5493                                 length = 2;
5494                         
5495                         Parameter [] param_list = new Parameter [length];
5496
5497                         if ((ModFlags & RequiredModifiers) != RequiredModifiers){
5498                                 Report.Error (
5499                                         558, Location, 
5500                                         "User defined operators `" +
5501                                         Prototype (container) +
5502                                         "' must be declared static and public");
5503                                 return false;
5504                         }
5505
5506                         param_list[0] = new Parameter (FirstArgType, FirstArgName,
5507                                                        Parameter.Modifier.NONE, null);
5508                         if (SecondArgType != null)
5509                                 param_list[1] = new Parameter (SecondArgType, SecondArgName,
5510                                                                Parameter.Modifier.NONE, null);
5511                         
5512                         OperatorMethod = new Method (
5513                                 container, ReturnType, ModFlags, false,
5514                                 new MemberName (MethodName),
5515                                 new Parameters (param_list, null, Location),
5516                                 OptAttributes, Location);
5517
5518                         OperatorMethod.Block = Block;
5519                         OperatorMethod.IsOperator = true;                       
5520                         OperatorMethod.Define (container);
5521
5522                         if (OperatorMethod.MethodBuilder == null)
5523                                 return false;
5524                         
5525                         OperatorMethodBuilder = OperatorMethod.MethodBuilder;
5526
5527                         Type [] param_types = OperatorMethod.ParameterTypes;
5528                         Type declaring_type = OperatorMethod.MethodData.DeclaringType;
5529                         Type return_type = OperatorMethod.GetReturnType ();
5530                         Type first_arg_type = param_types [0];
5531
5532                         // Rules for conversion operators
5533                         
5534                         if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
5535                                 if (first_arg_type == return_type && first_arg_type == declaring_type){
5536                                         Report.Error (
5537                                                 555, Location,
5538                                                 "User-defined conversion cannot take an object of the " +
5539                                                 "enclosing type and convert to an object of the enclosing" +
5540                                                 " type");
5541                                         return false;
5542                                 }
5543                                 
5544                                 if (first_arg_type != declaring_type && return_type != declaring_type){
5545                                         Report.Error (
5546                                                 556, Location, 
5547                                                 "User-defined conversion must convert to or from the " +
5548                                                 "enclosing type");
5549                                         return false;
5550                                 }
5551                                 
5552                                 if (first_arg_type == TypeManager.object_type ||
5553                                     return_type == TypeManager.object_type){
5554                                         Report.Error (
5555                                                 -8, Location,
5556                                                 "User-defined conversion cannot convert to or from " +
5557                                                 "object type");
5558                                         return false;
5559                                 }
5560
5561                                 if (first_arg_type.IsInterface || return_type.IsInterface){
5562                                         Report.Error (
5563                                                 552, Location,
5564                                                 "User-defined conversion cannot convert to or from an " +
5565                                                 "interface type");
5566                                         return false;
5567                                 }
5568                                 
5569                                 if (first_arg_type.IsSubclassOf (return_type) ||
5570                                     return_type.IsSubclassOf (first_arg_type)){
5571                                         Report.Error (
5572                                                 -10, Location,
5573                                                 "User-defined conversion cannot convert between types " +
5574                                                 "that derive from each other");
5575                                         return false;
5576                                 }
5577                         } else if (SecondArgType == null) {
5578                                 // Checks for Unary operators
5579                                 
5580                                 if (first_arg_type != declaring_type){
5581                                         Report.Error (
5582                                                 562, Location,
5583                                                 "The parameter of a unary operator must be the " +
5584                                                 "containing type");
5585                                         return false;
5586                                 }
5587                                 
5588                                 if (OperatorType == OpType.Increment || OperatorType == OpType.Decrement) {
5589                                         if (return_type != declaring_type){
5590                                                 Report.Error (
5591                                                         559, Location,
5592                                                         "The parameter and return type for ++ and -- " +
5593                                                         "must be the containing type");
5594                                                 return false;
5595                                         }
5596                                         
5597                                 }
5598                                 
5599                                 if (OperatorType == OpType.True || OperatorType == OpType.False) {
5600                                         if (return_type != TypeManager.bool_type){
5601                                                 Report.Error (
5602                                                         215, Location,
5603                                                         "The return type of operator True or False " +
5604                                                         "must be bool");
5605                                                 return false;
5606                                         }
5607                                 }
5608                                 
5609                         } else {
5610                                 // Checks for Binary operators
5611                                 
5612                                 if (first_arg_type != declaring_type &&
5613                                     param_types [1] != declaring_type){
5614                                         Report.Error (
5615                                                 563, Location,
5616                                                 "One of the parameters of a binary operator must " +
5617                                                 "be the containing type");
5618                                         return false;
5619                                 }
5620                         }
5621
5622                         return true;
5623                 }
5624                 
5625                 public void Emit (TypeContainer container)
5626                 {
5627                         //
5628                         // abstract or extern methods have no bodies
5629                         //
5630                         if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
5631                                 return;
5632                         
5633                         OperatorMethod.Emit (container);
5634                         Block = null;
5635                 }
5636
5637                 public static string GetName (OpType ot)
5638                 {
5639                         switch (ot){
5640                         case OpType.LogicalNot:
5641                                 return "!";
5642                         case OpType.OnesComplement:
5643                                 return "~";
5644                         case OpType.Increment:
5645                                 return "++";
5646                         case OpType.Decrement:
5647                                 return "--";
5648                         case OpType.True:
5649                                 return "true";
5650                         case OpType.False:
5651                                 return "false";
5652                         case OpType.Addition:
5653                                 return "+";
5654                         case OpType.Subtraction:
5655                                 return "-";
5656                         case OpType.UnaryPlus:
5657                                 return "+";
5658                         case OpType.UnaryNegation:
5659                                 return "-";
5660                         case OpType.Multiply:
5661                                 return "*";
5662                         case OpType.Division:
5663                                 return "/";
5664                         case OpType.Modulus:
5665                                 return "%";
5666                         case OpType.BitwiseAnd:
5667                                 return "&";
5668                         case OpType.BitwiseOr:
5669                                 return "|";
5670                         case OpType.ExclusiveOr:
5671                                 return "^";
5672                         case OpType.LeftShift:
5673                                 return "<<";
5674                         case OpType.RightShift:
5675                                 return ">>";
5676                         case OpType.Equality:
5677                                 return "==";
5678                         case OpType.Inequality:
5679                                 return "!=";
5680                         case OpType.GreaterThan:
5681                                 return ">";
5682                         case OpType.LessThan:
5683                                 return "<";
5684                         case OpType.GreaterThanOrEqual:
5685                                 return ">=";
5686                         case OpType.LessThanOrEqual:
5687                                 return "<=";
5688                         case OpType.Implicit:
5689                                 return "implicit";
5690                         case OpType.Explicit:
5691                                 return "explicit";
5692                         default: return "";
5693                         }
5694                 }
5695                 
5696                 public override string ToString ()
5697                 {
5698                         Type return_type = OperatorMethod.GetReturnType();
5699                         Type [] param_types = OperatorMethod.ParameterTypes;
5700                         
5701                         if (SecondArgType == null)
5702                                 return String.Format (
5703                                         "{0} operator {1}({2})",
5704                                         TypeManager.CSharpName (return_type),
5705                                         GetName (OperatorType),
5706                                         param_types [0]);
5707                         else
5708                                 return String.Format (
5709                                         "{0} operator {1}({2}, {3})",
5710                                         TypeManager.CSharpName (return_type),
5711                                         GetName (OperatorType),
5712                                         param_types [0], param_types [1]);
5713                 }
5714
5715                 public void SetYields ()
5716                 {
5717                         ModFlags |= Modifiers.METHOD_YIELDS;
5718                 }
5719         }
5720
5721         //
5722         // This is used to compare method signatures
5723         //
5724         struct MethodSignature {
5725                 public string Name;
5726                 public Type RetType;
5727                 public Type [] Parameters;
5728                 
5729                 /// <summary>
5730                 ///    This delegate is used to extract methods which have the
5731                 ///    same signature as the argument
5732                 /// </summary>
5733                 public static MemberFilter method_signature_filter = new MemberFilter (MemberSignatureCompare);
5734                 
5735                 public MethodSignature (string name, Type ret_type, Type [] parameters)
5736                 {
5737                         Name = name;
5738                         RetType = ret_type;
5739
5740                         if (parameters == null)
5741                                 Parameters = TypeManager.NoTypes;
5742                         else
5743                                 Parameters = parameters;
5744                 }
5745
5746                 public override string ToString ()
5747                 {
5748                         string pars = "";
5749                         if (Parameters.Length != 0){
5750                                 System.Text.StringBuilder sb = new System.Text.StringBuilder ();
5751                                 for (int i = 0; i < Parameters.Length; i++){
5752                                         sb.Append (Parameters [i]);
5753                                         if (i+1 < Parameters.Length)
5754                                                 sb.Append (", ");
5755                                 }
5756                                 pars = sb.ToString ();
5757                         }
5758
5759                         return String.Format ("{0} {1} ({2})", RetType, Name, pars);
5760                 }
5761                 
5762                 public override int GetHashCode ()
5763                 {
5764                         return Name.GetHashCode ();
5765                 }
5766
5767                 public override bool Equals (Object o)
5768                 {
5769                         MethodSignature other = (MethodSignature) o;
5770
5771                         if (other.Name != Name)
5772                                 return false;
5773
5774                         if (other.RetType != RetType)
5775                                 return false;
5776                         
5777                         if (Parameters == null){
5778                                 if (other.Parameters == null)
5779                                         return true;
5780                                 return false;
5781                         }
5782
5783                         if (other.Parameters == null)
5784                                 return false;
5785                         
5786                         int c = Parameters.Length;
5787                         if (other.Parameters.Length != c)
5788                                 return false;
5789
5790                         for (int i = 0; i < c; i++)
5791                                 if (other.Parameters [i] != Parameters [i])
5792                                         return false;
5793
5794                         return true;
5795                 }
5796
5797                 static bool MemberSignatureCompare (MemberInfo m, object filter_criteria)
5798                 {
5799                         MethodSignature sig = (MethodSignature) filter_criteria;
5800
5801                         if (m.Name != sig.Name)
5802                                 return false;
5803
5804                         Type ReturnType;
5805                         MethodInfo mi = m as MethodInfo;
5806                         PropertyInfo pi = m as PropertyInfo;
5807
5808                         if (mi != null)
5809                                 ReturnType = mi.ReturnType;
5810                         else if (pi != null)
5811                                 ReturnType = pi.PropertyType;
5812                         else
5813                                 return false;
5814                         
5815                         //
5816                         // we use sig.RetType == null to mean `do not check the
5817                         // method return value.  
5818                         //
5819                         if (sig.RetType != null)
5820                                 if (ReturnType != sig.RetType)
5821                                         return false;
5822
5823                         Type [] args;
5824                         if (mi != null)
5825                                 args = TypeManager.GetArgumentTypes (mi);
5826                         else
5827                                 args = TypeManager.GetArgumentTypes (pi);
5828                         Type [] sigp = sig.Parameters;
5829
5830                         if (args.Length != sigp.Length)
5831                                 return false;
5832
5833                         for (int i = args.Length; i > 0; ){
5834                                 i--;
5835                                 if (args [i] != sigp [i])
5836                                         return false;
5837                         }
5838                         return true;
5839                 }
5840         }
5841 }