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