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