2004-01-20 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 ToplevelBlock (null, Location);
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 ToplevelBlock (Block.Flags.Implicit, parameters, loc);
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 is Destructor)
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         public class Destructor : Method {
3498
3499                 public Destructor (DeclSpace ds, Expression return_type, int mod, string name,
3500                                    Parameters parameters, Attributes attrs, Location l)
3501                         : base (ds, return_type, mod, name, parameters, attrs, l)
3502                 { }
3503
3504         }
3505         
3506         abstract public class MemberBase : MemberCore {
3507                 public Expression Type;
3508                 public readonly Attributes OptAttributes;
3509
3510                 protected MethodAttributes flags;
3511                         
3512                 protected readonly int explicit_mod_flags;
3513
3514                 //
3515                 // The "short" name of this property / indexer / event.  This is the
3516                 // name without the explicit interface.
3517                 //
3518                 public string ShortName;
3519
3520                 //
3521                 // The type of this property / indexer / event
3522                 //
3523                 public Type MemberType;
3524
3525                 //
3526                 // If true, this is an explicit interface implementation
3527                 //
3528                 public bool IsExplicitImpl = false;
3529
3530                 //
3531                 // The name of the interface we are explicitly implementing
3532                 //
3533                 public string ExplicitInterfaceName = null;
3534
3535                 //
3536                 // If true, the interface type we are explicitly implementing
3537                 //
3538                 public Type InterfaceType = null;
3539
3540                 //
3541                 // The method we're overriding if this is an override method.
3542                 //
3543                 protected MethodInfo parent_method = null;
3544                 public MethodInfo ParentMethod {
3545                         get {
3546                                 return parent_method;
3547                         }
3548                 }
3549
3550                 //
3551                 // The constructor is only exposed to our children
3552                 //
3553                 protected MemberBase (Expression type, int mod, int allowed_mod, int def_mod, string name,
3554                                       Attributes attrs, Location loc)
3555                         : base (name, loc)
3556                 {
3557                         explicit_mod_flags = mod;
3558                         Type = type;
3559                         ModFlags = Modifiers.Check (allowed_mod, mod, def_mod, loc);
3560                         OptAttributes = attrs;
3561                 }
3562
3563                 protected virtual bool CheckBase (TypeContainer container)
3564                 {
3565                         if ((container is Struct) || (RootContext.WarningLevel > 3)){
3566                                 if ((ModFlags & Modifiers.PROTECTED) != 0 && (container.ModFlags & Modifiers.SEALED) != 0){
3567                                         if (container is Struct){
3568                                                 Report.Error (666, Location, "Protected member in struct declaration");
3569                                                 return false;
3570                                         } else
3571                                                 Report.Warning (628, Location, "Member " + container.MakeName (Name) + " protected in sealed class");
3572                                 }
3573                         }
3574                         return true;
3575                 }
3576
3577                 protected void WarningNotHiding (TypeContainer parent)
3578                 {
3579                         Report.Warning (
3580                                 109, Location,
3581                                 "The member " + parent.MakeName (Name) + " does not hide an " +
3582                                 "inherited member.  The keyword new is not required");
3583                                                            
3584                 }
3585
3586                 void Error_CannotChangeAccessModifiers (TypeContainer parent, MethodInfo parent_method,
3587                                                         string name)
3588                 {
3589                         //
3590                         // FIXME: report the old/new permissions?
3591                         //
3592                         Report.Error (
3593                                 507, Location, parent.MakeName (Name) +
3594                                 ": can't change the access modifiers when overriding inherited " +
3595                                 "member `" + name + "'");
3596                 }
3597                 
3598                 //
3599                 // Performs various checks on the MethodInfo `mb' regarding the modifier flags
3600                 // that have been defined.
3601                 //
3602                 // `name' is the user visible name for reporting errors (this is used to
3603                 // provide the right name regarding method names and properties)
3604                 //
3605                 protected bool CheckMethodAgainstBase (TypeContainer parent, MethodAttributes my_attrs,
3606                                                        MethodInfo mb, string name)
3607                 {
3608                         bool ok = true;
3609                         
3610                         if ((ModFlags & Modifiers.OVERRIDE) != 0){
3611                                 if (!(mb.IsAbstract || mb.IsVirtual)){
3612                                         Report.Error (
3613                                                 506, Location, parent.MakeName (Name) +
3614                                                 ": cannot override inherited member `" +
3615                                                 name + "' because it is not " +
3616                                                 "virtual, abstract or override");
3617                                         ok = false;
3618                                 }
3619                                 
3620                                 // Now we check that the overriden method is not final
3621                                 
3622                                 if (mb.IsFinal) {
3623                                         // This happens when implementing interface methods.
3624                                         if (mb.IsHideBySig && mb.IsVirtual) {
3625                                                 Report.Error (
3626                                                         506, Location, parent.MakeName (Name) +
3627                                                         ": cannot override inherited member `" +
3628                                                         name + "' because it is not " +
3629                                                         "virtual, abstract or override");
3630                                         } else
3631                                                 Report.Error (239, Location, parent.MakeName (Name) + " : cannot " +
3632                                                               "override inherited member `" + name +
3633                                                               "' because it is sealed.");
3634                                         ok = false;
3635                                 }
3636                                 //
3637                                 // Check that the permissions are not being changed
3638                                 //
3639                                 MethodAttributes thisp = my_attrs & MethodAttributes.MemberAccessMask;
3640                                 MethodAttributes parentp = mb.Attributes & MethodAttributes.MemberAccessMask;
3641
3642                                 //
3643                                 // special case for "protected internal"
3644                                 //
3645
3646                                 if ((parentp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
3647                                         //
3648                                         // when overriding protected internal, the method can be declared
3649                                         // protected internal only within the same assembly
3650                                         //
3651
3652                                         if ((thisp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
3653                                                 if (parent.TypeBuilder.Assembly != mb.DeclaringType.Assembly){
3654                                                         //
3655                                                         // assemblies differ - report an error
3656                                                         //
3657                                                         
3658                                                         Error_CannotChangeAccessModifiers (parent, mb, name);
3659                                                     ok = false;
3660                                                 } else if (thisp != parentp) {
3661                                                         //
3662                                                         // same assembly, but other attributes differ - report an error
3663                                                         //
3664                                                         
3665                                                         Error_CannotChangeAccessModifiers (parent, mb, name);
3666                                                         ok = false;
3667                                                 };
3668                                         } else if ((thisp & MethodAttributes.Family) != MethodAttributes.Family) {
3669                                                 //
3670                                                 // if it's not "protected internal", it must be "protected"
3671                                                 //
3672
3673                                                 Error_CannotChangeAccessModifiers (parent, mb, name);
3674                                                 ok = false;
3675                                         } else if (parent.TypeBuilder.Assembly == mb.DeclaringType.Assembly) {
3676                                                 //
3677                                                 // protected within the same assembly - an error
3678                                                 //
3679                                                 Error_CannotChangeAccessModifiers (parent, mb, name);
3680                                                 ok = false;
3681                                         } else if ((thisp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem)) != 
3682                                                    (parentp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem))) {
3683                                                 //
3684                                                 // protected ok, but other attributes differ - report an error
3685                                                 //
3686                                                 Error_CannotChangeAccessModifiers (parent, mb, name);
3687                                                 ok = false;
3688                                         }
3689                                 } else {
3690                                         if (thisp != parentp){
3691                                                 Error_CannotChangeAccessModifiers (parent, mb, name);
3692                                                 ok = false;
3693                                         }
3694                                 }
3695                         }
3696
3697                         if (mb.IsVirtual || mb.IsAbstract){
3698                                 if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE)) == 0){
3699                                         if (Name != "Finalize"){
3700                                                 Report.Warning (
3701                                                         114, 2, Location, parent.MakeName (Name) + 
3702                                                         " hides inherited member `" + name +
3703                                                         "'.  To make the current member override that " +
3704                                                         "implementation, add the override keyword, " +
3705                                                         "otherwise use the new keyword");
3706                                                 ModFlags |= Modifiers.NEW;
3707                                         }
3708                                 }
3709                         } else {
3710                                 if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE)) == 0){
3711                                         if (Name != "Finalize"){
3712                                                 Report.Warning (
3713                                                         108, 1, Location, "The keyword new is required on " +
3714                                                         parent.MakeName (Name) + " because it hides " +
3715                                                         "inherited member `" + name + "'");
3716                                                 ModFlags |= Modifiers.NEW;
3717                                         }
3718                                 }
3719                         }
3720
3721                         return ok;
3722                 }
3723
3724                 protected virtual bool CheckParameters (DeclSpace ds, Type [] parameters)
3725                 {
3726                         bool error = false;
3727
3728                         foreach (Type partype in parameters){
3729                                 if (partype.IsPointer){
3730                                         if (!UnsafeOK (ds))
3731                                                 error = true;
3732                                         if (!TypeManager.VerifyUnManaged (TypeManager.GetElementType (partype), Location))
3733                                                 error = true;
3734                                 }
3735
3736                                 if (ds.AsAccessible (partype, ModFlags))
3737                                         continue;
3738
3739                                 if (this is Indexer)
3740                                         Report.Error (55, Location,
3741                                                       "Inconsistent accessibility: parameter type `" +
3742                                                       TypeManager.CSharpName (partype) + "' is less " +
3743                                                       "accessible than indexer `" + Name + "'");
3744                                 else if ((this is Method) && ((Method) this).IsOperator)
3745                                         Report.Error (57, Location,
3746                                                       "Inconsistent accessibility: parameter type `" +
3747                                                       TypeManager.CSharpName (partype) + "' is less " +
3748                                                       "accessible than operator `" + Name + "'");
3749                                 else
3750                                         Report.Error (51, Location,
3751                                                       "Inconsistent accessibility: parameter type `" +
3752                                                       TypeManager.CSharpName (partype) + "' is less " +
3753                                                       "accessible than method `" + Name + "'");
3754                                 error = true;
3755                         }
3756
3757                         return !error;
3758                 }
3759
3760                 protected virtual bool DoDefine (TypeContainer container)
3761                 {
3762                         if (Name == null)
3763                                 Name = "this";
3764
3765                         if (!container.MethodModifiersValid (ModFlags, Name, Location))
3766                                 return false;
3767
3768                         flags = Modifiers.MethodAttr (ModFlags);
3769
3770                         // Lookup Type, verify validity
3771                         MemberType = container.ResolveType (Type, false, Location);
3772                         if (MemberType == null)
3773                                 return false;
3774
3775                         if ((container.ModFlags & Modifiers.SEALED) != 0){
3776                                 if ((ModFlags & (Modifiers.VIRTUAL|Modifiers.ABSTRACT)) != 0){
3777                                         Report.Error (549, Location, "Virtual method can not be contained in sealed class");
3778                                         return false;
3779                                 }
3780                         }
3781                         
3782                         // verify accessibility
3783                         if (!container.AsAccessible (MemberType, ModFlags)) {
3784                                 if (this is Property)
3785                                         Report.Error (53, Location,
3786                                                       "Inconsistent accessibility: property type `" +
3787                                                       TypeManager.CSharpName (MemberType) + "' is less " +
3788                                                       "accessible than property `" + Name + "'");
3789                                 else if (this is Indexer)
3790                                         Report.Error (54, Location,
3791                                                       "Inconsistent accessibility: indexer return type `" +
3792                                                       TypeManager.CSharpName (MemberType) + "' is less " +
3793                                                       "accessible than indexer `" + Name + "'");
3794                                 else if (this is Method) {
3795                                         if (((Method) this).IsOperator)
3796                                                 Report.Error (56, Location,
3797                                                               "Inconsistent accessibility: return type `" +
3798                                                               TypeManager.CSharpName (MemberType) + "' is less " +
3799                                                               "accessible than operator `" + Name + "'");
3800                                         else
3801                                                 Report.Error (50, Location,
3802                                                               "Inconsistent accessibility: return type `" +
3803                                                               TypeManager.CSharpName (MemberType) + "' is less " +
3804                                                               "accessible than method `" + Name + "'");
3805                                 } else
3806                                         Report.Error (52, Location,
3807                                                       "Inconsistent accessibility: field type `" +
3808                                                       TypeManager.CSharpName (MemberType) + "' is less " +
3809                                                       "accessible than field `" + Name + "'");
3810                                 return false;
3811                         }
3812
3813                         if (MemberType.IsPointer && !UnsafeOK (container))
3814                                 return false;
3815                         
3816                         //
3817                         // Check for explicit interface implementation
3818                         //
3819                         if ((ExplicitInterfaceName == null) && (Name.IndexOf ('.') != -1)){
3820                                 int pos = Name.LastIndexOf ('.');
3821
3822                                 ExplicitInterfaceName = Name.Substring (0, pos);
3823                                 ShortName = Name.Substring (pos + 1);
3824                         } else
3825                                 ShortName = Name;
3826
3827                         if (ExplicitInterfaceName != null) {
3828                                 InterfaceType  = RootContext.LookupType (
3829                                         container, ExplicitInterfaceName, false, Location);
3830                                 if (InterfaceType == null)
3831                                         return false;
3832
3833                                 // Compute the full name that we need to export.
3834                                 Name = InterfaceType.FullName + "." + ShortName;
3835                                 
3836                                 if (!container.VerifyImplements (InterfaceType, ShortName, Name, Location))
3837                                         return false;
3838                                 
3839                                 Modifiers.Check (Modifiers.AllowedExplicitImplFlags, explicit_mod_flags, 0, Location);
3840                                 
3841                                 IsExplicitImpl = true;
3842                         } else
3843                                 IsExplicitImpl = false;
3844
3845                         return true;
3846                 }
3847         }
3848
3849         //
3850         // Fields and Events both generate FieldBuilders, we use this to share 
3851         // their common bits.  This is also used to flag usage of the field
3852         //
3853         abstract public class FieldBase : MemberBase {
3854                 public FieldBuilder  FieldBuilder;
3855                 public Status status;
3856
3857                 [Flags]
3858                 public enum Status : byte { ASSIGNED = 1, USED = 2 }
3859
3860                 //
3861                 // The constructor is only exposed to our children
3862                 //
3863                 protected FieldBase (Expression type, int mod, int allowed_mod, string name,
3864                                      object init, Attributes attrs, Location loc)
3865                         : base (type, mod, allowed_mod, Modifiers.PRIVATE, name, attrs, loc)
3866                 {
3867                         this.init = init;
3868                 }
3869
3870                 //
3871                 // Whether this field has an initializer.
3872                 //
3873                 public bool HasInitializer {
3874                         get {
3875                                 return init != null;
3876                         }
3877                 }
3878
3879                 protected readonly Object init;
3880                 // Private.
3881                 Expression init_expr;
3882                 bool init_expr_initialized = false;
3883
3884                 //
3885                 // Resolves and returns the field initializer.
3886                 //
3887                 public Expression GetInitializerExpression (EmitContext ec)
3888                 {
3889                         if (init_expr_initialized)
3890                                 return init_expr;
3891
3892                         Expression e;
3893                         if (init is Expression)
3894                                 e = (Expression) init;
3895                         else
3896                                 e = new ArrayCreation (Type, "", (ArrayList)init, Location);
3897
3898                         ec.IsFieldInitializer = true;
3899                         e = e.DoResolve (ec);
3900                         ec.IsFieldInitializer = false;
3901
3902                         init_expr = e;
3903                         init_expr_initialized = true;
3904
3905                         return init_expr;
3906                 }
3907
3908                 public void SetAssigned ()
3909                 {
3910                         status |= Status.ASSIGNED;
3911                 }
3912         }
3913
3914         //
3915         // The Field class is used to represents class/struct fields during parsing.
3916         //
3917         public class Field : FieldBase {
3918                 // <summary>
3919                 //   Modifiers allowed in a class declaration
3920                 // </summary>
3921                 const int AllowedModifiers =
3922                         Modifiers.NEW |
3923                         Modifiers.PUBLIC |
3924                         Modifiers.PROTECTED |
3925                         Modifiers.INTERNAL |
3926                         Modifiers.PRIVATE |
3927                         Modifiers.STATIC |
3928                         Modifiers.VOLATILE |
3929                         Modifiers.UNSAFE |
3930                         Modifiers.READONLY;
3931
3932                 public Field (Expression type, int mod, string name, Object expr_or_array_init,
3933                               Attributes attrs, Location loc)
3934                         : base (type, mod, AllowedModifiers, name, expr_or_array_init, attrs, loc)
3935                 {
3936                 }
3937
3938                 public override bool Define (TypeContainer container)
3939                 {
3940                         Type t = container.ResolveType (Type, false, Location);
3941                         
3942                         if (t == null)
3943                                 return false;
3944
3945                         CheckBase (container);
3946                         
3947                         if (!container.AsAccessible (t, ModFlags)) {
3948                                 Report.Error (52, Location,
3949                                               "Inconsistent accessibility: field type `" +
3950                                               TypeManager.CSharpName (t) + "' is less " +
3951                                               "accessible than field `" + Name + "'");
3952                                 return false;
3953                         }
3954
3955                         if (t.IsPointer && !UnsafeOK (container))
3956                                 return false;
3957                         
3958                         if (RootContext.WarningLevel > 1){
3959                                 Type ptype = container.TypeBuilder.BaseType;
3960
3961                                 // ptype is only null for System.Object while compiling corlib.
3962                                 if (ptype != null){
3963                                         TypeContainer.FindMembers (
3964                                                 ptype, MemberTypes.Method,
3965                                                 BindingFlags.Public |
3966                                                 BindingFlags.Static | BindingFlags.Instance,
3967                                                 System.Type.FilterName, Name);
3968                                 }
3969                         }
3970
3971                         if ((ModFlags & Modifiers.VOLATILE) != 0){
3972                                 if (!t.IsClass){
3973                                         Type vt = t;
3974                                         
3975                                         if (TypeManager.IsEnumType (vt))
3976                                                 vt = TypeManager.EnumToUnderlying (t);
3977
3978                                         if (!((vt == TypeManager.bool_type) ||
3979                                               (vt == TypeManager.sbyte_type) ||
3980                                               (vt == TypeManager.byte_type) ||
3981                                               (vt == TypeManager.short_type) ||    
3982                                               (vt == TypeManager.ushort_type) ||
3983                                               (vt == TypeManager.int32_type) ||    
3984                                               (vt == TypeManager.uint32_type) ||    
3985                                               (vt == TypeManager.char_type) ||    
3986                                               (vt == TypeManager.float_type))){
3987                                                 Report.Error (
3988                                                         677, Location, container.MakeName (Name) +
3989                                                         " A volatile field can not be of type `" +
3990                                                         TypeManager.CSharpName (vt) + "'");
3991                                                 return false;
3992                                         }
3993                                 }
3994
3995                                 if ((ModFlags & Modifiers.READONLY) != 0){
3996                                         Report.Error (
3997                                                       678, Location,
3998                                                       "A field can not be both volatile and readonly");
3999                                         return false;
4000                                 }
4001                         }
4002
4003                         FieldAttributes fa = Modifiers.FieldAttr (ModFlags);
4004
4005                         if (container is Struct && 
4006                             ((fa & FieldAttributes.Static) == 0) &&
4007                             t == container.TypeBuilder &&
4008                             !TypeManager.IsBuiltinType (t)){
4009                                 Report.Error (523, Location, "Struct member `" + container.Name + "." + Name + 
4010                                               "' causes a cycle in the structure layout");
4011                                 return false;
4012                         }
4013
4014                         FieldBuilder = container.TypeBuilder.DefineField (
4015                                 Name, t, Modifiers.FieldAttr (ModFlags));
4016
4017                         TypeManager.RegisterFieldBase (FieldBuilder, this);
4018                         return true;
4019                 }
4020
4021                 public void Emit (TypeContainer tc)
4022                 {
4023                         EmitContext ec = new EmitContext (tc, Location, null,
4024                                                           FieldBuilder.FieldType, ModFlags);
4025
4026                         Attribute.ApplyAttributes (ec, FieldBuilder, this, OptAttributes);
4027                 }
4028         }
4029
4030         //
4031         // `set' and `get' accessors are represented with an Accessor.
4032         // 
4033         public class Accessor {
4034                 //
4035                 // Null if the accessor is empty, or a Block if not
4036                 //
4037                 public Block Block;
4038                 public Attributes OptAttributes;
4039                 
4040                 public Accessor (Block b, Attributes attrs)
4041                 {
4042                         Block = b;
4043                         OptAttributes = attrs;
4044                 }
4045         }
4046
4047         //
4048         // Properties and Indexers both generate PropertyBuilders, we use this to share 
4049         // their common bits.
4050         //
4051         abstract public class PropertyBase : MethodCore {
4052                 public Accessor Get, Set;
4053                 public PropertyBuilder PropertyBuilder;
4054                 public MethodBuilder GetBuilder, SetBuilder;
4055                 public MethodData GetData, SetData;
4056
4057                 protected EmitContext ec;
4058
4059                 public PropertyBase (DeclSpace ds, Expression type, string name, int mod_flags,
4060                                      int allowed_mod, Parameters parameters,
4061                                      Accessor get_block, Accessor set_block,
4062                                      Attributes attrs, Location loc)
4063                         : base (ds, type, mod_flags, allowed_mod, name, attrs, parameters, loc)
4064                 {
4065                         Get = get_block;
4066                         Set = set_block;
4067                 }
4068
4069                 protected override bool DoDefine (TypeContainer container)
4070                 {
4071                         if (!base.DoDefine (container))
4072                                 return false;
4073
4074                         ec = new EmitContext (container, Location, null, MemberType, ModFlags);
4075
4076                         return true;
4077                 }
4078
4079                 //
4080                 // Checks our base implementation if any
4081                 //
4082                 protected override bool CheckBase (TypeContainer container)
4083                 {
4084                         base.CheckBase (container);
4085                         
4086                         // Check whether arguments were correct.
4087                         if (!DoDefineParameters ())
4088                                 return false;
4089
4090                         if (IsExplicitImpl)
4091                                 return true;
4092
4093                         string report_name;
4094                         MethodSignature ms, base_ms;
4095                         if (this is Indexer) {
4096                                 string name, base_name;
4097
4098                                 report_name = "this";
4099                                 name = TypeManager.IndexerPropertyName (container.TypeBuilder);
4100                                 ms = new MethodSignature (name, null, ParameterTypes);
4101                                 base_name = TypeManager.IndexerPropertyName (container.TypeBuilder.BaseType);
4102                                 base_ms = new MethodSignature (base_name, null, ParameterTypes);
4103                         } else {
4104                                 report_name = Name;
4105                                 ms = base_ms = new MethodSignature (Name, null, ParameterTypes);
4106                         }
4107
4108                         //
4109                         // Verify if the parent has a type with the same name, and then
4110                         // check whether we have to create a new slot for it or not.
4111                         //
4112                         Type ptype = container.TypeBuilder.BaseType;
4113
4114                         // ptype is only null for System.Object while compiling corlib.
4115                         if (ptype == null) {
4116                                 if ((ModFlags & Modifiers.NEW) != 0)
4117                                         WarningNotHiding (container);
4118
4119                                 return true;
4120                         }
4121
4122                         MemberList props_this;
4123
4124                         props_this = TypeContainer.FindMembers (
4125                                 container.TypeBuilder, MemberTypes.Property,
4126                                 BindingFlags.NonPublic | BindingFlags.Public |
4127                                 BindingFlags.Static | BindingFlags.Instance |
4128                                 BindingFlags.DeclaredOnly,
4129                                 MethodSignature.method_signature_filter, ms);
4130
4131                         if (props_this.Count > 0) {
4132                                 Report.Error (111, Location, "Class `" + container.Name + "' " +
4133                                               "already defines a member called `" + report_name + "' " +
4134                                               "with the same parameter types");
4135                                 return false;
4136                         }
4137
4138                         MemberList mi_props;
4139
4140                         mi_props = TypeContainer.FindMembers (
4141                                 ptype, MemberTypes.Property,
4142                                 BindingFlags.NonPublic | BindingFlags.Public |
4143                                 BindingFlags.Instance | BindingFlags.Static,
4144                                 MethodSignature.inheritable_method_signature_filter, base_ms);
4145
4146                         if (mi_props.Count > 0){
4147                                 PropertyInfo parent_property = (PropertyInfo) mi_props [0];
4148                                 string name = parent_property.DeclaringType.Name + "." +
4149                                         parent_property.Name;
4150
4151                                 MethodInfo get, set, parent_method;
4152                                 get = parent_property.GetGetMethod (true);
4153                                 set = parent_property.GetSetMethod (true);
4154
4155                                 if (get != null)
4156                                         parent_method = get;
4157                                 else if (set != null)
4158                                         parent_method = set;
4159                                 else
4160                                         throw new Exception ("Internal error!");
4161
4162                                 if (!CheckMethodAgainstBase (container, flags, parent_method, name))
4163                                         return false;
4164
4165                                 if ((ModFlags & Modifiers.NEW) == 0) {
4166                                         Type parent_type = TypeManager.TypeToCoreType (
4167                                                 parent_property.PropertyType);
4168
4169                                         if (parent_type != MemberType) {
4170                                                 Report.Error (
4171                                                         508, Location, container.MakeName (Name) + ": cannot " +
4172                                                         "change return type when overriding " +
4173                                                         "inherited member " + name);
4174                                                 return false;
4175                                         }
4176                                 }
4177                         } else {
4178                                 if ((ModFlags & Modifiers.NEW) != 0)
4179                                         WarningNotHiding (container);
4180
4181                                 if ((ModFlags & Modifiers.OVERRIDE) != 0){
4182                                         if (this is Indexer)
4183                                                 Report.Error (115, Location,
4184                                                               container.MakeName (Name) +
4185                                                               " no suitable indexers found to override");
4186                                         else
4187                                                 Report.Error (115, Location,
4188                                                               container.MakeName (Name) +
4189                                                               " no suitable properties found to override");
4190                                         return false;
4191                                 }
4192                         }
4193                         return true;
4194                 }
4195
4196                 public void Emit (TypeContainer tc)
4197                 {
4198                         //
4199                         // The PropertyBuilder can be null for explicit implementations, in that
4200                         // case, we do not actually emit the ".property", so there is nowhere to
4201                         // put the attribute
4202                         //
4203                         if (PropertyBuilder != null)
4204                                 Attribute.ApplyAttributes (ec, PropertyBuilder, this, OptAttributes);
4205
4206                         if (GetData != null) {
4207                                 GetData.Emit (tc, Get.Block, Get);
4208                                 Get.Block = null;
4209                         }
4210
4211                         if (SetData != null) {
4212                                 SetData.Emit (tc, Set.Block, Set);
4213                                 Set.Block = null;
4214                         }
4215                 }
4216         }
4217                         
4218         public class Property : PropertyBase {
4219                 const int AllowedModifiers =
4220                         Modifiers.NEW |
4221                         Modifiers.PUBLIC |
4222                         Modifiers.PROTECTED |
4223                         Modifiers.INTERNAL |
4224                         Modifiers.PRIVATE |
4225                         Modifiers.STATIC |
4226                         Modifiers.SEALED |
4227                         Modifiers.OVERRIDE |
4228                         Modifiers.ABSTRACT |
4229                         Modifiers.UNSAFE |
4230                         Modifiers.EXTERN |
4231                         Modifiers.VIRTUAL;
4232
4233                 public Property (DeclSpace ds, Expression type, string name, int mod_flags,
4234                                  Accessor get_block, Accessor set_block,
4235                                  Attributes attrs, Location loc)
4236                         : base (ds, type, name, mod_flags, AllowedModifiers,
4237                                 Parameters.EmptyReadOnlyParameters,
4238                                 get_block, set_block, attrs, loc)
4239                 {
4240                 }
4241
4242                 public override bool Define (TypeContainer container)
4243                 {
4244                         if (!DoDefine (container))
4245                                 return false;
4246
4247                         if (!CheckBase (container))
4248                                 return false;
4249
4250                         flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
4251
4252                         if (Get != null) {
4253                                 Type [] parameters = TypeManager.NoTypes;
4254
4255                                 InternalParameters ip = new InternalParameters (
4256                                         container, Parameters.EmptyReadOnlyParameters);
4257
4258                                 GetData = new MethodData (container, this, "get", MemberType,
4259                                                           parameters, ip, CallingConventions.Standard,
4260                                                           Get.OptAttributes, ModFlags, flags, false);
4261
4262                                 if (!GetData.Define (container))
4263                                         return false;
4264
4265                                 GetBuilder = GetData.MethodBuilder;
4266                         }
4267
4268                         if (Set != null) {
4269                                 Type [] parameters = new Type [1];
4270                                 parameters [0] = MemberType;
4271
4272                                 Parameter [] parms = new Parameter [1];
4273                                 parms [0] = new Parameter (Type, "value", Parameter.Modifier.NONE, null);
4274                                 InternalParameters ip = new InternalParameters (
4275                                         container, new Parameters (parms, null, Location));
4276
4277                                 SetData = new MethodData (container, this, "set", TypeManager.void_type,
4278                                                           parameters, ip, CallingConventions.Standard,
4279                                                           Set.OptAttributes, ModFlags, flags, false);
4280
4281                                 if (!SetData.Define (container))
4282                                         return false;
4283
4284                                 SetBuilder = SetData.MethodBuilder;
4285                                 SetBuilder.DefineParameter (1, ParameterAttributes.None, "value"); 
4286                         }
4287
4288                         // FIXME - PropertyAttributes.HasDefault ?
4289                         
4290                         PropertyAttributes prop_attr =
4291                         PropertyAttributes.RTSpecialName |
4292                         PropertyAttributes.SpecialName;
4293
4294                         if (!IsExplicitImpl){
4295                                 PropertyBuilder = container.TypeBuilder.DefineProperty (
4296                                         Name, prop_attr, MemberType, null);
4297                                 
4298                                 if (Get != null)
4299                                         PropertyBuilder.SetGetMethod (GetBuilder);
4300                                 
4301                                 if (Set != null)
4302                                         PropertyBuilder.SetSetMethod (SetBuilder);
4303
4304                                 //
4305                                 // HACK for the reasons exposed above
4306                                 //
4307                                 if (!TypeManager.RegisterProperty (PropertyBuilder, GetBuilder, SetBuilder)) {
4308                                         Report.Error (
4309                                                 111, Location,
4310                                                 "Class `" + container.Name +
4311                                                 "' already contains a definition for the property `" +
4312                                                 Name + "'");
4313                                         return false;
4314                                 }
4315                         }
4316                         return true;
4317                 }
4318         }
4319
4320         /// </summary>
4321         ///  Gigantic workaround  for lameness in SRE follows :
4322         ///  This class derives from EventInfo and attempts to basically
4323         ///  wrap around the EventBuilder so that FindMembers can quickly
4324         ///  return this in it search for members
4325         /// </summary>
4326         public class MyEventBuilder : EventInfo {
4327                 
4328                 //
4329                 // We use this to "point" to our Builder which is
4330                 // not really a MemberInfo
4331                 //
4332                 EventBuilder MyBuilder;
4333                 
4334                 //
4335                 // We "catch" and wrap these methods
4336                 //
4337                 MethodInfo raise, remove, add;
4338
4339                 EventAttributes attributes;
4340                 Type declaring_type, reflected_type, event_type;
4341                 string name;
4342
4343                 Event my_event;
4344
4345                 public MyEventBuilder (Event ev, TypeBuilder type_builder, string name, EventAttributes event_attr, Type event_type)
4346                 {
4347                         MyBuilder = type_builder.DefineEvent (name, event_attr, event_type);
4348
4349                         // And now store the values in our own fields.
4350                         
4351                         declaring_type = type_builder;
4352
4353                         reflected_type = type_builder;
4354                         
4355                         attributes = event_attr;
4356                         this.name = name;
4357                         my_event = ev;
4358                         this.event_type = event_type;
4359                 }
4360                 
4361                 //
4362                 // Methods that you have to override.  Note that you only need 
4363                 // to "implement" the variants that take the argument (those are
4364                 // the "abstract" methods, the others (GetAddMethod()) are 
4365                 // regular.
4366                 //
4367                 public override MethodInfo GetAddMethod (bool nonPublic)
4368                 {
4369                         return add;
4370                 }
4371                 
4372                 public override MethodInfo GetRemoveMethod (bool nonPublic)
4373                 {
4374                         return remove;
4375                 }
4376                 
4377                 public override MethodInfo GetRaiseMethod (bool nonPublic)
4378                 {
4379                         return raise;
4380                 }
4381                 
4382                 //
4383                 // These methods make "MyEventInfo" look like a Builder
4384                 //
4385                 public void SetRaiseMethod (MethodBuilder raiseMethod)
4386                 {
4387                         raise = raiseMethod;
4388                         MyBuilder.SetRaiseMethod (raiseMethod);
4389                 }
4390
4391                 public void SetRemoveOnMethod (MethodBuilder removeMethod)
4392                 {
4393                         remove = removeMethod;
4394                         MyBuilder.SetRemoveOnMethod (removeMethod);
4395                 }
4396
4397                 public void SetAddOnMethod (MethodBuilder addMethod)
4398                 {
4399                         add = addMethod;
4400                         MyBuilder.SetAddOnMethod (addMethod);
4401                 }
4402
4403                 public void SetCustomAttribute (CustomAttributeBuilder cb)
4404                 {
4405                         MyBuilder.SetCustomAttribute (cb);
4406                 }
4407                 
4408                 public override object [] GetCustomAttributes (bool inherit)
4409                 {
4410                         // FIXME : There's nothing which can be seemingly done here because
4411                         // we have no way of getting at the custom attribute objects of the
4412                         // EventBuilder !
4413                         return null;
4414                 }
4415
4416                 public override object [] GetCustomAttributes (Type t, bool inherit)
4417                 {
4418                         // FIXME : Same here !
4419                         return null;
4420                 }
4421
4422                 public override bool IsDefined (Type t, bool b)
4423                 {
4424                         return true;
4425                 }
4426
4427                 public override EventAttributes Attributes {
4428                         get {
4429                                 return attributes;
4430                         }
4431                 }
4432
4433                 public override string Name {
4434                         get {
4435                                 return name;
4436                         }
4437                 }
4438
4439                 public override Type DeclaringType {
4440                         get {
4441                                 return declaring_type;
4442                         }
4443                 }
4444
4445                 public override Type ReflectedType {
4446                         get {
4447                                 return reflected_type;
4448                         }
4449                 }
4450
4451                 public Type EventType {
4452                         get {
4453                                 return event_type;
4454                         }
4455                 }
4456                 
4457                 public void SetUsed ()
4458                 {
4459                         if (my_event != null)
4460                                 my_event.status = (FieldBase.Status.ASSIGNED | FieldBase.Status.USED);
4461                 }
4462         }
4463         
4464         public class Event : FieldBase {
4465                 const int AllowedModifiers =
4466                         Modifiers.NEW |
4467                         Modifiers.PUBLIC |
4468                         Modifiers.PROTECTED |
4469                         Modifiers.INTERNAL |
4470                         Modifiers.PRIVATE |
4471                         Modifiers.STATIC |
4472                         Modifiers.VIRTUAL |
4473                         Modifiers.SEALED |
4474                         Modifiers.OVERRIDE |
4475                         Modifiers.UNSAFE |
4476                         Modifiers.ABSTRACT;
4477
4478                 public readonly Accessor  Add;
4479                 public readonly Accessor  Remove;
4480                 public MyEventBuilder     EventBuilder;
4481
4482                 MethodBuilder AddBuilder, RemoveBuilder;
4483                 MethodData AddData, RemoveData;
4484                 
4485                 public Event (Expression type, string name, Object init, int mod, Accessor add,
4486                               Accessor remove, Attributes attrs, Location loc)
4487                         : base (type, mod, AllowedModifiers, name, init, attrs, loc)
4488                 {
4489                         Add = add;
4490                         Remove = remove;
4491                 }
4492
4493                 public override bool Define (TypeContainer container)
4494                 {
4495                         EventAttributes e_attr = EventAttributes.RTSpecialName | EventAttributes.SpecialName;
4496                         MethodAttributes m_attr = MethodAttributes.HideBySig | MethodAttributes.SpecialName
4497 ;
4498                         if (!DoDefine (container))
4499                                 return false;
4500
4501                         if (init != null && ((ModFlags & Modifiers.ABSTRACT) != 0)){
4502                                 Report.Error (74, Location, "'" + container.Name + "." + Name +
4503                                               "': abstract event can not have an initializer");
4504                                 return false;
4505                         }
4506                         
4507                         if (!MemberType.IsSubclassOf (TypeManager.delegate_type)) {
4508                                 Report.Error (66, Location, "'" + container.Name + "." + Name +
4509                                               "' : event must be of a delegate type");
4510                                 return false;
4511                         }
4512
4513                         Type [] parameter_types = new Type [1];
4514                         parameter_types [0] = MemberType;
4515
4516                         Parameter [] parms = new Parameter [1];
4517                         parms [0] = new Parameter (Type, "value", Parameter.Modifier.NONE, null);
4518                         InternalParameters ip = new InternalParameters (
4519                                 container, new Parameters (parms, null, Location)); 
4520
4521                         if (!CheckBase (container))
4522                                 return false;
4523
4524                         //
4525                         // Now define the accessors
4526                         //
4527                         AddData = new MethodData (container, this, "add", TypeManager.void_type,
4528                                                   parameter_types, ip, CallingConventions.Standard,
4529                                                   (Add != null) ? Add.OptAttributes : null,
4530                                                   ModFlags, flags | m_attr, false);
4531
4532                         if (!AddData.Define (container))
4533                                 return false;
4534
4535                         AddBuilder = AddData.MethodBuilder;
4536                         AddBuilder.DefineParameter (1, ParameterAttributes.None, "value");
4537
4538                         RemoveData = new MethodData (container, this, "remove", TypeManager.void_type,
4539                                                      parameter_types, ip, CallingConventions.Standard,
4540                                                      (Remove != null) ? Remove.OptAttributes : null,
4541                                                      ModFlags, flags | m_attr, false);
4542
4543                         if (!RemoveData.Define (container))
4544                                 return false;
4545
4546                         RemoveBuilder = RemoveData.MethodBuilder;
4547                         RemoveBuilder.DefineParameter (1, ParameterAttributes.None, "value");
4548
4549                         if (!IsExplicitImpl){
4550                                 EventBuilder = new MyEventBuilder (this,
4551                                         container.TypeBuilder, Name, e_attr, MemberType);
4552                                         
4553                                 if (Add == null && Remove == null) {
4554                                         FieldBuilder = container.TypeBuilder.DefineField (
4555                                                 Name, MemberType,
4556                                                 FieldAttributes.Private | ((ModFlags & Modifiers.STATIC) != 0 ? FieldAttributes.Static : 0));
4557                                         TypeManager.RegisterPrivateFieldOfEvent (
4558                                                 (EventInfo) EventBuilder, FieldBuilder);
4559                                         TypeManager.RegisterFieldBase (FieldBuilder, this);
4560                                 }
4561                         
4562                                 EventBuilder.SetAddOnMethod (AddBuilder);
4563                                 EventBuilder.SetRemoveOnMethod (RemoveBuilder);
4564
4565                                 if (!TypeManager.RegisterEvent (EventBuilder, AddBuilder, RemoveBuilder)) {
4566                                         Report.Error (111, Location,
4567                                                       "Class `" + container.Name +
4568                                                       "' already contains a definition for the event `" +
4569                                                       Name + "'");
4570                                         return false;
4571                                 }
4572                         }
4573                         
4574                         return true;
4575                 }
4576
4577                 void EmitDefaultMethod (EmitContext ec, bool is_add)
4578                 {
4579                         ILGenerator ig = ec.ig;
4580                         MethodInfo method = null;
4581                         
4582                         if (is_add)
4583                                 method = TypeManager.delegate_combine_delegate_delegate;
4584                         else
4585                                 method = TypeManager.delegate_remove_delegate_delegate;
4586
4587                         if ((ModFlags & Modifiers.STATIC) != 0) {
4588                                 ig.Emit (OpCodes.Ldsfld, (FieldInfo) FieldBuilder);
4589                                 ig.Emit (OpCodes.Ldarg_0);
4590                                 ig.Emit (OpCodes.Call, method);
4591                                 ig.Emit (OpCodes.Castclass, MemberType);
4592                                 ig.Emit (OpCodes.Stsfld, (FieldInfo) FieldBuilder);
4593                         } else {
4594                                 ig.Emit (OpCodes.Ldarg_0);
4595                                 ig.Emit (OpCodes.Ldarg_0);
4596                                 ig.Emit (OpCodes.Ldfld, (FieldInfo) FieldBuilder);
4597                                 ig.Emit (OpCodes.Ldarg_1);
4598                                 ig.Emit (OpCodes.Call, method);
4599                                 ig.Emit (OpCodes.Castclass, MemberType);
4600                                 ig.Emit (OpCodes.Stfld, (FieldInfo) FieldBuilder);
4601                         }
4602                         ig.Emit (OpCodes.Ret);
4603                 }
4604
4605                 public void Emit (TypeContainer tc)
4606                 {
4607                         EmitContext ec;
4608
4609                         ec = new EmitContext (tc, Location, null, MemberType, ModFlags);
4610                         Attribute.ApplyAttributes (ec, EventBuilder, this, OptAttributes);
4611
4612                         if (Add != null) {
4613                                 AddData.Emit (tc, Add.Block, Add);
4614                                 Add.Block = null;
4615                         } else {
4616                                 ILGenerator ig = AddData.MethodBuilder.GetILGenerator ();
4617                                 ec = new EmitContext (tc, Location, ig, TypeManager.void_type, ModFlags);
4618                                 EmitDefaultMethod (ec, true);
4619                         }
4620
4621                         if (Remove != null) {
4622                                 RemoveData.Emit (tc, Remove.Block, Remove);
4623                                 Remove.Block = null;
4624                         } else {
4625                                 ILGenerator ig = RemoveData.MethodBuilder.GetILGenerator ();
4626                                 ec = new EmitContext (tc, Location, ig, TypeManager.void_type, ModFlags);
4627                                 EmitDefaultMethod (ec, false);
4628                         }
4629                 }
4630                 
4631         }
4632
4633         //
4634         // FIXME: This does not handle:
4635         //
4636         //   int INTERFACENAME [ args ]
4637         //   Does not 
4638         //
4639         // Only:
4640         // 
4641         // int this [ args ]
4642  
4643         public class Indexer : PropertyBase {
4644
4645                 const int AllowedModifiers =
4646                         Modifiers.NEW |
4647                         Modifiers.PUBLIC |
4648                         Modifiers.PROTECTED |
4649                         Modifiers.INTERNAL |
4650                         Modifiers.PRIVATE |
4651                         Modifiers.VIRTUAL |
4652                         Modifiers.SEALED |
4653                         Modifiers.OVERRIDE |
4654                         Modifiers.UNSAFE |
4655                         Modifiers.EXTERN |
4656                         Modifiers.ABSTRACT;
4657
4658                 public string IndexerName;
4659                 public string InterfaceIndexerName;
4660
4661                 //
4662                 // Are we implementing an interface ?
4663                 //
4664                 public Indexer (DeclSpace ds, Expression type, string int_type, int flags,
4665                                 Parameters parameters, Accessor get_block, Accessor set_block,
4666                                 Attributes attrs, Location loc)
4667                         : base (ds, type, "", flags, AllowedModifiers, parameters, get_block, set_block,
4668                                 attrs, loc)
4669                 {
4670                         ExplicitInterfaceName = int_type;
4671                 }
4672
4673                 public override bool Define (TypeContainer container)
4674                 {
4675                         PropertyAttributes prop_attr =
4676                                 PropertyAttributes.RTSpecialName |
4677                                 PropertyAttributes.SpecialName;
4678                         
4679                         if (!DoDefine (container))
4680                                 return false;
4681
4682                         IndexerName = Attribute.ScanForIndexerName (ec, OptAttributes);
4683                         if (IndexerName == null)
4684                                 IndexerName = "Item";
4685                         else if (IsExplicitImpl)
4686                                 Report.Error (592, Location,
4687                                               "Attribute 'IndexerName' is not valid on this declaration " +
4688                                               "type. It is valid on `property' declarations only.");
4689
4690                         ShortName = IndexerName;
4691                         if (IsExplicitImpl) {
4692                                 InterfaceIndexerName = TypeManager.IndexerPropertyName (InterfaceType);
4693                                 Name = InterfaceType.FullName + "." + IndexerName;
4694                         } else {
4695                                 InterfaceIndexerName = IndexerName;
4696                                 Name = ShortName;
4697                         }
4698
4699                         if (!CheckBase (container))
4700                                 return false;
4701
4702                         flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
4703                         if (Get != null){
4704                                 InternalParameters ip = new InternalParameters (container, Parameters);
4705
4706                                 GetData = new MethodData (container, this, "get", MemberType,
4707                                                           ParameterTypes, ip, CallingConventions.Standard,
4708                                                           Get.OptAttributes, ModFlags, flags, false);
4709
4710                                 if (!GetData.Define (container))
4711                                         return false;
4712
4713                                 GetBuilder = GetData.MethodBuilder;
4714                         }
4715                         
4716                         if (Set != null){
4717                                 int top = ParameterTypes.Length;
4718                                 Type [] set_pars = new Type [top + 1];
4719                                 ParameterTypes.CopyTo (set_pars, 0);
4720                                 set_pars [top] = MemberType;
4721
4722                                 Parameter [] fixed_parms = Parameters.FixedParameters;
4723
4724                                 if (fixed_parms == null){
4725                                         throw new Exception ("We currently do not support only array arguments in an indexer at: " + Location);
4726                                         // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
4727                                         // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
4728                                         //
4729                                         // Here is the problem: the `value' parameter has
4730                                         // to come *after* the array parameter in the declaration
4731                                         // like this:
4732                                         // X (object [] x, Type value)
4733                                         // .param [0]
4734                                         //
4735                                         // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
4736                                         // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
4737                                         
4738                                 }
4739                                 
4740                                 Parameter [] tmp = new Parameter [fixed_parms.Length + 1];
4741
4742
4743                                 fixed_parms.CopyTo (tmp, 0);
4744                                 tmp [fixed_parms.Length] = new Parameter (
4745                                         Type, "value", Parameter.Modifier.NONE, null);
4746
4747                                 Parameters set_formal_params = new Parameters (tmp, null, Location);
4748                                 
4749                                 InternalParameters ip = new InternalParameters (container, set_formal_params);
4750
4751                                 SetData = new MethodData (container, this, "set", TypeManager.void_type,
4752                                                           set_pars, ip, CallingConventions.Standard,
4753                                                           Set.OptAttributes, ModFlags, flags, false);
4754
4755                                 if (!SetData.Define (container))
4756                                         return false;
4757
4758                                 SetBuilder = SetData.MethodBuilder;
4759                         }
4760
4761                         //
4762                         // Now name the parameters
4763                         //
4764                         Parameter [] p = Parameters.FixedParameters;
4765                         if (p != null) {
4766                                 int i;
4767                                 
4768                                 for (i = 0; i < p.Length; ++i) {
4769                                         if (Get != null)
4770                                                 GetBuilder.DefineParameter (
4771                                                         i + 1, p [i].Attributes, p [i].Name);
4772
4773                                         if (Set != null)
4774                                                 SetBuilder.DefineParameter (
4775                                                         i + 1, p [i].Attributes, p [i].Name);
4776                                 }
4777
4778                                 if (Set != null)
4779                                         SetBuilder.DefineParameter (
4780                                                 i + 1, ParameterAttributes.None, "value");
4781                                         
4782                                 if (i != ParameterTypes.Length) {
4783                                         Parameter array_param = Parameters.ArrayParameter;
4784
4785                                         SetBuilder.DefineParameter (
4786                                                 i + 1, array_param.Attributes, array_param.Name);
4787                                 }
4788                         }
4789
4790                         //
4791                         // Define the PropertyBuilder if one of the following conditions are met:
4792                         // a) we're not implementing an interface indexer.
4793                         // b) the indexer has a different IndexerName and this is no
4794                         //    explicit interface implementation.
4795                         //
4796                         if (!IsExplicitImpl) {
4797                                 PropertyBuilder = container.TypeBuilder.DefineProperty (
4798                                         IndexerName, prop_attr, MemberType, ParameterTypes);
4799
4800                                 if (GetData != null)
4801                                         PropertyBuilder.SetGetMethod (GetBuilder);
4802
4803                                 if (SetData != null)
4804                                         PropertyBuilder.SetSetMethod (SetBuilder);
4805                                 
4806                                 TypeManager.RegisterIndexer (PropertyBuilder, GetBuilder, SetBuilder,
4807                                                              ParameterTypes);
4808                         }
4809
4810                         return true;
4811                 }
4812         }
4813
4814         public class Operator : MemberBase {
4815
4816                 const int AllowedModifiers =
4817                         Modifiers.PUBLIC |
4818                         Modifiers.UNSAFE |
4819                         Modifiers.EXTERN |
4820                         Modifiers.STATIC;
4821
4822                 const int RequiredModifiers =
4823                         Modifiers.PUBLIC |
4824                         Modifiers.STATIC;
4825
4826                 public enum OpType : byte {
4827
4828                         // Unary operators
4829                         LogicalNot,
4830                         OnesComplement,
4831                         Increment,
4832                         Decrement,
4833                         True,
4834                         False,
4835
4836                         // Unary and Binary operators
4837                         Addition,
4838                         Subtraction,
4839
4840                         UnaryPlus,
4841                         UnaryNegation,
4842                         
4843                         // Binary operators
4844                         Multiply,
4845                         Division,
4846                         Modulus,
4847                         BitwiseAnd,
4848                         BitwiseOr,
4849                         ExclusiveOr,
4850                         LeftShift,
4851                         RightShift,
4852                         Equality,
4853                         Inequality,
4854                         GreaterThan,
4855                         LessThan,
4856                         GreaterThanOrEqual,
4857                         LessThanOrEqual,
4858
4859                         // Implicit and Explicit
4860                         Implicit,
4861                         Explicit
4862                 };
4863
4864                 public readonly OpType OperatorType;
4865                 public readonly Expression ReturnType;
4866                 public readonly Expression FirstArgType, SecondArgType;
4867                 public readonly string FirstArgName, SecondArgName;
4868                 public Block           Block;
4869                 public MethodBuilder   OperatorMethodBuilder;
4870                 
4871                 public string MethodName;
4872                 public Method OperatorMethod;
4873
4874                 public Operator (OpType type, Expression ret_type, int mod_flags,
4875                                  Expression arg1type, string arg1name,
4876                                  Expression arg2type, string arg2name,
4877                                  Block block, Attributes attrs, Location loc)
4878                         : base (ret_type, mod_flags, AllowedModifiers, Modifiers.PUBLIC, "", attrs, loc)
4879                 {
4880                         OperatorType = type;
4881                         ReturnType = ret_type;
4882                         FirstArgType = arg1type;
4883                         FirstArgName = arg1name;
4884                         SecondArgType = arg2type;
4885                         SecondArgName = arg2name;
4886                         Block = block;
4887                 }
4888
4889                 string Prototype (TypeContainer container)
4890                 {
4891                         return container.Name + ".operator " + OperatorType + " (" + FirstArgType + "," +
4892                                 SecondArgType + ")";
4893                 }
4894                 
4895                 public override bool Define (TypeContainer container)
4896                 {
4897                         int length = 1;
4898                         MethodName = "op_" + OperatorType;
4899                         
4900                         if (SecondArgType != null)
4901                                 length = 2;
4902                         
4903                         Parameter [] param_list = new Parameter [length];
4904
4905                         if ((ModFlags & RequiredModifiers) != RequiredModifiers){
4906                                 Report.Error (
4907                                         558, Location, 
4908                                         "User defined operators `" +
4909                                         Prototype (container) +
4910                                         "' must be declared static and public");
4911                                 return false;
4912                         }
4913
4914                         param_list[0] = new Parameter (FirstArgType, FirstArgName,
4915                                                        Parameter.Modifier.NONE, null);
4916                         if (SecondArgType != null)
4917                                 param_list[1] = new Parameter (SecondArgType, SecondArgName,
4918                                                                Parameter.Modifier.NONE, null);
4919                         
4920                         OperatorMethod = new Method (container, ReturnType, ModFlags, MethodName,
4921                                                      new Parameters (param_list, null, Location),
4922                                                      OptAttributes, Location);
4923
4924                         OperatorMethod.IsOperator = true;                       
4925                         OperatorMethod.Define (container);
4926
4927                         if (OperatorMethod.MethodBuilder == null)
4928                                 return false;
4929                         
4930                         OperatorMethodBuilder = OperatorMethod.MethodBuilder;
4931
4932                         Type [] param_types = OperatorMethod.ParameterTypes;
4933                         Type declaring_type = OperatorMethodBuilder.DeclaringType;
4934                         Type return_type = OperatorMethod.GetReturnType ();
4935                         Type first_arg_type = param_types [0];
4936
4937                         // Rules for conversion operators
4938                         
4939                         if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
4940                                 if (first_arg_type == return_type && first_arg_type == declaring_type){
4941                                         Report.Error (
4942                                                 555, Location,
4943                                                 "User-defined conversion cannot take an object of the " +
4944                                                 "enclosing type and convert to an object of the enclosing" +
4945                                                 " type");
4946                                         return false;
4947                                 }
4948                                 
4949                                 if (first_arg_type != declaring_type && return_type != declaring_type){
4950                                         Report.Error (
4951                                                 556, Location, 
4952                                                 "User-defined conversion must convert to or from the " +
4953                                                 "enclosing type");
4954                                         return false;
4955                                 }
4956                                 
4957                                 if (first_arg_type == TypeManager.object_type ||
4958                                     return_type == TypeManager.object_type){
4959                                         Report.Error (
4960                                                 -8, Location,
4961                                                 "User-defined conversion cannot convert to or from " +
4962                                                 "object type");
4963                                         return false;
4964                                 }
4965
4966                                 if (first_arg_type.IsInterface || return_type.IsInterface){
4967                                         Report.Error (
4968                                                 552, Location,
4969                                                 "User-defined conversion cannot convert to or from an " +
4970                                                 "interface type");
4971                                         return false;
4972                                 }
4973                                 
4974                                 if (first_arg_type.IsSubclassOf (return_type) ||
4975                                     return_type.IsSubclassOf (first_arg_type)){
4976                                         Report.Error (
4977                                                 -10, Location,
4978                                                 "User-defined conversion cannot convert between types " +
4979                                                 "that derive from each other");
4980                                         return false;
4981                                 }
4982                         } else if (SecondArgType == null) {
4983                                 // Checks for Unary operators
4984                                 
4985                                 if (first_arg_type != declaring_type){
4986                                         Report.Error (
4987                                                 562, Location,
4988                                                 "The parameter of a unary operator must be the " +
4989                                                 "containing type");
4990                                         return false;
4991                                 }
4992                                 
4993                                 if (OperatorType == OpType.Increment || OperatorType == OpType.Decrement) {
4994                                         if (return_type != declaring_type){
4995                                                 Report.Error (
4996                                                         559, Location,
4997                                                         "The parameter and return type for ++ and -- " +
4998                                                         "must be the containing type");
4999                                                 return false;
5000                                         }
5001                                         
5002                                 }
5003                                 
5004                                 if (OperatorType == OpType.True || OperatorType == OpType.False) {
5005                                         if (return_type != TypeManager.bool_type){
5006                                                 Report.Error (
5007                                                         215, Location,
5008                                                         "The return type of operator True or False " +
5009                                                         "must be bool");
5010                                                 return false;
5011                                         }
5012                                 }
5013                                 
5014                         } else {
5015                                 // Checks for Binary operators
5016                                 
5017                                 if (first_arg_type != declaring_type &&
5018                                     param_types [1] != declaring_type){
5019                                         Report.Error (
5020                                                 563, Location,
5021                                                 "One of the parameters of a binary operator must " +
5022                                                 "be the containing type");
5023                                         return false;
5024                                 }
5025                         }
5026
5027                         return true;
5028                 }
5029                 
5030                 public void Emit (TypeContainer container)
5031                 {
5032                         //
5033                         // abstract or extern methods have no bodies
5034                         //
5035                         if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
5036                                 return;
5037                         
5038                         OperatorMethod.Block = Block;
5039                         OperatorMethod.Emit (container);
5040                         Block = null;
5041                 }
5042
5043                 public static string GetName (OpType ot)
5044                 {
5045                         switch (ot){
5046                         case OpType.LogicalNot:
5047                                 return "!";
5048                         case OpType.OnesComplement:
5049                                 return "~";
5050                         case OpType.Increment:
5051                                 return "++";
5052                         case OpType.Decrement:
5053                                 return "--";
5054                         case OpType.True:
5055                                 return "true";
5056                         case OpType.False:
5057                                 return "false";
5058                         case OpType.Addition:
5059                                 return "+";
5060                         case OpType.Subtraction:
5061                                 return "-";
5062                         case OpType.UnaryPlus:
5063                                 return "+";
5064                         case OpType.UnaryNegation:
5065                                 return "-";
5066                         case OpType.Multiply:
5067                                 return "*";
5068                         case OpType.Division:
5069                                 return "/";
5070                         case OpType.Modulus:
5071                                 return "%";
5072                         case OpType.BitwiseAnd:
5073                                 return "&";
5074                         case OpType.BitwiseOr:
5075                                 return "|";
5076                         case OpType.ExclusiveOr:
5077                                 return "^";
5078                         case OpType.LeftShift:
5079                                 return "<<";
5080                         case OpType.RightShift:
5081                                 return ">>";
5082                         case OpType.Equality:
5083                                 return "==";
5084                         case OpType.Inequality:
5085                                 return "!=";
5086                         case OpType.GreaterThan:
5087                                 return ">";
5088                         case OpType.LessThan:
5089                                 return "<";
5090                         case OpType.GreaterThanOrEqual:
5091                                 return ">=";
5092                         case OpType.LessThanOrEqual:
5093                                 return "<=";
5094                         case OpType.Implicit:
5095                                 return "implicit";
5096                         case OpType.Explicit:
5097                                 return "explicit";
5098                         default: return "";
5099                         }
5100                 }
5101                 
5102                 public override string ToString ()
5103                 {
5104                         Type return_type = OperatorMethod.GetReturnType();
5105                         Type [] param_types = OperatorMethod.ParameterTypes;
5106                         
5107                         if (SecondArgType == null)
5108                                 return String.Format (
5109                                         "{0} operator {1}({2})",
5110                                         TypeManager.CSharpName (return_type),
5111                                         GetName (OperatorType),
5112                                         param_types [0]);
5113                         else
5114                                 return String.Format (
5115                                         "{0} operator {1}({2}, {3})",
5116                                         TypeManager.CSharpName (return_type),
5117                                         GetName (OperatorType),
5118                                         param_types [0], param_types [1]);
5119                 }
5120         }
5121
5122         //
5123         // This is used to compare method signatures
5124         //
5125         struct MethodSignature {
5126                 public string Name;
5127                 public Type RetType;
5128                 public Type [] Parameters;
5129                 
5130                 /// <summary>
5131                 ///    This delegate is used to extract methods which have the
5132                 ///    same signature as the argument
5133                 /// </summary>
5134                 public static MemberFilter method_signature_filter;
5135
5136                 /// <summary>
5137                 ///   This delegate is used to extract inheritable methods which
5138                 ///   have the same signature as the argument.  By inheritable,
5139                 ///   this means that we have permissions to override the method
5140                 ///   from the current assembly and class
5141                 /// </summary>
5142                 public static MemberFilter inheritable_method_signature_filter;
5143
5144                 static MethodSignature ()
5145                 {
5146                         method_signature_filter = new MemberFilter (MemberSignatureCompare);
5147                         inheritable_method_signature_filter = new MemberFilter (
5148                                 InheritableMemberSignatureCompare);
5149                 }
5150                 
5151                 public MethodSignature (string name, Type ret_type, Type [] parameters)
5152                 {
5153                         Name = name;
5154                         RetType = ret_type;
5155
5156                         if (parameters == null)
5157                                 Parameters = TypeManager.NoTypes;
5158                         else
5159                                 Parameters = parameters;
5160                 }
5161
5162                 public override string ToString ()
5163                 {
5164                         string pars = "";
5165                         if (Parameters.Length != 0){
5166                                 System.Text.StringBuilder sb = new System.Text.StringBuilder ();
5167                                 for (int i = 0; i < Parameters.Length; i++){
5168                                         sb.Append (Parameters [i]);
5169                                         if (i+1 < Parameters.Length)
5170                                                 sb.Append (", ");
5171                                 }
5172                                 pars = sb.ToString ();
5173                         }
5174
5175                         return String.Format ("{0} {1} ({2})", RetType, Name, pars);
5176                 }
5177                 
5178                 public override int GetHashCode ()
5179                 {
5180                         return Name.GetHashCode ();
5181                 }
5182
5183                 public override bool Equals (Object o)
5184                 {
5185                         MethodSignature other = (MethodSignature) o;
5186
5187                         if (other.Name != Name)
5188                                 return false;
5189
5190                         if (other.RetType != RetType)
5191                                 return false;
5192                         
5193                         if (Parameters == null){
5194                                 if (other.Parameters == null)
5195                                         return true;
5196                                 return false;
5197                         }
5198
5199                         if (other.Parameters == null)
5200                                 return false;
5201                         
5202                         int c = Parameters.Length;
5203                         if (other.Parameters.Length != c)
5204                                 return false;
5205
5206                         for (int i = 0; i < c; i++)
5207                                 if (other.Parameters [i] != Parameters [i])
5208                                         return false;
5209
5210                         return true;
5211                 }
5212
5213                 static bool MemberSignatureCompare (MemberInfo m, object filter_criteria)
5214                 {
5215                         MethodSignature sig = (MethodSignature) filter_criteria;
5216
5217                         if (m.Name != sig.Name)
5218                                 return false;
5219
5220                         Type ReturnType;
5221                         MethodInfo mi = m as MethodInfo;
5222                         PropertyInfo pi = m as PropertyInfo;
5223
5224                         if (mi != null)
5225                                 ReturnType = mi.ReturnType;
5226                         else if (pi != null)
5227                                 ReturnType = pi.PropertyType;
5228                         else
5229                                 return false;
5230                         
5231                         //
5232                         // we use sig.RetType == null to mean `do not check the
5233                         // method return value.  
5234                         //
5235                         if (sig.RetType != null)
5236                                 if (ReturnType != sig.RetType)
5237                                         return false;
5238
5239                         Type [] args;
5240                         if (mi != null)
5241                                 args = TypeManager.GetArgumentTypes (mi);
5242                         else
5243                                 args = TypeManager.GetArgumentTypes (pi);
5244                         Type [] sigp = sig.Parameters;
5245
5246                         if (args.Length != sigp.Length)
5247                                 return false;
5248
5249                         for (int i = args.Length; i > 0; ){
5250                                 i--;
5251                                 if (args [i] != sigp [i])
5252                                         return false;
5253                         }
5254                         return true;
5255                 }
5256
5257                 //
5258                 // This filter should be used when we are requesting methods that
5259                 // we want to override.
5260                 //
5261                 // This makes a number of assumptions, for example
5262                 // that the methods being extracted are of a parent
5263                 // class (this means we know implicitly that we are
5264                 // being called to find out about members by a derived
5265                 // class).
5266                 // 
5267                 static bool InheritableMemberSignatureCompare (MemberInfo m, object filter_criteria)
5268                 {
5269                         MethodInfo mi;
5270                         PropertyInfo pi = m as PropertyInfo;
5271
5272                         if (pi != null) {
5273                                 mi = pi.GetGetMethod (true);
5274                                 if (mi == null)
5275                                         mi = pi.GetSetMethod (true);
5276                         } else
5277                                 mi = m as MethodInfo;
5278
5279                         if (mi == null){
5280                                 Console.WriteLine ("Nothing found");
5281                         }
5282                         
5283                         MethodAttributes prot = mi.Attributes & MethodAttributes.MemberAccessMask;
5284
5285                         // If only accessible to the current class.
5286                         if (prot == MethodAttributes.Private)
5287                                 return false;
5288
5289                         if (!MemberSignatureCompare (m, filter_criteria))
5290                                 return false;
5291
5292                         // If only accessible to the defining assembly or 
5293                         if (prot == MethodAttributes.FamANDAssem ||
5294                             prot == MethodAttributes.Assembly){
5295                                 if (m.DeclaringType.Assembly == CodeGen.AssemblyBuilder)
5296                                         return true;
5297                                 else
5298                                         return false;
5299                         }
5300
5301                         // Anything else (FamOrAssembly and Public) is fine
5302                         return true;
5303                 }
5304         }
5305 }