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