Few property related checks applied
[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
1368                                                 if (pb != null && filter (pb, criteria) == true) {
1369                                                         members.Add (p.PropertyBuilder);
1370                                                 }
1371                                         }
1372
1373                                 if (indexers != null)
1374                                         foreach (Indexer ix in indexers) {
1375                                                 if ((ix.ModFlags & modflags) == 0)
1376                                                         continue;
1377                                                 if ((ix.ModFlags & static_mask) != static_flags)
1378                                                         continue;
1379
1380                                                 MemberInfo ib = ix.PropertyBuilder;
1381                                                 if (ib != null && filter (ib, criteria) == true) {
1382                                                         members.Add (ix.PropertyBuilder);
1383                                                 }
1384                                         }
1385                         }
1386                         
1387                         if ((mt & MemberTypes.NestedType) != 0) {
1388                                 if (types != null){
1389                                         foreach (TypeContainer t in types) {
1390                                                 if ((t.ModFlags & modflags) == 0)
1391                                                         continue;
1392
1393                                                 TypeBuilder tb = t.TypeBuilder;
1394                                                 if (tb != null && (filter (tb, criteria) == true))
1395                                                                 members.Add (tb);
1396                                         }
1397                                 }
1398
1399                                 if (enums != null){
1400                                         foreach (Enum en in enums){
1401                                                 if ((en.ModFlags & modflags) == 0)
1402                                                         continue;
1403
1404                                                 TypeBuilder tb = en.TypeBuilder;
1405                                                 if (tb != null && (filter (tb, criteria) == true))
1406                                                         members.Add (tb);
1407                                         }
1408                                 }
1409                                 
1410                                 if (delegates != null){
1411                                         foreach (Delegate d in delegates){
1412                                                 if ((d.ModFlags & modflags) == 0)
1413                                                         continue;
1414
1415                                                 TypeBuilder tb = d.TypeBuilder;
1416                                                 if (tb != null && (filter (tb, criteria) == true))
1417                                                         members.Add (tb);
1418                                         }
1419                                 }
1420
1421                                 if (interfaces != null){
1422                                         foreach (Interface iface in interfaces){
1423                                                 if ((iface.ModFlags & modflags) == 0)
1424                                                         continue;
1425
1426                                                 TypeBuilder tb = iface.TypeBuilder;
1427                                                 if (tb != null && (filter (tb, criteria) == true))
1428                                                         members.Add (tb);
1429                                         }
1430                                 }
1431                         }
1432
1433                         if ((mt & MemberTypes.Constructor) != 0){
1434                                 if (((bf & BindingFlags.Instance) != 0) && (instance_constructors != null)){
1435                                         foreach (Constructor c in instance_constructors){
1436                                                 ConstructorBuilder cb = c.ConstructorBuilder;
1437                                                 if (cb != null)
1438                                                         if (filter (cb, criteria) == true)
1439                                                                 members.Add (cb);
1440                                         }
1441                                 }
1442
1443                                 if (((bf & BindingFlags.Static) != 0) && (default_static_constructor != null)){
1444                                         ConstructorBuilder cb =
1445                                                 default_static_constructor.ConstructorBuilder;
1446                                         
1447                                         if (cb != null)
1448                                         if (filter (cb, criteria) == true)
1449                                                 members.Add (cb);
1450                                 }
1451                         }
1452
1453                         //
1454                         // Lookup members in parent if requested.
1455                         //
1456                         if (((bf & BindingFlags.DeclaredOnly) == 0) && (TypeBuilder.BaseType != null)) {
1457                                 MemberList list = FindMembers (TypeBuilder.BaseType, mt, bf, filter, criteria);
1458                                 members.AddRange (list);
1459                         }
1460
1461                         Timer.StopTimer (TimerType.TcFindMembers);
1462
1463                         return new MemberList (members);
1464                 }
1465
1466                 public override MemberCache MemberCache {
1467                         get {
1468                                 return member_cache;
1469                         }
1470                 }
1471
1472                 public static MemberList FindMembers (Type t, MemberTypes mt, BindingFlags bf,
1473                                                       MemberFilter filter, object criteria)
1474                 {
1475                         TypeContainer tc = TypeManager.LookupTypeContainer (t);
1476
1477                         if (tc != null)
1478                                 return tc.FindMembers (mt, bf, filter, criteria);
1479                         else
1480                                 return new MemberList (t.FindMembers (mt, bf, filter, criteria));
1481                 }
1482
1483                 //
1484                 // FindMethods will look for methods not only in the type `t', but in
1485                 // any interfaces implemented by the type.
1486                 //
1487                 public static MethodInfo [] FindMethods (Type t, BindingFlags bf,
1488                                                          MemberFilter filter, object criteria)
1489                 {
1490                         return null;
1491                 }
1492
1493                 /// <summary>
1494                 ///   Emits the values for the constants
1495                 /// </summary>
1496                 public void EmitConstants ()
1497                 {
1498                         if (constants != null)
1499                                 foreach (Const con in constants)
1500                                         con.EmitConstant (this);
1501                         return;
1502                 }
1503
1504                 /// <summary>
1505                 ///   Emits the code, this step is performed after all
1506                 ///   the types, enumerations, constructors
1507                 /// </summary>
1508                 public void Emit ()
1509                 {
1510                         if (instance_constructors != null)
1511                                 foreach (Constructor c in instance_constructors)
1512                                         c.Emit (this);
1513
1514                         if (default_static_constructor != null)
1515                                 default_static_constructor.Emit (this);
1516                         
1517                         if (methods != null)
1518                                 foreach (Method m in methods)
1519                                         m.Emit (this);
1520
1521                         if (operators != null)
1522                                 foreach (Operator o in operators)
1523                                         o.Emit (this);
1524
1525                         if (properties != null)
1526                                 foreach (Property p in properties)
1527                                         p.Emit (this);
1528
1529                         if (indexers != null){
1530                                 foreach (Indexer ix in indexers)
1531                                         ix.Emit (this);
1532                                 
1533                                 CustomAttributeBuilder cb = Interface.EmitDefaultMemberAttr (
1534                                         this, IndexerName, ModFlags, Location);
1535                                 TypeBuilder.SetCustomAttribute (cb);
1536                         }
1537                         
1538                         if (fields != null)
1539                                 foreach (Field f in fields)
1540                                         f.Emit (this);
1541
1542                         if (events != null){
1543                                 foreach (Event e in Events)
1544                                         e.Emit (this);
1545                         }
1546
1547                         if (Pending != null)
1548                                 if (Pending.VerifyPendingMethods ())
1549                                         return;
1550                         
1551                         Attribute.ApplyAttributes (ec, TypeBuilder, this, OptAttributes, Location);
1552
1553                         //
1554                         // Check for internal or private fields that were never assigned
1555                         //
1556                         if (fields != null && RootContext.WarningLevel >= 3) {
1557                                 foreach (Field f in fields) {
1558                                         if ((f.ModFlags & Modifiers.PUBLIC) != 0)
1559                                                 continue;
1560
1561                                         if (f.status == 0){
1562                                                 Report.Warning (
1563                                                         169, f.Location, "Private field " +
1564                                                         MakeName (f.Name) + " is never used");
1565                                                 continue;
1566                                         }
1567
1568                                         //
1569                                         // Only report 649 on level 4
1570                                         //
1571                                         if (RootContext.WarningLevel < 4)
1572                                                 continue;
1573
1574                                         if ((f.status & Field.Status.ASSIGNED) != 0)
1575                                                 continue;
1576
1577                                         Report.Warning (
1578                                                 649, f.Location,
1579                                                 "Field " + MakeName (f.Name) + " is never assigned " +
1580                                                 " to and will always have its default value");
1581                                 }
1582                         }
1583                         
1584 //                      if (types != null)
1585 //                              foreach (TypeContainer tc in types)
1586 //                                      tc.Emit ();
1587                 }
1588                 
1589                 public override void CloseType ()
1590                 {
1591                         try {
1592                                 if (!Created){
1593                                         Created = true;
1594                                         TypeBuilder.CreateType ();
1595                                 }
1596                         } catch (TypeLoadException){
1597                                 //
1598                                 // This is fine, the code still created the type
1599                                 //
1600 //                              Report.Warning (-20, "Exception while creating class: " + TypeBuilder.Name);
1601 //                              Console.WriteLine (e.Message);
1602                         } catch {
1603                                 Console.WriteLine ("In type: " + Name);
1604                                 throw;
1605                         }
1606                         
1607                         if (Enums != null)
1608                                 foreach (Enum en in Enums)
1609                                         en.CloseType ();
1610
1611                         if (interface_order != null){
1612                                 foreach (Interface iface in interface_order)
1613                                         iface.CloseType ();
1614                         }
1615                         
1616                         if (Types != null){
1617                                 foreach (TypeContainer tc in Types)
1618                                         if (tc is Struct)
1619                                                 tc.CloseType ();
1620
1621                                 foreach (TypeContainer tc in Types)
1622                                         if (!(tc is Struct))
1623                                                 tc.CloseType ();
1624                         }
1625
1626                         if (Delegates != null)
1627                                 foreach (Delegate d in Delegates)
1628                                         d.CloseType ();
1629                 }
1630
1631                 public string MakeName (string n)
1632                 {
1633                         return "`" + Name + "." + n + "'";
1634                 }
1635
1636                 public void Warning_KeywordShadowsRequired (Location l, MemberInfo mi)
1637                 {
1638                         Report.Warning (
1639                                 108, l, "The keyword 'Shadows' is required on " + 
1640                                 MakeName (mi.Name) + " because it shadows `" +
1641                                 mi.ReflectedType.Name + "." + mi.Name + "'");
1642                 }
1643
1644                 public void Warning_KewywordShadowsNotRequired (Location l, MemberCore mc)
1645                 {
1646                         Report.Warning (
1647                                 109, l, "The member " + MakeName (mc.Name) + " does not hide an " +
1648                                 "inherited member, the keyword shadows is not required");
1649                 }
1650
1651                 public void Warning_KewywordNewNotRequired (Location l, MemberCore mc)
1652                 {
1653                         Report.Warning (
1654                                 109, l, "The member " + MakeName (mc.Name) + " does not hide an " +
1655                                 "inherited member, the keyword new is not required");
1656                 }
1657                 
1658                 public static int CheckMember (string name, MemberInfo mi, int ModFlags)
1659                 {
1660                         return 0;
1661                 }
1662
1663                 //
1664                 // Performs the validation on a Method's modifiers (properties have
1665                 // the same properties).
1666                 //
1667                 public bool MethodModifiersValid (int flags, string n, Location loc)
1668                 {
1669                         const int vao = (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE);
1670                         const int va = (Modifiers.VIRTUAL | Modifiers.ABSTRACT);
1671                         const int nv = (Modifiers.SHADOWS | Modifiers.VIRTUAL);
1672                         bool ok = true;
1673                         string name = MakeName (n);
1674                         
1675                         //
1676                         // At most one of static, virtual or override
1677                         //
1678                         if ((flags & Modifiers.STATIC) != 0){
1679                                 if ((flags & vao) != 0){
1680                                         Report.Error (
1681                                                 30501, loc, "Shared method " + name + " can not be " +
1682                                                 "declared as Overridable");
1683                                         ok = false;
1684                                 }
1685                         }
1686
1687                         if (this is Struct){
1688                                 if ((flags & va) != 0){
1689                                         Modifiers.Error_InvalidModifier (loc, "virtual or abstract");
1690                                         ok = false;
1691                                 }
1692                         }
1693
1694                         if ((flags & Modifiers.OVERRIDE) != 0 && (flags & Modifiers.VIRTUAL) != 0)\r
1695                         {
1696                                 Report.Error (
1697                                         30730, loc, name +
1698                                         ": Methods marked as Overrides cannot be made Overridable");
1699                                 ok = false;
1700                         }
1701
1702                         if ((flags & Modifiers.OVERRIDE) != 0 && (flags & Modifiers.SHADOWS) != 0){
1703                                 Report.Error (
1704                                         31408, loc, name +
1705                                         ": Methods marked as Overrides cannot be marked as Shadows");
1706                                 ok = false;
1707                         }
1708
1709                         //
1710                         // If the declaration includes the abstract modifier, then the
1711                         // declaration does not include static, virtual or extern
1712                         //
1713                         if ((flags & Modifiers.ABSTRACT) != 0){
1714                                 if ((flags & Modifiers.EXTERN) != 0){
1715                                         Report.Error (
1716                                                 180, loc, name + " can not be both abstract and extern");
1717                                         ok = false;
1718                                 }
1719
1720                                 if ((flags & Modifiers.VIRTUAL) != 0){
1721                                         Report.Error (
1722                                                 503, loc, name + " can not be both abstract and virtual");
1723                                         ok = false;
1724                                 }
1725
1726                                 if((ModFlags & Modifiers.SEALED) != 0){
1727                                         Report.Error (
1728                                                 30607, loc, 
1729                                                 "Class declared as 'NotInheritable' " +
1730                                                 "cannot have a 'MustOverride' member");
1731                                         ok = false;
1732                                 }
1733                                 else if ((ModFlags & Modifiers.ABSTRACT) == 0){
1734                                         Report.Error (
1735                                                 31411, loc, name +
1736                                                 " is declared as 'MustOverride', hence its container " +
1737                                                 "class should be declared as 'MustInherit'");
1738                                         ok = false;
1739
1740                                 }
1741                         }
1742
1743                         if ((flags & Modifiers.PRIVATE) != 0){
1744                                 if ((flags & vao) != 0){
1745                                         Report.Error (
1746                                                 31408, loc, name +
1747                                                 ": Members marked as Overridable or Overrides can not be Private");
1748                                         ok = false;
1749                                 }
1750                         }
1751
1752                         if ((flags & Modifiers.SEALED) != 0){
1753                                 if ((flags & Modifiers.OVERRIDE) == 0){
1754                                         Report.Error (
1755                                                 238, loc, name +
1756                                                 ": cannot be sealed because it is not an override");
1757                                         ok = false;
1758                                 }
1759                         }
1760                         if ((flags & Modifiers.NEW) != 0){
1761                                 if ((flags & Modifiers.SHADOWS) != 0){
1762                                         Report.Error (
1763                                                 31408, loc, 
1764                                                 " 'Overloads' and 'Shadows' cannot be combined ");
1765                                         ok = false;
1766                                 }
1767                         }
1768
1769                         return ok;
1770                 }
1771
1772                 // Access level of a type.
1773                 enum AccessLevel {
1774                         Public                  = 0,
1775                         ProtectedInternal       = 1,
1776                         Internal                = 2,
1777                         Protected               = 3,
1778                         Private                 = 4
1779                 }
1780
1781                 // Check whether `flags' denotes a more restricted access than `level'
1782                 // and return the new level.
1783                 static AccessLevel CheckAccessLevel (AccessLevel level, int flags)
1784                 {
1785                         AccessLevel old_level = level;
1786
1787                         if ((flags & Modifiers.INTERNAL) != 0) {
1788                                 if ((flags & Modifiers.PROTECTED) != 0) {
1789                                         if ((int) level < (int) AccessLevel.ProtectedInternal)
1790                                                 level = AccessLevel.ProtectedInternal;
1791                                 } else {
1792                                         if ((int) level < (int) AccessLevel.Internal)
1793                                                 level = AccessLevel.Internal;
1794                                 }
1795                         } else if ((flags & Modifiers.PROTECTED) != 0) {
1796                                 if ((int) level < (int) AccessLevel.Protected)
1797                                         level = AccessLevel.Protected;
1798                         } else if ((flags & Modifiers.PRIVATE) != 0)
1799                                 level = AccessLevel.Private;
1800
1801                         return level;
1802                 }
1803
1804                 // Return the access level for a new member which is defined in the current
1805                 // TypeContainer with access modifiers `flags'.
1806                 AccessLevel GetAccessLevel (int flags)
1807                 {
1808                         if ((flags & Modifiers.PRIVATE) != 0)
1809                                 return AccessLevel.Private;
1810
1811                         AccessLevel level;
1812                         if (!IsTopLevel && (Parent != null))
1813                                 level = Parent.GetAccessLevel (flags);
1814                         else
1815                                 level = AccessLevel.Public;
1816
1817                         return CheckAccessLevel (CheckAccessLevel (level, flags), ModFlags);
1818                 }
1819
1820                 // Return the access level for type `t', but don't give more access than `flags'.
1821                 static AccessLevel GetAccessLevel (Type t, int flags)
1822                 {
1823                         if (((flags & Modifiers.PRIVATE) != 0) || t.IsNestedPrivate)
1824                                 return AccessLevel.Private;
1825
1826                         AccessLevel level;
1827                         if (TypeManager.IsBuiltinType (t))
1828                                 return AccessLevel.Public;
1829                         else if ((t.DeclaringType != null) && (t != t.DeclaringType))
1830                                 level = GetAccessLevel (t.DeclaringType, flags);
1831                         else {
1832                                 level = CheckAccessLevel (AccessLevel.Public, flags);
1833                         }
1834
1835                         if (t.IsNestedPublic)
1836                                 return level;
1837
1838                         if (t.IsNestedAssembly || t.IsNotPublic) {
1839                                 if ((int) level < (int) AccessLevel.Internal)
1840                                         level = AccessLevel.Internal;
1841                         }
1842
1843                         if (t.IsNestedFamily) {
1844                                 if ((int) level < (int) AccessLevel.Protected)
1845                                         level = AccessLevel.Protected;
1846                         }
1847
1848                         if (t.IsNestedFamORAssem) {
1849                                 if ((int) level < (int) AccessLevel.ProtectedInternal)
1850                                         level = AccessLevel.ProtectedInternal;
1851                         }
1852
1853                         return level;
1854                 }
1855
1856                 //
1857                 // Returns true if `parent' is as accessible as the flags `flags'
1858                 // given for this member.
1859                 //
1860                 public bool AsAccessible (Type parent, int flags)
1861                 {
1862                         while (parent.IsArray || parent.IsPointer || parent.IsByRef)
1863                                 parent = parent.GetElementType ();
1864
1865                         AccessLevel level = GetAccessLevel (flags);
1866                         AccessLevel level2 = GetAccessLevel (parent, flags);
1867
1868                         return (int) level >= (int) level2;
1869                 }
1870
1871                 Hashtable builder_and_args;
1872                 
1873                 public bool RegisterMethod (MethodBuilder mb, InternalParameters ip, Type [] args)
1874                 {
1875                         if (builder_and_args == null)
1876                                 builder_and_args = new Hashtable ();
1877                         return true;
1878                 }
1879
1880                 /// <summary>
1881                 ///   Performs checks for an explicit interface implementation.  First it
1882                 ///   checks whether the `interface_type' is a base inteface implementation.
1883                 ///   Then it checks whether `name' exists in the interface type.
1884                 /// </summary>
1885                 public bool VerifyImplements (Type interface_type, string full, string name, Location loc)
1886                 {
1887                         bool found = false;
1888
1889                         if (ifaces != null){
1890                                 foreach (Type t in ifaces){
1891                                         if (t == interface_type){
1892                                                 found = true;
1893                                                 break;
1894                                         }
1895                                 }
1896                         }
1897                         
1898                         if (!found){
1899                                 Report.Error (540, "`" + full + "': containing class does not implement interface `" + interface_type.FullName + "'");
1900                                 return false;
1901                         }
1902
1903                         return true;
1904                 }
1905
1906                 public static void Error_ExplicitInterfaceNotMemberInterface (Location loc, string name)
1907                 {
1908                         Report.Error (539, loc, "Explicit implementation: `" + name + "' is not a member of the interface");
1909                 }
1910
1911                 //
1912                 // IMemberContainer
1913                 //
1914
1915                 string IMemberContainer.Name {
1916                         get {
1917                                 return Name;
1918                         }
1919                 }
1920
1921                 Type IMemberContainer.Type {
1922                         get {
1923                                 return TypeBuilder;
1924                         }
1925                 }
1926
1927                 IMemberContainer IMemberContainer.Parent {
1928                         get {
1929                                 return parent_container;
1930                         }
1931                 }
1932
1933                 MemberCache IMemberContainer.MemberCache {
1934                         get {
1935                                 return member_cache;
1936                         }
1937                 }
1938
1939                 bool IMemberContainer.IsInterface {
1940                         get {
1941                                 return false;
1942                         }
1943                 }
1944
1945                 MemberList IMemberContainer.GetMembers (MemberTypes mt, BindingFlags bf)
1946                 {
1947                         return FindMembers (mt, bf | BindingFlags.DeclaredOnly, null, null);
1948                 }
1949
1950                 //
1951                 // Operator pair checking
1952                 //
1953
1954                 class OperatorEntry {
1955                         public int flags;
1956                         public Type ret_type;
1957                         public Type type1, type2;
1958                         public Operator op;
1959                         public Operator.OpType ot;
1960                         
1961                         public OperatorEntry (int f, Operator o)
1962                         {
1963                                 flags = f;
1964
1965                                 ret_type = o.OperatorMethod.GetReturnType ();
1966                                 Type [] pt = o.OperatorMethod.ParameterTypes;
1967                                 type1 = pt [0];
1968                                 type2 = pt [1];
1969                                 op = o;
1970                                 ot = o.OperatorType;
1971                         }
1972
1973                         public override int GetHashCode ()
1974                         {       
1975                                 return ret_type.GetHashCode ();
1976                         }
1977
1978                         public override bool Equals (object o)
1979                         {
1980                                 OperatorEntry other = (OperatorEntry) o;
1981
1982                                 if (other.ret_type != ret_type)
1983                                         return false;
1984                                 if (other.type1 != type1)
1985                                         return false;
1986                                 if (other.type2 != type2)
1987                                         return false;
1988                                 return true;
1989                         }
1990                 }
1991                                 
1992                 //
1993                 // Checks that some operators come in pairs:
1994                 //  == and !=
1995                 // > and <
1996                 // >= and <=
1997                 //
1998                 // They are matched based on the return type and the argument types
1999                 //
2000                 void CheckPairedOperators ()
2001                 {
2002                         Hashtable pairs = new Hashtable (null, null);
2003
2004                         // Register all the operators we care about.
2005                         foreach (Operator op in operators){
2006                                 int reg = 0;
2007                                 
2008                                 switch (op.OperatorType){
2009                                 case Operator.OpType.Equality:
2010                                         reg = 1; break;
2011                                 case Operator.OpType.Inequality:
2012                                         reg = 2; break;
2013                                         
2014                                 case Operator.OpType.GreaterThan:
2015                                         reg = 1; break;
2016                                 case Operator.OpType.LessThan:
2017                                         reg = 2; break;
2018                                         
2019                                 case Operator.OpType.GreaterThanOrEqual:
2020                                         reg = 1; break;
2021                                 case Operator.OpType.LessThanOrEqual:
2022                                         reg = 2; break;
2023                                 }
2024                                 if (reg == 0)
2025                                         continue;
2026
2027                                 OperatorEntry oe = new OperatorEntry (reg, op);
2028
2029                                 object o = pairs [oe];
2030                                 if (o == null)
2031                                         pairs [oe] = oe;
2032                                 else {
2033                                         oe = (OperatorEntry) o;
2034                                         oe.flags |= reg;
2035                                 }
2036                         }
2037
2038                         //
2039                         // Look for the mistakes.
2040                         //
2041                         foreach (DictionaryEntry de in pairs){
2042                                 OperatorEntry oe = (OperatorEntry) de.Key;
2043
2044                                 if (oe.flags == 3)
2045                                         continue;
2046
2047                                 string s = "";
2048                                 switch (oe.ot){
2049                                 case Operator.OpType.Equality:
2050                                         s = "!=";
2051                                         break;
2052                                 case Operator.OpType.Inequality: 
2053                                         s = "==";
2054                                         break;
2055                                 case Operator.OpType.GreaterThan: 
2056                                         s = "<";
2057                                         break;
2058                                 case Operator.OpType.LessThan:
2059                                         s = ">";
2060                                         break;
2061                                 case Operator.OpType.GreaterThanOrEqual:
2062                                         s = "<=";
2063                                         break;
2064                                 case Operator.OpType.LessThanOrEqual:
2065                                         s = ">=";
2066                                         break;
2067                                 }
2068                                 Report.Error (216, oe.op.Location,
2069                                               "The operator `" + oe.op + "' requires a matching operator `" + s + "' to also be defined");
2070                         }
2071                 }
2072                 
2073                 
2074         }
2075
2076         public class Class : TypeContainer {
2077                 // <summary>
2078                 //   Modifiers allowed in a class declaration
2079                 // </summary>
2080                 public const int AllowedModifiers =
2081                         Modifiers.NEW |
2082                         Modifiers.PUBLIC |
2083                         Modifiers.PROTECTED |
2084                         Modifiers.INTERNAL |
2085                         Modifiers.PRIVATE |
2086                         Modifiers.ABSTRACT |
2087                         Modifiers.SEALED ;
2088                 
2089                 public Class (TypeContainer parent, string name, int mod, Attributes attrs, Location l)
2090                         : base (parent, name, l)
2091                 {
2092                         int accmods;
2093
2094                         if (parent.Parent == null)
2095                                 accmods = Modifiers.INTERNAL;
2096                         else
2097                                 accmods = Modifiers.PUBLIC;
2098
2099                         this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
2100                         this.attributes = attrs;
2101                 }
2102
2103                 //
2104                 // FIXME: How do we deal with the user specifying a different
2105                 // layout?
2106                 //
2107                 public override TypeAttributes TypeAttr {
2108                         get {
2109                                 return base.TypeAttr | TypeAttributes.AutoLayout | TypeAttributes.Class;
2110                         }
2111                 }
2112         }
2113
2114         public class Struct : TypeContainer {
2115                 // <summary>
2116                 //   Modifiers allowed in a struct declaration
2117                 // </summary>
2118                 public const int AllowedModifiers =
2119                         Modifiers.NEW       |
2120                         Modifiers.PUBLIC    |
2121                         Modifiers.PROTECTED |
2122                         Modifiers.INTERNAL  |
2123                         Modifiers.UNSAFE    |
2124                         Modifiers.PRIVATE;
2125
2126                 public Struct (TypeContainer parent, string name, int mod, Attributes attrs, Location l)
2127                         : base (parent, name, l)
2128                 {
2129                         int accmods;
2130                         
2131                         if (parent.Parent == null)
2132                                 accmods = Modifiers.INTERNAL;
2133                         else
2134                                 accmods = Modifiers.PUBLIC;
2135                         
2136                         this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
2137
2138                         this.ModFlags |= Modifiers.SEALED;
2139                         this.attributes = attrs;
2140                         
2141                 }
2142
2143                 //
2144                 // FIXME: Allow the user to specify a different set of attributes
2145                 // in some cases (Sealed for example is mandatory for a class,
2146                 // but what SequentialLayout can be changed
2147                 //
2148                 public override TypeAttributes TypeAttr {
2149                         get {
2150                                 return base.TypeAttr |
2151                                         TypeAttributes.SequentialLayout |
2152                                         TypeAttributes.Sealed |
2153                                         TypeAttributes.BeforeFieldInit;
2154                         }
2155                 }
2156         }
2157
2158         public abstract class MethodCore : MemberBase {
2159                 public /* readonly */ Parameters Parameters;
2160                 Block block;
2161                 
2162                 //
2163                 // Parameters, cached for semantic analysis.
2164                 //
2165                 protected InternalParameters parameter_info;
2166                 protected Type [] parameter_types;
2167
2168                 public MethodCore (Expression type, int mod, int allowed_mod, string name,
2169                                    Attributes attrs, Parameters parameters, Location loc)
2170                         : base (type, mod, allowed_mod, name, attrs, loc)
2171                 {
2172                         Parameters = parameters;
2173                 }
2174                 
2175                 //
2176                 //  Returns the System.Type array for the parameters of this method
2177                 //
2178                 public Type [] ParameterTypes {
2179                         get {
2180                                 return parameter_types;
2181                         }
2182                 }
2183
2184                 public InternalParameters ParameterInfo
2185                 {
2186                         get {
2187                                 return parameter_info;
2188                         }
2189                 }
2190                 
2191                 public Block Block {
2192                         get {
2193                                 return block;
2194                         }
2195
2196                         set {
2197                                 block = value;
2198                         }
2199                 }
2200
2201                 protected virtual bool DoDefineParameters (TypeContainer parent)
2202                 {
2203                         // Check if arguments were correct
2204                         parameter_types = Parameters.GetParameterInfo (parent);
2205                         if ((parameter_types == null) || !CheckParameters (parent, parameter_types))
2206                                 return false;
2207
2208                         parameter_info = new InternalParameters (parent, Parameters);
2209
2210                         return true;
2211                 }
2212
2213                 public CallingConventions GetCallingConvention (bool is_class)
2214                 {
2215                         CallingConventions cc = 0;
2216                         
2217                         cc = Parameters.GetCallingConvention ();
2218
2219                         if (is_class)
2220                                 if ((ModFlags & Modifiers.STATIC) == 0)
2221                                         cc |= CallingConventions.HasThis;
2222
2223                         // FIXME: How is `ExplicitThis' used in C#?
2224                         
2225                         return cc;
2226                 }
2227
2228                 public void LabelParameters (EmitContext ec, Type [] parameters, MethodBase builder)
2229                 {
2230                         LabelParameters (ec, parameters, builder, null);
2231                 }
2232
2233                 public void LabelParameters (EmitContext ec, Type [] parameters, MethodBase builder, Parameters p_params)
2234                 {
2235                         //
2236                         // Define each type attribute (in/out/ref) and
2237                         // the argument names.
2238                         //
2239                         Parameter [] p = p_params == null ? Parameters.FixedParameters : p_params.FixedParameters;
2240                         int i = 0;
2241                         
2242                         MethodBuilder mb = null;
2243                         ConstructorBuilder cb = null;
2244
2245                         if (builder is MethodBuilder)
2246                                 mb = (MethodBuilder) builder;
2247                         else
2248                                 cb = (ConstructorBuilder) builder;
2249
2250                         if (p != null){
2251                                 for (i = 0; i < p.Length; i++) {
2252                                         ParameterBuilder pb;
2253                                         
2254                                         if (mb == null)
2255                                                 pb = cb.DefineParameter (
2256                                                         i + 1, p [i].Attributes, p [i].Name);
2257                                         else 
2258                                                 pb = mb.DefineParameter (
2259                                                         i + 1, p [i].Attributes, p [i].Name);
2260                                         
2261                                         Attributes attr = p [i].OptAttributes;
2262                                         if (attr != null)
2263                                                 Attribute.ApplyAttributes (ec, pb, pb, attr, Location);
2264                                 }
2265                         }
2266
2267                         if (Parameters.ArrayParameter != null){
2268                                 ParameterBuilder pb;
2269                                 Parameter array_param = Parameters.ArrayParameter;
2270                                 
2271                                 if (mb == null)
2272                                         pb = cb.DefineParameter (
2273                                                 i + 1, array_param.Attributes,
2274                                                 array_param.Name);
2275                                 else
2276                                         pb = mb.DefineParameter (
2277                                                 i + 1, array_param.Attributes,
2278                                                 array_param.Name);
2279                                         
2280                                 CustomAttributeBuilder a = new CustomAttributeBuilder (
2281                                         TypeManager.cons_param_array_attribute, new object [0]);
2282                                 
2283                                 pb.SetCustomAttribute (a);
2284                         }
2285                 }
2286         }
2287         
2288         public class Method : MethodCore {
2289                 public MethodBuilder MethodBuilder;
2290                 public MethodData MethodData;
2291
2292                 /// <summary>
2293                 ///   Modifiers allowed in a class declaration
2294                 /// </summary>
2295                 const int AllowedModifiers =
2296                         Modifiers.NEW |
2297                         Modifiers.PUBLIC |
2298                         Modifiers.PROTECTED |
2299                         Modifiers.INTERNAL |
2300                         Modifiers.PRIVATE |
2301                         Modifiers.STATIC |
2302                         Modifiers.VIRTUAL |
2303                         Modifiers.NONVIRTUAL |
2304                         Modifiers.OVERRIDE |
2305                         Modifiers.ABSTRACT |
2306                         Modifiers.UNSAFE |
2307                         Modifiers.EXTERN|
2308                         Modifiers.SHADOWS;
2309
2310                 //
2311                 // return_type can be "null" for VOID values.
2312                 //
2313                 public Method (Expression return_type, int mod, string name, Parameters parameters,
2314                                Attributes attrs, Location l)
2315                         : base (return_type, mod, AllowedModifiers, name, attrs, parameters, l)
2316                 { 
2317                         Implements = null;
2318                 }
2319
2320                 public Method (Expression return_type, int mod, string name, Parameters parameters,
2321                         Attributes attrs, Expression impl_what, Location l)
2322                         : base (return_type, mod, AllowedModifiers, name, attrs, parameters, l)
2323                 { 
2324                         Implements = impl_what;
2325                 }
2326
2327                 //
2328                 // Returns the `System.Type' for the ReturnType of this
2329                 // function.  Provides a nice cache.  (used between semantic analysis
2330                 // and actual code generation
2331                 //
2332                 public Type GetReturnType ()
2333                 {
2334                         return MemberType;
2335                 }
2336
2337                 // Whether this is an operator method.
2338                 public bool IsOperator;
2339
2340                 void DuplicateEntryPoint (MethodInfo b, Location location)
2341                 {
2342                         Report.Error (
2343                                 30738, location,
2344                                 "Program `" + CodeGen.FileName +
2345                                 "'  has more than one entry point defined: `" +
2346                                 TypeManager.MonoBASIC_Signature(b) + "'");
2347                 }
2348
2349                 void Report28 (MethodInfo b)
2350                 {
2351                         if (RootContext.WarningLevel < 4) 
2352                                 return;
2353                                 
2354                         Report.Warning (
2355                                 28, Location,
2356                                 "`" + TypeManager.MonoBASIC_Signature(b) +
2357                                 "' has the wrong signature to be an entry point");
2358                 }
2359
2360                 public bool IsEntryPoint (MethodBuilder b, InternalParameters pinfo)
2361                 {
2362                         if (b.ReturnType != TypeManager.void_type &&
2363                             b.ReturnType != TypeManager.int32_type)
2364                                 return false;
2365
2366                         if (pinfo.Count == 0)
2367                                 return true;
2368
2369                         if (pinfo.Count > 1)
2370                                 return false;
2371
2372                         Type t = pinfo.ParameterType(0);
2373                         if (t.IsArray &&
2374                             (t.GetArrayRank() == 1) &&
2375                             (t.GetElementType() == TypeManager.string_type) &&
2376                             (pinfo.ParameterModifier(0) == Parameter.Modifier.NONE))
2377                                 return true;
2378                         else
2379                                 return false;
2380                 }
2381
2382                 //
2383                 // Checks our base implementation if any
2384                 //
2385                 protected override bool CheckBase (TypeContainer parent)
2386                 {
2387                         // Check whether arguments were correct.
2388                         if (!DoDefineParameters (parent))
2389                                 return false;
2390
2391                         MethodSignature ms = new MethodSignature (Name, null, ParameterTypes);
2392                         if (!IsOperator) {
2393                                 MemberList mi_this;
2394
2395                                 mi_this = TypeContainer.FindMembers (
2396                                         parent.TypeBuilder, MemberTypes.Method,
2397                                         BindingFlags.NonPublic | BindingFlags.Public |
2398                                         BindingFlags.Static | BindingFlags.Instance |
2399                                         BindingFlags.DeclaredOnly,
2400                                         MethodSignature.method_signature_filter, ms);
2401
2402                                 if (mi_this.Count > 0) {
2403                                         Report.Error (111, Location, "Class `" + parent.Name + "' " +
2404                                                       "already defines a member called `" + Name + "' " +
2405                                                       "with the same parameter types");
2406                                         return false;
2407                                 }
2408                         }
2409
2410                         //
2411                         // Verify if the parent has a type with the same name, and then
2412                         // check whether we have to create a new slot for it or not.
2413                         //
2414                         Type ptype = parent.TypeBuilder.BaseType;
2415
2416                         // ptype is only null for System.Object while compiling corlib.
2417                         if (ptype != null){
2418                                 MemberList mi, mi_static, mi_instance;
2419
2420                                 mi_static = TypeContainer.FindMembers (
2421                                         ptype, MemberTypes.Method,
2422                                         BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static,
2423                                         MethodSignature.inheritable_method_signature_filter, ms);
2424
2425                                 mi_instance = TypeContainer.FindMembers (
2426                                         ptype, MemberTypes.Method,
2427                                         BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance,
2428                                         MethodSignature.inheritable_method_signature_filter,
2429                                         ms);
2430
2431                                 if (mi_instance.Count > 0){
2432                                         mi = mi_instance;
2433                                 } else if (mi_static.Count > 0)
2434                                         mi = mi_static;
2435                                 else
2436                                         mi = null;
2437
2438                                 if (mi != null && mi.Count > 0){
2439                                         parent_method = (MethodInfo) mi [0];
2440                                         string name = parent_method.DeclaringType.Name + "." +
2441                                                 parent_method.Name;
2442
2443                                         if (!CheckMethodAgainstBase (parent, flags, parent_method, name))
2444                                                 return false;
2445
2446                                         if ((ModFlags & Modifiers.NEW) == 0) {
2447                                                 Type parent_ret = TypeManager.TypeToCoreType (
2448                                                         parent_method.ReturnType);
2449
2450                                                 if (parent_ret != MemberType) {
2451                                                         Report.Error (
2452                                                                 508, parent.MakeName (Name) + ": cannot " +
2453                                                                 "change return type when overriding " +
2454                                                                 "inherited member " + name);
2455                                                         return false;
2456                                                 }
2457                                         }
2458                                 } else {
2459                                         /*if ((ModFlags & Modifiers.NEW) != 0)
2460                                                 WarningNotHiding (parent);*/
2461
2462                                         if ((ModFlags & Modifiers.OVERRIDE) != 0){
2463                                                 Report.Error (30284, Location,
2464                                                               parent.MakeName (Name) +
2465                                                               " : No suitable methods found to override");
2466                                         }
2467                                         if ((ModFlags & ( Modifiers.NEW | Modifiers.SHADOWS | Modifiers.OVERRIDE )) == 0) \r
2468                                         {
2469                                                 if ((ModFlags & Modifiers.NONVIRTUAL) != 0)\r
2470                                                 {
2471                                                         Report.Error (31088, Location,
2472                                                                 parent.MakeName (Name) + " : Cannot " +
2473                                                                 "be declared NotOverridable since this method is " +
2474                                                                 "not maked as Overrides");
2475                                                 }
2476                                         }
2477                                         // if a member of module is not inherited from Object class
2478                                         // can not be declared protected
2479                                         if ((parent is Module) && ((ModFlags & Modifiers.PROTECTED) != 0))
2480                                                 Report.Error (31066, Location,
2481                                                                 "'Sub' or 'Function' inside a 'Module' can not be declared as " +
2482                                                                 "'Protected' or 'Protected Friend'");
2483                                 }
2484                         }
2485                         /* else if ((ModFlags & Modifiers.NEW) != 0)
2486                                 WarningNotHiding (parent);
2487                         */
2488
2489                         return true;
2490                 }
2491
2492                 //
2493                 // Creates the type
2494                 //
2495                 public override bool Define (TypeContainer parent)
2496                 {
2497                         if (!DoDefine (parent))
2498                                 return false;
2499
2500                         if (!CheckBase (parent))
2501                                 return false;
2502
2503                         if ((parent is Struct) && ((ModFlags & Modifiers.PROTECTED) != 0))
2504                                 Report.Error (31067, Location,
2505                                         "'Sub' or 'Function' inside a 'Structure' can not be declared as " +
2506                                         "'Protected' or 'Protected Friend'");
2507
2508                         CallingConventions cc = GetCallingConvention (parent is Class);
2509
2510                         MethodData = new MethodData (this, null, MemberType, ParameterTypes,
2511                                                      ParameterInfo, cc, OptAttributes,
2512                                                      ModFlags, flags, true);
2513
2514                         if (!MethodData.Define (parent))
2515                                 return false;
2516
2517                         MethodBuilder = MethodData.MethodBuilder;
2518                         
2519                         //
2520                         // This is used to track the Entry Point,
2521                         //
2522                         if (Name.ToUpper() == "MAIN" &&
2523                             ((ModFlags & Modifiers.STATIC) != 0) && 
2524                             (RootContext.MainClass == null ||
2525                              RootContext.MainClass == parent.TypeBuilder.FullName ||
2526                              (RootContext.RootNamespace != null &&
2527                                   RootContext.RootNamespace.Length > 0 &&
2528                                   (RootContext.RootNamespace + "." + RootContext.MainClass) == parent.TypeBuilder.FullName))) {
2529                                 if (IsEntryPoint (MethodBuilder, ParameterInfo)) {
2530                                         if (RootContext.EntryPoint == null) {
2531                                                 RootContext.EntryPoint = MethodBuilder;
2532                                                 RootContext.EntryPointLocation = Location;
2533                                         } else {
2534                                                 DuplicateEntryPoint (RootContext.EntryPoint, RootContext.EntryPointLocation);
2535                                                 DuplicateEntryPoint (MethodBuilder, Location);
2536                                         }
2537                                 } else                                  
2538                                         Report28(MethodBuilder);
2539                         }
2540
2541                         return true;
2542                 }
2543
2544                 //
2545                 // Emits the code
2546                 // 
2547                 public void Emit (TypeContainer parent)
2548                 {
2549                         MethodData.Emit (parent, Block, this);
2550                 }
2551         }
2552
2553         public abstract class ConstructorInitializer {
2554                 ArrayList argument_list;
2555                 ConstructorInfo parent_constructor;
2556                 Parameters parameters;
2557                 Location loc;
2558                 public bool implicit_initialization;
2559                 
2560                 public ConstructorInitializer (ArrayList argument_list, Parameters parameters,
2561                                                Location loc)
2562                 {
2563                         this.argument_list = argument_list;
2564                         this.parameters = parameters;
2565                         this.loc = loc;
2566                         this.implicit_initialization = false;
2567                 }
2568
2569                 public ArrayList Arguments {
2570                         get {
2571                                 return argument_list;
2572                         }
2573                 }
2574
2575                 public ConstructorInfo ParentConstructor
2576                 {
2577                         get\r
2578                         {
2579                                 return parent_constructor;
2580                         }
2581                 }
2582         
2583                 public bool Resolve (EmitContext ec)
2584                 {
2585                         Expression parent_constructor_group;
2586                         Type t;
2587
2588                         ec.CurrentBlock = new Block (null, true, parameters);
2589
2590                         if (argument_list != null){
2591                                 foreach (Argument a in argument_list){
2592                                         if (!a.Resolve (ec, loc))
2593                                                 return false;
2594                                 }
2595                         }
2596
2597                         ec.CurrentBlock = null;
2598
2599                         if (this is ConstructorBaseInitializer) {
2600                                 if (ec.ContainerType.BaseType == null)
2601                                         return true;
2602
2603                                 t = ec.ContainerType.BaseType;
2604                                 if (ec.ContainerType.IsValueType){
2605                                         Report.Error (522, loc,
2606                                                 "structs cannot call base class constructors");
2607                                         return false;
2608                                 }
2609                         }\r
2610                         else
2611                                 t = ec.ContainerType;
2612                         
2613                         parent_constructor_group = Expression.MemberLookup (
2614                                 ec, t, t, ".ctor", 
2615                                 MemberTypes.Constructor,
2616                                 BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
2617                                 loc);
2618                         
2619                         if (parent_constructor_group == null){
2620                                 Report.Error (30455, loc, "Class '" + t + "' can not find a constructor for this argument list" );
2621                                 return false;
2622                         }
2623
2624                         parent_constructor = (ConstructorInfo) Invocation.OverloadResolve (ec, 
2625                                 (MethodGroupExpr) parent_constructor_group, argument_list, loc);
2626
2627                         if (parent_constructor == null) {
2628                                 if (this.implicit_initialization)
2629                                         Report.Error (30148, loc, "Must declare 'MyBase.New' in the constructor " +\r
2630                                         "of the class '" + ec.TypeContainer.Name + "' with appropriate arguments, since the base class '" +\r
2631                                                 t.FullName + "' does not contain a definition of 'New' without any parameter");
2632                                 else
2633                                         Report.Error (30455, loc, "Class '" + t + "' can not find a constructor for this argument list" );
2634
2635                                 return false;
2636                         }
2637
2638                         return true;
2639                 }
2640
2641                 public void Emit (EmitContext ec)
2642                 {
2643                         if (parent_constructor != null){
2644                                 if (ec.IsStatic)
2645                                         Invocation.EmitCall (ec, true, true, null, parent_constructor, argument_list, loc);
2646                                 else
2647                                         Invocation.EmitCall (ec, true, false, ec.This, parent_constructor, argument_list, loc);
2648                         }
2649                 }
2650
2651
2652         }
2653
2654         public class ConstructorBaseInitializer : ConstructorInitializer {
2655                 public ConstructorBaseInitializer (ArrayList argument_list, Parameters pars, Location l) :
2656                         base (argument_list, pars, l)
2657                 {
2658                 }
2659         }
2660
2661         public class ConstructorThisInitializer : ConstructorInitializer {
2662                 public ConstructorThisInitializer (ArrayList argument_list, Parameters pars, Location l) :
2663                         base (argument_list, pars, l)
2664                 {
2665                 }
2666         }
2667         
2668         public class Constructor : MethodCore {
2669                 public ConstructorBuilder ConstructorBuilder;
2670                 public ConstructorInitializer Initializer;
2671                 new public Attributes OptAttributes;
2672
2673                 // <summary>
2674                 //   Modifiers allowed for a constructor.
2675                 // </summary>
2676                 public const int AllowedModifiers =
2677                         Modifiers.PUBLIC |
2678                         Modifiers.PROTECTED |
2679                         Modifiers.INTERNAL |
2680                         Modifiers.STATIC |
2681                         Modifiers.UNSAFE |
2682                         Modifiers.EXTERN |              
2683                         Modifiers.PRIVATE;
2684
2685                 //
2686                 // The spec claims that static is not permitted, but
2687                 // my very own code has static constructors.
2688                 //
2689                 public Constructor (string name, Parameters args, ConstructorInitializer init, Location l)
2690                         : base (null, 0, AllowedModifiers, name, null, args, l)
2691                 {
2692                         Initializer = init;
2693                 }
2694
2695                 //
2696                 // Returns true if this is a default constructor
2697                 //
2698                 public bool IsDefault ()
2699                 {
2700                         if ((ModFlags & Modifiers.STATIC) != 0)
2701                                 return  (Parameters.FixedParameters == null ? true : Parameters.Empty) &&
2702                                         (Parameters.ArrayParameter == null ? true : Parameters.Empty);
2703                         
2704                         else
2705                                 return  (Parameters.FixedParameters == null ? true : Parameters.Empty) &&
2706                                         (Parameters.ArrayParameter == null ? true : Parameters.Empty) &&
2707                                         (Initializer is ConstructorBaseInitializer) &&
2708                                         (Initializer.Arguments == null);
2709                 }
2710
2711                 //
2712                 // Creates the ConstructorBuilder
2713                 //
2714                 public override bool Define (TypeContainer parent)
2715                 {
2716                         MethodAttributes ca = (MethodAttributes.RTSpecialName |
2717                                                MethodAttributes.SpecialName);
2718
2719                         // Check if arguments were correct.
2720                         if (!DoDefineParameters (parent))
2721                                 return false;
2722
2723                         if ((ModFlags & Modifiers.STATIC) != 0) {
2724                                 ca |= MethodAttributes.Static;
2725
2726                                 if (this.Parameters != Parameters.EmptyReadOnlyParameters)
2727                                         Report.Error (
2728                                                 30479, Location, 
2729                                                 "Shared constructor can not have parameters");
2730
2731                                 if ((ModFlags & Modifiers.Accessibility) != 0)
2732                                         Report.Error (
2733                                                 30480, Location, 
2734                                                 "Shared constructor can not be declared " +
2735                                                 "explicitly as public, private, friend or protected");
2736
2737                                 if (this.Initializer != null)
2738                                         Report.Error (
2739                                                 30043, Location, 
2740                                                 "Keywords like MyBase, MyClass, Me are not " +
2741                                                 "valid inside a Shared Constructor");
2742                         }
2743                         else {
2744                                 if (parent is Struct && ParameterTypes.Length == 0)     {
2745                                         Report.Error (
2746                                                 30629, Location, 
2747                                                 "Structs can not contain explicit parameterless " +
2748                                                 "constructors");
2749                                         return false;
2750                                 }
2751                                 ca |= MethodAttributes.HideBySig;
2752
2753                                 if ((ModFlags & Modifiers.PUBLIC) != 0)
2754                                         ca |= MethodAttributes.Public;
2755                                 else if ((ModFlags & Modifiers.PROTECTED) != 0) {
2756                                         if ((ModFlags & Modifiers.INTERNAL) != 0)
2757                                                 ca |= MethodAttributes.FamORAssem;
2758                                         else 
2759                                                 ca |= MethodAttributes.Family;
2760                                 }\r
2761                                 else if ((ModFlags & Modifiers.INTERNAL) != 0)
2762                                         ca |= MethodAttributes.Assembly;
2763                                 else if (IsDefault ())
2764                                         ca |= MethodAttributes.Public;
2765                                 else
2766                                         ca |= MethodAttributes.Private;
2767                         }
2768
2769                         ConstructorBuilder = parent.TypeBuilder.DefineConstructor (
2770                                 ca, GetCallingConvention (parent is Class), ParameterTypes);
2771
2772                         //
2773                         // HACK because System.Reflection.Emit is lame
2774                         //
2775                         if (!TypeManager.RegisterMethod (ConstructorBuilder, ParameterInfo, ParameterTypes)) {
2776                                 Report.Error (
2777                                         111, Location,
2778                                         "Class `" +parent.Name+ "' already contains a definition with the " +
2779                                         "same return value and parameter types for constructor `" + Name
2780                                         + "'");
2781                                 return false;
2782                         }
2783
2784                         return true;
2785                 }
2786
2787                 //
2788                 // Emits the code
2789                 //
2790                 public void Emit (TypeContainer parent)
2791                 {
2792                         ILGenerator ig = ConstructorBuilder.GetILGenerator ();
2793                         EmitContext ec = new EmitContext (parent, Location, ig, null, ModFlags, true);
2794
2795                         if ((ModFlags & Modifiers.STATIC) == 0){
2796                                 if (parent is Class && Initializer == null) {
2797                                         Initializer = new ConstructorBaseInitializer (
2798                                                 null, Parameters.EmptyReadOnlyParameters, parent.Location);
2799                                         Initializer.implicit_initialization = true;
2800                                 }
2801
2802                                 //
2803                                 // Spec mandates that Initializers will not have
2804                                 // `this' access
2805                                 //
2806                                 ec.IsStatic = true;
2807                                 if (Initializer != null && !Initializer.Resolve (ec))
2808                                         return;
2809                                 ec.IsStatic = false;
2810                         }
2811
2812                         LabelParameters (ec, ParameterTypes, ConstructorBuilder);
2813                         
2814                         //
2815                         // Classes can have base initializers and instance field initializers.
2816                         //
2817                         if (parent is Class){
2818                                 if ((ModFlags & Modifiers.STATIC) == 0)
2819                                         parent.EmitFieldInitializers (ec);
2820                         }
2821
2822                         if (Initializer != null) {
2823                                 if (this.ConstructorBuilder.Equals (Initializer.ParentConstructor))
2824                                         Report.Error (
2825                                                 30297, Location,
2826                                                 "A constructor can not call itself" );
2827
2828                                 Initializer.Emit (ec);
2829                         }
2830                         
2831                         if ((ModFlags & Modifiers.STATIC) != 0)
2832                                 parent.EmitFieldInitializers (ec);
2833
2834                         Attribute.ApplyAttributes (ec, ConstructorBuilder, this, OptAttributes, Location);
2835
2836                         // If this is a non-static `struct' constructor and doesn't have any
2837                         // initializer, it must initialize all of the struct's fields.
2838                         if ((parent is Struct) && ((ModFlags & Modifiers.STATIC) == 0) &&
2839                             (Initializer == null))
2840                                 Block.AddThisVariable (parent, Location);
2841
2842                         ec.EmitTopBlock (Block, ParameterInfo, Location);
2843                 }
2844         }
2845
2846         public class MethodData {
2847                 //
2848                 // The return type of this method
2849                 //
2850                 public readonly Type ReturnType;
2851                 public readonly Type[] ParameterTypes;
2852                 public readonly InternalParameters ParameterInfo;
2853                 public readonly CallingConventions CallingConventions;
2854                 public readonly Attributes OptAttributes;
2855                 public readonly Location Location;
2856
2857                 //
2858                 // Are we implementing an interface ?
2859                 //
2860                 public bool IsImplementing = false;
2861
2862                 //
2863                 // Protected data.
2864                 //
2865                 protected MemberBase member;
2866                 protected int modifiers;
2867                 protected MethodAttributes flags;
2868                 protected bool is_method;
2869                 protected string accessor_name;
2870                 ArrayList conditionals;
2871
2872                 MethodBuilder builder = null;
2873                 public MethodBuilder MethodBuilder {
2874                         get {
2875                                 return builder;
2876                         }
2877                 }
2878
2879                 public MethodData (MemberBase member, string name, Type return_type,
2880                                    Type [] parameter_types, InternalParameters parameters,
2881                                    CallingConventions cc, Attributes opt_attrs,
2882                                    int modifiers, MethodAttributes flags, bool is_method)
2883                 {
2884                         this.member = member;
2885                         this.accessor_name = name;
2886                         this.ReturnType = return_type;
2887                         this.ParameterTypes = parameter_types;
2888                         this.ParameterInfo = parameters;
2889                         this.CallingConventions = cc;
2890                         this.OptAttributes = opt_attrs;
2891                         this.modifiers = modifiers;
2892                         this.flags = flags;
2893                         this.is_method = is_method;
2894                         this.Location = member.Location;
2895                         this.conditionals = new ArrayList ();
2896                 }
2897
2898                 //
2899                 // Attributes.
2900                 //
2901                 Attribute dllimport_attribute = null;
2902                 string obsolete = null;
2903                 bool obsolete_error = false;
2904
2905                 public virtual bool ApplyAttributes (Attributes opt_attrs, bool is_method)
2906                 {
2907                         if ((opt_attrs == null) || (opt_attrs.AttributeSections == null))
2908                                 return true;
2909
2910                         foreach (AttributeSection asec in opt_attrs.AttributeSections) {
2911                                 if (asec.Attributes == null)
2912                                         continue;
2913                                         
2914                                 foreach (Attribute a in asec.Attributes) {
2915                                         if (a.Name == "Conditional") {
2916                                                 if (!ApplyConditionalAttribute (a))
2917                                                         return false;
2918                                         } else if (a.Name == "Obsolete") {
2919                                                 if (!ApplyObsoleteAttribute (a))
2920                                                         return false;
2921                                         } else if (a.Name.IndexOf ("DllImport") != -1) {
2922                                                 if (!is_method) {
2923                                                         a.Type = TypeManager.dllimport_type;
2924                                                         Attribute.Error_AttributeNotValidForElement (a, Location);
2925                                                         return false;
2926                                                 }
2927                                                 if (!ApplyDllImportAttribute (a))
2928                                                         return false;
2929                                         }
2930                                 }
2931                         }
2932
2933                         return true;
2934                 }
2935
2936                 //
2937                 // Applies the `DllImport' attribute to the method.
2938                 //
2939                 protected virtual bool ApplyDllImportAttribute (Attribute a)
2940                 {
2941                         const int extern_static = Modifiers.EXTERN | Modifiers.STATIC;
2942                         if ((modifiers & extern_static) != extern_static) {
2943                                 Report.Error (601, Location,
2944                                               "The DllImport attribute must be specified on a method " +
2945                                               "marked `static' and `extern'.");
2946                                 return false;
2947                         }
2948
2949                         flags |= MethodAttributes.PinvokeImpl;
2950                         dllimport_attribute = a;
2951                         return true;
2952                 }
2953
2954                 //
2955                 // Applies the `Obsolete' attribute to the method.
2956                 //
2957                 protected virtual bool ApplyObsoleteAttribute (Attribute a)
2958                 {
2959                         if (obsolete != null) {
2960                                 Report.Error (579, Location, "Duplicate `Obsolete' attribute");
2961                                 return false;
2962                         }
2963
2964                         obsolete = a.Obsolete_GetObsoleteMessage (out obsolete_error);
2965                         return obsolete != null;
2966                 }
2967
2968                 //
2969                 // Applies the `Conditional' attribute to the method.
2970                 //
2971                 protected virtual bool ApplyConditionalAttribute (Attribute a)
2972                 {
2973                         // The Conditional attribute is only valid on methods.
2974                         if (!is_method) {
2975                                 Attribute.Error_AttributeNotValidForElement (a, Location);
2976                                 return false;
2977                         }
2978
2979                         string condition = a.Conditional_GetConditionName ();
2980
2981                         if (condition == null)
2982                                 return false;
2983
2984                         if (ReturnType != TypeManager.void_type) {
2985                                 Report.Error (578, Location,
2986                                               "Conditional not valid on `" + member.Name + "' " +
2987                                               "because its return type is not void");
2988                                 return false;
2989                         }
2990
2991                         if ((modifiers & Modifiers.OVERRIDE) != 0) {
2992                                 Report.Error (243, Location,
2993                                               "Conditional not valid on `" + member.Name + "' " +
2994                                               "because it is an override method");
2995                                 return false;
2996                         }
2997
2998                         if (member.IsExplicitImpl) {
2999                                 Report.Error (577, Location,
3000                                               "Conditional not valid on `" + member.Name + "' " +
3001                                               "because it is an explicit interface implementation");
3002                                 return false;
3003                         }
3004
3005                         if (IsImplementing) {
3006                                 Report.Error (623, Location,
3007                                               "Conditional not valid on `" + member.Name + "' " +
3008                                               "because it is an interface method");
3009                                 return false;
3010                         }
3011
3012                         conditionals.Add (condition);
3013
3014                         return true;
3015                 }
3016
3017                 //
3018                 // Checks whether this method should be ignored due to its Conditional attributes.
3019                 //
3020                 bool ShouldIgnore (Location loc)
3021                 {
3022                         // When we're overriding a virtual method, we implicitly inherit the
3023                         // Conditional attributes from our parent.
3024                         if (member.ParentMethod != null) {
3025                                 TypeManager.MethodFlags flags = TypeManager.GetMethodFlags (
3026                                         member.ParentMethod, loc);
3027
3028                                 if ((flags & TypeManager.MethodFlags.ShouldIgnore) != 0)
3029                                         return true;
3030                         }
3031
3032                         foreach (string condition in conditionals)
3033                                 if (RootContext.AllDefines [condition] == null)
3034                                         return true;
3035
3036                         return false;
3037                 }
3038
3039                 //
3040                 // Returns the TypeManager.MethodFlags for this method.
3041                 // This emits an error 619 / warning 618 if the method is obsolete.
3042                 // In the former case, TypeManager.MethodFlags.IsObsoleteError is returned.
3043                 //
3044                 public virtual TypeManager.MethodFlags GetMethodFlags (Location loc)
3045                 {
3046                         TypeManager.MethodFlags flags = 0;
3047
3048                         if (obsolete != null) {
3049                                 if (obsolete_error) {
3050                                         Report.Error (619, loc, "Method `" + member.Name +
3051                                                       "' is obsolete: `" + obsolete + "'");
3052                                         return TypeManager.MethodFlags.IsObsoleteError;
3053                                 } else
3054                                         Report.Warning (618, loc, "Method `" + member.Name +
3055                                                         "' is obsolete: `" + obsolete + "'");
3056
3057                                 flags |= TypeManager.MethodFlags.IsObsolete;
3058                         }
3059
3060                         if (ShouldIgnore (loc))
3061                             flags |= TypeManager.MethodFlags.ShouldIgnore;
3062
3063                         return flags;
3064                 }
3065
3066                 public virtual bool Define (TypeContainer parent)
3067                 {
3068                         MethodInfo implementing = null;
3069                         string method_name, name, prefix;
3070
3071                         if (OptAttributes != null)
3072                                 if (!ApplyAttributes (OptAttributes, is_method))
3073                                         return false;
3074
3075                         if (member.IsExplicitImpl)
3076                                 prefix = member.InterfaceType.FullName + ".";
3077                         else
3078                                 prefix = "";
3079
3080                         if (accessor_name != null)
3081                                 name = accessor_name + "_" + member.ShortName;
3082                         else
3083                                 name = member.ShortName;
3084                         method_name = prefix + name;
3085
3086                         if (parent.Pending != null){
3087                                 if (member is Indexer)
3088                                         implementing = parent.Pending.IsInterfaceIndexer (
3089                                                 member.InterfaceType, ReturnType, ParameterTypes);
3090                                 else
3091                                         implementing = parent.Pending.IsInterfaceMethod (
3092                                                 member.InterfaceType, name, ReturnType, ParameterTypes);
3093
3094                                 if (member.InterfaceType != null && implementing == null){
3095                                         TypeContainer.Error_ExplicitInterfaceNotMemberInterface (
3096                                                 Location, name);
3097                                         return false;
3098                                 }
3099                         }
3100
3101                         //
3102                         // For implicit implementations, make sure we are public, for
3103                         // explicit implementations, make sure we are private.
3104                         //
3105                         if (implementing != null){
3106                                 //
3107                                 // Setting null inside this block will trigger a more
3108                                 // verbose error reporting for missing interface implementations
3109                                 //
3110                                 // The "candidate" function has been flagged already
3111                                 // but it wont get cleared
3112                                 //
3113                                 if (!member.IsExplicitImpl){
3114                                         //
3115                                         // We already catch different accessibility settings
3116                                         // so we just need to check that we are not private
3117                                         //
3118                                         if ((modifiers & Modifiers.PRIVATE) != 0)
3119                                                 implementing = null;
3120                                         
3121                                         //
3122                                         // Static is not allowed
3123                                         //
3124                                         if ((modifiers & Modifiers.STATIC) != 0)
3125                                                 implementing = null;
3126                                 } else {
3127                                         if ((modifiers & (Modifiers.PUBLIC | Modifiers.ABSTRACT | Modifiers.VIRTUAL)) != 0){
3128                                                 Modifiers.Error_InvalidModifier (Location, "public, virtual or abstract");
3129                                                 implementing = null;
3130                                         }
3131                                 }
3132                         }
3133                         
3134                         //
3135                         // If implementing is still valid, set flags
3136                         //
3137                         if (implementing != null){
3138                                 //
3139                                 // When implementing interface methods, set NewSlot.
3140                                 //
3141                                 if (implementing.DeclaringType.IsInterface)
3142                                         flags |= MethodAttributes.NewSlot;
3143
3144                                 flags |=
3145                                         MethodAttributes.Virtual |
3146                                         MethodAttributes.HideBySig;
3147
3148                                 // Get the method name from the explicit interface.
3149                                 if (member.InterfaceType != null) {
3150                                         name = implementing.Name;
3151                                         method_name = prefix + name;
3152                                 }
3153
3154                                 IsImplementing = true;
3155                         }
3156
3157                         //
3158                         // Create the MethodBuilder for the method
3159                         //
3160                         if ((flags & MethodAttributes.PinvokeImpl) != 0) {
3161                                 if ((modifiers & Modifiers.STATIC) == 0) {
3162                                         Report.Error (601, Location,
3163                                                       "The DllImport attribute must be specified on " +
3164                                                       "a method marked 'static' and 'extern'.");
3165                                         return false;
3166                                 }
3167                                 
3168                                 EmitContext ec = new EmitContext (
3169                                         parent, Location, null, ReturnType, modifiers);
3170                                 
3171                                 builder = dllimport_attribute.DefinePInvokeMethod (
3172                                         ec, parent.TypeBuilder, method_name, flags,
3173                                         ReturnType, ParameterTypes);
3174                         } else
3175                                 builder = parent.TypeBuilder.DefineMethod (
3176                                         method_name, flags, CallingConventions,
3177                                         ReturnType, ParameterTypes);
3178
3179                         if (builder == null)
3180                                 return false;
3181
3182                         if (IsImplementing) {
3183                                 //
3184                                 // clear the pending implemntation flag
3185                                 //
3186                                 if (member is Indexer) {
3187                                         parent.Pending.ImplementIndexer (
3188                                                 member.InterfaceType, builder, ReturnType,
3189                                                 ParameterTypes, true);
3190                                 } else
3191                                         parent.Pending.ImplementMethod (
3192                                                 member.InterfaceType, name, ReturnType,
3193                                                 ParameterTypes, member.IsExplicitImpl);
3194
3195                                 if (member.IsExplicitImpl)
3196                                         parent.TypeBuilder.DefineMethodOverride (
3197                                                 builder, implementing);
3198                         }
3199
3200                         if (!TypeManager.RegisterMethod (builder, ParameterInfo, ParameterTypes)) {
3201                                 Report.Error (111, Location,
3202                                               "Class `" + parent.Name +
3203                                               "' already contains a definition with the " +
3204                                               "same return value and parameter types as the " +
3205                                               "'get' method of property `" + member.Name + "'");
3206                                 return false;
3207                         }
3208
3209                         TypeManager.AddMethod (builder, this);
3210
3211                         return true;
3212                 }
3213
3214                 //
3215                 // Emits the code
3216                 // 
3217                 public virtual void Emit (TypeContainer parent, Block block, object kind)
3218                 {
3219                         ILGenerator ig;
3220                         EmitContext ec;
3221
3222                         if ((flags & MethodAttributes.PinvokeImpl) == 0)
3223                                 ig = builder.GetILGenerator ();
3224                         else
3225                                 ig = null;
3226
3227                         ec = new EmitContext (parent, Location, ig, ReturnType, modifiers);
3228
3229                         if (OptAttributes != null)
3230                                 Attribute.ApplyAttributes (ec, builder, kind, OptAttributes, Location);
3231
3232                         if (member is MethodCore)
3233                                 ((MethodCore) member).LabelParameters (ec, ParameterTypes, MethodBuilder);
3234
3235                         //
3236                         // abstract or extern methods have no bodies
3237                         //
3238                         if ((modifiers & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0){
3239                                 if (block == null)
3240                                         return;
3241
3242                                 //
3243                                 // abstract or extern methods have no bodies.
3244                                 //
3245                                 if ((modifiers & Modifiers.ABSTRACT) != 0)
3246                                         Report.Error (
3247                                                 500, Location, "Abstract method `" +
3248                                                 TypeManager.MonoBASIC_Signature (builder) +
3249                                                 "' can not have a body");
3250
3251                                 if ((modifiers & Modifiers.EXTERN) != 0)
3252                                         Report.Error (
3253                                                 179, Location, "External method `" +
3254                                                 TypeManager.MonoBASIC_Signature (builder) +
3255                                                 "' can not have a body");
3256
3257                                 return;
3258                         }
3259
3260                         //
3261                         // Methods must have a body unless they're extern or abstract
3262                         //
3263                         if (block == null) {
3264                                 Report.Error (
3265                                         501, Location, "Method `" +
3266                                         TypeManager.MonoBASIC_Signature (builder) +
3267                                         "' must declare a body since it is not marked " +
3268                                         "abstract or extern");
3269                                 return;
3270                         }
3271
3272                         //
3273                         // Handle destructors specially
3274                         //
3275                         // FIXME: This code generates buggy code
3276                         //
3277                         if (member.Name == "Finalize" && ReturnType == TypeManager.void_type)
3278                                 EmitDestructor (ec, block);
3279                         else {
3280                                 ISymbolWriter sw = CodeGen.SymbolWriter;
3281
3282                                 if ((sw != null) && !Location.IsNull (Location) &&
3283                                     !Location.IsNull (block.EndLocation)) {
3284                                         Location end = block.EndLocation;
3285                                         MethodToken token = MethodBuilder.GetToken ();
3286                                         sw.OpenMethod (new SymbolToken (token.Token));
3287                                         // Avoid error if we don't support debugging for the platform
3288                                         try {
3289                                                 sw.SetMethodSourceRange (Location.SymbolDocument,
3290                                                                          Location.Row, 0,
3291                                                                          end.SymbolDocument,
3292                                                                          end.Row, 0);
3293                                         } catch (Exception) {
3294                                         }
3295
3296                                         ec.EmitTopBlock (block, member.Name, ParameterInfo, Location);
3297
3298                                         sw.CloseMethod ();
3299                                 } else
3300                                         ec.EmitTopBlock (block, member.Name, ParameterInfo, Location);
3301                         }
3302                 }
3303
3304                 void EmitDestructor (EmitContext ec, Block block)
3305                 {
3306                         ILGenerator ig = ec.ig;
3307                         
3308                         Label finish = ig.DefineLabel ();
3309                         bool old_in_try = ec.InTry;
3310                         
3311                         ig.BeginExceptionBlock ();
3312                         ec.InTry = true;
3313                         ec.ReturnLabel = finish;
3314                         ec.HasReturnLabel = true;
3315                         ec.EmitTopBlock (block, null, Location);
3316                         ec.InTry = old_in_try;
3317                         
3318                         // ig.MarkLabel (finish);
3319                         bool old_in_finally = ec.InFinally;
3320                         ec.InFinally = true;
3321                         ig.BeginFinallyBlock ();
3322                         
3323                         if (ec.ContainerType.BaseType != null) {
3324                                 Expression member_lookup = Expression.MemberLookup (
3325                                         ec, ec.ContainerType.BaseType, ec.ContainerType.BaseType, "Finalize",
3326                                         MemberTypes.Method, Expression.AllBindingFlags, Location);
3327
3328                                 if (member_lookup != null){
3329                                         MethodGroupExpr parent_destructor = ((MethodGroupExpr) member_lookup);
3330                                 
3331                                         ig.Emit (OpCodes.Ldarg_0);
3332                                         ig.Emit (OpCodes.Call, (MethodInfo) parent_destructor.Methods [0]);
3333                                 }
3334                         }
3335                         ec.InFinally = old_in_finally;
3336                         
3337                         ig.EndExceptionBlock ();
3338                         //ig.MarkLabel (ec.ReturnLabel);
3339                         ig.Emit (OpCodes.Ret);
3340                 }
3341         }
3342
3343         abstract public class MemberBase : MemberCore {
3344                 public Expression Type;
3345                 public readonly Attributes OptAttributes;
3346                 public Expression Implements;
3347
3348                 protected MethodAttributes flags;
3349
3350                 //
3351                 // The "short" name of this property / indexer / event.  This is the
3352                 // name without the explicit interface.
3353                 //
3354                 public string ShortName;
3355
3356                 //
3357                 // The type of this property / indexer / event
3358                 //
3359                 public Type MemberType;
3360
3361                 //
3362                 // If true, this is an explicit interface implementation
3363                 //
3364                 public bool IsExplicitImpl = false;
3365
3366                 //
3367                 // The name of the interface we are explicitly implementing
3368                 //
3369                 public string ExplicitInterfaceName = null;
3370
3371                 //
3372                 // If true, the interface type we are explicitly implementing
3373                 //
3374                 public Type InterfaceType = null;
3375
3376                 //
3377                 // The method we're overriding if this is an override method.
3378                 //
3379                 protected MethodInfo parent_method = null;
3380                 public MethodInfo ParentMethod {
3381                         get {
3382                                 return parent_method;
3383                         }
3384                 }
3385
3386                 //
3387                 // The constructor is only exposed to our children
3388                 //
3389                 protected MemberBase (Expression type, int mod, int allowed_mod, string name,
3390                                       Attributes attrs, Location loc)
3391                         : base (name, loc)
3392                 {
3393                         Type = type;
3394                         ModFlags = Modifiers.Check (allowed_mod, mod, Modifiers.PUBLIC, loc);
3395                         OptAttributes = attrs;
3396                 }
3397
3398                 protected virtual bool CheckBase (TypeContainer parent)
3399                 {
3400                         return true;
3401                 }
3402
3403                 protected virtual bool CheckParameters (TypeContainer parent, Type [] parameters)
3404                 {
3405                         bool error = false;
3406
3407                         foreach (Type partype in parameters){
3408                                 if (partype.IsPointer && !UnsafeOK (parent))
3409                                         error = true;
3410
3411                                 if (parent.AsAccessible (partype, ModFlags))
3412                                         continue;
3413
3414                                 if (this is Indexer)
3415                                         Report.Error (55, Location,
3416                                                       "Inconsistent accessibility: parameter type `" +
3417                                                       TypeManager.MonoBASIC_Name (partype) + "' is less " +
3418                                                       "accessible than indexer `" + Name + "'");
3419                                 else
3420                                         Report.Error (51, Location,
3421                                                       "Inconsistent accessibility: parameter type `" +
3422                                                       TypeManager.MonoBASIC_Name (partype) + "' is less " +
3423                                                       "accessible than method `" + Name + "'");
3424                                 error = true;
3425                         }
3426
3427                         return !error;
3428                 }
3429
3430                 protected virtual bool DoDefine (TypeContainer parent)
3431                 {
3432                         if (Name == null)
3433                                 Name = "this";
3434
3435                         if (!parent.MethodModifiersValid (ModFlags, Name, Location))
3436                                 return false;
3437
3438                         flags = Modifiers.MethodAttr (ModFlags);
3439
3440                         // Lookup Type, verify validity
3441                         MemberType = parent.ResolveType (Type, false, Location);
3442                         if (MemberType == null)
3443                                 return false;
3444
3445                         // verify accessibility
3446                         if (!parent.AsAccessible (MemberType, ModFlags)) {
3447                                 if (this is Property)
3448                                         Report.Error (53, Location,
3449                                                       "Inconsistent accessibility: property type `" +
3450                                                       TypeManager.MonoBASIC_Name (MemberType) + "' is less " +
3451                                                       "accessible than property `" + Name + "'");
3452                                 else if (this is Indexer)
3453                                         Report.Error (54, Location,
3454                                                       "Inconsistent accessibility: indexer return type `" +
3455                                                       TypeManager.MonoBASIC_Name (MemberType) + "' is less " +
3456                                                       "accessible than indexer `" + Name + "'");
3457                                 else if (this is Method)
3458                                         Report.Error (50, Location,
3459                                                       "Inconsistent accessibility: return type `" +
3460                                                       TypeManager.MonoBASIC_Name (MemberType) + "' is less " +
3461                                                       "accessible than method `" + Name + "'");
3462                                 else
3463                                         Report.Error (52, Location,
3464                                                       "Inconsistent accessibility: field type `" +
3465                                                       TypeManager.MonoBASIC_Name (MemberType) + "' is less " +
3466                                                       "accessible than field `" + Name + "'");
3467                                 return false;
3468                         }
3469
3470                         if (MemberType.IsPointer && !UnsafeOK (parent))
3471                                 return false;
3472                         
3473                         //
3474                         // Check for explicit interface implementation
3475                         //
3476                         if ((ExplicitInterfaceName == null) && (Name.IndexOf (".") != -1)){
3477                                 int pos = Name.LastIndexOf (".");
3478
3479                                 ExplicitInterfaceName = Name.Substring (0, pos);
3480                                 ShortName = Name.Substring (pos + 1);
3481                         } else
3482                                 ShortName = Name;
3483
3484                         if (ExplicitInterfaceName != null) {
3485                                 InterfaceType  = RootContext.LookupType (
3486                                         parent, ExplicitInterfaceName, false, Location);
3487                                 if (InterfaceType == null)
3488                                         return false;
3489
3490                                 // Compute the full name that we need to export.
3491                                 Name = InterfaceType.FullName + "." + ShortName;
3492                                 
3493                                 if (!parent.VerifyImplements (InterfaceType, ShortName, Name, Location))
3494                                         return false;
3495                                 
3496                                 IsExplicitImpl = true;
3497                         } else
3498                                 IsExplicitImpl = false;
3499
3500                         return true;
3501                 }
3502         }
3503
3504         //
3505         // Fields and Events both generate FieldBuilders, we use this to share 
3506         // their common bits.  This is also used to flag usage of the field
3507         //
3508         abstract public class FieldBase : MemberBase {
3509                 public FieldBuilder  FieldBuilder;
3510                 public Status status;
3511
3512                 [Flags]
3513                 public enum Status : byte { ASSIGNED = 1, USED = 2 }
3514
3515                 //
3516                 // The constructor is only exposed to our children
3517                 //
3518                 protected FieldBase (Expression type, int mod, int allowed_mod, string name,
3519                                      object init, Attributes attrs, Location loc)
3520                         : base (type, mod, allowed_mod, name, attrs, loc)
3521                 {
3522                         this.init = init;
3523                 }
3524
3525                 //
3526                 // Whether this field has an initializer.
3527                 //
3528                 public bool HasInitializer {
3529                         get {
3530                                 return init != null;
3531                         }
3532                 }
3533
3534                 // Private.
3535                 readonly Object init;
3536                 Expression init_expr;
3537                 bool init_expr_initialized = false;
3538
3539                 //
3540                 // Resolves and returns the field initializer.
3541                 //
3542                 public Expression GetInitializerExpression (EmitContext ec)
3543                 {
3544                         if (init_expr_initialized)
3545                                 return init_expr;
3546
3547                         Expression e;
3548                         if (init is Expression)
3549                                 e = (Expression) init;
3550                         else
3551                                 e = new ArrayCreation (Type, "", (ArrayList)init, Location);
3552
3553                         ec.IsFieldInitializer = true;
3554                         e = e.DoResolve (ec);
3555                         ec.IsFieldInitializer = false;
3556
3557                         init_expr = e;
3558                         init_expr_initialized = true;
3559
3560                         return init_expr;
3561                 }
3562
3563         }
3564
3565         //
3566         // The Field class is used to represents class/struct fields during parsing.
3567         //
3568         public class Field : FieldBase {
3569                 // <summary>
3570                 //   Modifiers allowed in a class declaration
3571                 // </summary>
3572                 const int AllowedModifiers =
3573                         Modifiers.SHADOWS |
3574                         Modifiers.PUBLIC |
3575                         Modifiers.PROTECTED |
3576                         Modifiers.INTERNAL |
3577                         Modifiers.PRIVATE |
3578                         Modifiers.STATIC |
3579                    //     Modifiers.VOLATILE |
3580                    //     Modifiers.UNSAFE |
3581                         Modifiers.READONLY;
3582
3583                 public Field (Expression type, int mod, string name, Object expr_or_array_init,
3584                               Attributes attrs, Location loc)
3585                         : base (type, mod, AllowedModifiers, name, expr_or_array_init, attrs, loc)
3586                 {
3587                 }
3588
3589                 public override bool Define (TypeContainer parent)
3590                 {
3591                         Type t = parent.ResolveType (Type, false, Location);
3592                         
3593                         if (t == null)
3594                                 return false;
3595
3596                         if (!parent.AsAccessible (t, ModFlags)) {
3597                                 Report.Error (52, Location,
3598                                               "Inconsistent accessibility: field type `" +
3599                                               TypeManager.MonoBASIC_Name (t) + "' is less " +
3600                                               "accessible than field `" + Name + "'");
3601                                 return false;
3602                         }
3603
3604                         if (t.IsPointer && !UnsafeOK (parent))
3605                                 return false;
3606                                 
3607                         Type ptype = parent.TypeBuilder.BaseType;
3608
3609                         // ptype is only null for System.Object while compiling corlib.
3610                         if (ptype != null){
3611                                 MemberList list = TypeContainer.FindMembers (
3612                                         ptype, MemberTypes.Field,
3613                                         BindingFlags.Public |
3614                                         BindingFlags.Static | BindingFlags.Instance,
3615                                         System.Type.FilterName, Name);
3616
3617                                 if (RootContext.WarningLevel > 1){      
3618                                         if ((list.Count > 0) && ((ModFlags & Modifiers.SHADOWS) == 0)) \r
3619                                         {
3620                                                 Report.Warning (
3621                                                         40004, 2, Location, 
3622                                                         "Variable '" + Name + "' should be declared " +
3623                                                         "Shadows since the base type '" + ptype.Name + 
3624                                                         "' has a variable with same name");
3625
3626                                                 ModFlags |= Modifiers.SHADOWS;
3627                                         }
3628                                 }
3629                                 if (list.Count == 0)
3630                                         // if a member of module is not inherited from Object class
3631                                         // can not be declared protected
3632                                         if ((parent is Module) && ((ModFlags & Modifiers.PROTECTED) != 0))
3633                                         Report.Error (30593, Location,
3634                                                 "'Variable' inside a 'Module' can not be " +
3635                                                 "declared as 'Protected'");
3636                         }
3637                         
3638                         if ((parent is Struct) && ((ModFlags & Modifiers.PROTECTED) != 0))
3639                                 Report.Error (30435, Location,
3640                                         "'Variable' inside a 'Structure' can not be " +
3641                                         "declared as 'Protected'");
3642
3643                         if ((ModFlags & Modifiers.VOLATILE) != 0){
3644                                 if (!t.IsClass){
3645                                         if (TypeManager.IsEnumType (t))
3646                                                 t = TypeManager.EnumToUnderlying (t);
3647
3648                                         if (!((t == TypeManager.bool_type) ||
3649                                               (t == TypeManager.sbyte_type) ||
3650                                               (t == TypeManager.byte_type) ||
3651                                               (t == TypeManager.short_type) ||    
3652                                               (t == TypeManager.ushort_type) ||
3653                                               (t == TypeManager.int32_type) ||    
3654                                               (t == TypeManager.uint32_type) ||    
3655                                               (t == TypeManager.char_type) ||    
3656                                               (t == TypeManager.float_type))){
3657                                                 Report.Error (
3658                                                         677, Location, parent.MakeName (Name) +
3659                                                         " A volatile field can not be of type `" +
3660                                                         TypeManager.MonoBASIC_Name (t) + "'");
3661                                                 return false;
3662                                         }
3663                                 }
3664                         }
3665
3666                         FieldAttributes fa = Modifiers.FieldAttr (ModFlags);
3667
3668                         if (parent is Struct && 
3669                             ((fa & FieldAttributes.Static) == 0) &&
3670                             t == parent.TypeBuilder &&
3671                             !TypeManager.IsBuiltinType (t)){
3672                                 Report.Error (523, Location, "Struct member `" + parent.Name + "." + Name + 
3673                                               "' causes a cycle in the structure layout");
3674                                 return false;
3675                         }
3676                         FieldBuilder = parent.TypeBuilder.DefineField (
3677                                 Name, t, Modifiers.FieldAttr (ModFlags));
3678
3679                         TypeManager.RegisterFieldBase (FieldBuilder, this);
3680                         return true;
3681                 }
3682
3683                 public void Emit (TypeContainer tc)
3684                 {
3685                         EmitContext ec = new EmitContext (tc, Location, null,
3686                                                           FieldBuilder.FieldType, ModFlags);
3687
3688                         Attribute.ApplyAttributes (ec, FieldBuilder, this, OptAttributes, Location);
3689                 }
3690         }
3691
3692         //
3693         // `set' and `get' accessors are represented with an Accessor.
3694         // 
3695         public class Accessor {
3696                 //
3697                 // Null if the accessor is empty, or a Block if not
3698                 //
3699                 public Block Block;
3700                 public Attributes OptAttributes;
3701                 
3702                 public Accessor (Block b, Attributes attrs)
3703                 {
3704                         Block = b;
3705                         OptAttributes = attrs;
3706                 }
3707         }
3708
3709         //
3710         // Properties and Indexers both generate PropertyBuilders, we use this to share 
3711         // their common bits.
3712         //
3713         abstract public class PropertyBase : MethodCore {
3714                 public Accessor Get, Set;
3715                 public PropertyBuilder PropertyBuilder;
3716                 public MethodBuilder GetBuilder, SetBuilder;
3717                 public MethodData GetData, SetData;
3718
3719                 protected EmitContext ec;
3720
3721                 public PropertyBase (Expression type, string name, int mod_flags, int allowed_mod,
3722                                      Parameters parameters, Accessor get_block, Accessor set_block,
3723                                      Attributes attrs, Location loc)
3724                         : base (type, mod_flags, allowed_mod, name, attrs, parameters, loc)
3725                 {
3726                         Get = get_block;
3727                         Set = set_block;
3728                 }
3729
3730                 protected override bool DoDefine (TypeContainer parent)
3731                 {
3732                         if (!base.DoDefine (parent))
3733                                 return false;
3734
3735                         ec = new EmitContext (parent, Location, null, MemberType, ModFlags);
3736
3737                         return true;
3738                 }
3739
3740                 //
3741                 // Checks our base implementation if any
3742                 //
3743                 protected override bool CheckBase (TypeContainer parent)
3744                 {
3745                         // Check whether arguments were correct.
3746                         if (!DoDefineParameters (parent))
3747                                 return false;
3748
3749                         if (IsExplicitImpl)
3750                                 return true;
3751
3752                         string report_name;
3753                         MethodSignature ms, base_ms;
3754                         if (this is Indexer) {
3755                                 string name, base_name;
3756
3757                                 report_name = "this";
3758                                 name = TypeManager.IndexerPropertyName (parent.TypeBuilder);
3759                                 ms = new MethodSignature (name, null, ParameterTypes);
3760                                 base_name = TypeManager.IndexerPropertyName (parent.TypeBuilder.BaseType);
3761                                 base_ms = new MethodSignature (base_name, null, ParameterTypes);
3762                         } else {
3763                                 report_name = Name;
3764                                 ms = base_ms = new MethodSignature (Name, null, ParameterTypes);
3765                         }
3766
3767                         MemberList props_this;
3768
3769                         props_this = TypeContainer.FindMembers (
3770                                 parent.TypeBuilder, MemberTypes.Property,
3771                                 BindingFlags.NonPublic | BindingFlags.Public |
3772                                 BindingFlags.Static | BindingFlags.Instance |
3773                                 BindingFlags.DeclaredOnly,
3774                                 MethodSignature.method_signature_filter, ms);
3775
3776                         if (props_this.Count > 0) {
3777                                 Report.Error (111, Location, "Class `" + parent.Name + "' " +
3778                                               "already defines a member called `" + report_name + "' " +
3779                                               "with the same parameter types");
3780                                 return false;
3781                         }
3782
3783                         //
3784                         // Find properties with the same name on the base class
3785                         //
3786                         MemberList props;
3787                         MemberList props_static = TypeContainer.FindMembers (
3788                                 parent.TypeBuilder.BaseType, MemberTypes.Property,
3789                                 BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static,
3790                                 MethodSignature.inheritable_property_signature_filter, base_ms);
3791
3792                         MemberList props_instance = TypeContainer.FindMembers (
3793                                 parent.TypeBuilder.BaseType, MemberTypes.Property,
3794                                 BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance,
3795                                 MethodSignature.inheritable_property_signature_filter,
3796                                 base_ms);
3797
3798                         //
3799                         // Find if we have anything
3800                         //
3801                         if (props_static.Count > 0)
3802                                 props = props_static;
3803                         else if (props_instance.Count > 0)
3804                                 props = props_instance;
3805                         else
3806                                 props = null;
3807
3808
3809                         //
3810                         // If we have something on the base.
3811                         if (props != null && props.Count > 0){
3812                                 PropertyInfo pi = (PropertyInfo) props [0];
3813
3814                                 MethodInfo inherited_get = TypeManager.GetPropertyGetter (pi);
3815                                 MethodInfo inherited_set = TypeManager.GetPropertySetter (pi);
3816
3817                                 MethodInfo reference = inherited_get == null ?
3818                                         inherited_set : inherited_get;
3819                                 
3820                                 if (reference != null) {
3821                                         string name = reference.DeclaringType.Name + "." + report_name;
3822
3823                                         if (!CheckMethodAgainstBase (parent, flags, reference, name))
3824                                                 return false;
3825                                 }
3826
3827                                 if (((ModFlags & Modifiers.NEW) == 0) && (pi.PropertyType != MemberType)) {
3828                                         Report.Error (508, parent.MakeName (Name) + ": cannot " +
3829                                                       "change return type when overriding inherited " +
3830                                                       "member `" + pi.DeclaringType + "." + pi.Name + "'");
3831                                         return false;
3832                                 }
3833                         } else {
3834                                 /*if ((ModFlags & Modifiers.NEW) != 0)
3835                                         WarningNotHiding (parent);*/
3836                                 
3837                                 if ((ModFlags & Modifiers.OVERRIDE) != 0){
3838                                         if (this is Indexer)
3839                                                 Report.Error (115, Location,
3840                                                               parent.MakeName (Name) +
3841                                                               " no suitable indexers found to override");
3842                                         else
3843                                                 Report.Error (30284, Location,
3844                                                               parent.MakeName (Name) +
3845                                                               " no suitable properties found to override");
3846                                         return false;
3847                                 }
3848                         }
3849                         return true;
3850                 }
3851
3852                 public virtual void Emit (TypeContainer tc)
3853                 {
3854                         //
3855                         // The PropertyBuilder can be null for explicit implementations, in that
3856                         // case, we do not actually emit the ".property", so there is nowhere to
3857                         // put the attribute
3858                         //
3859                         if (PropertyBuilder != null)
3860                                 Attribute.ApplyAttributes (ec, PropertyBuilder, this, OptAttributes, Location);
3861 /*
3862                         if (GetData != null)
3863                                 GetData.Emit (tc, Get.Block, Get);
3864
3865                         if (SetData != null)
3866                                 SetData.Emit (tc, Set.Block, Set);
3867 */                              
3868                 }
3869         }
3870                         
3871         public class Property : PropertyBase {
3872                 const int AllowedModifiers =
3873                         Modifiers.NEW |
3874                         Modifiers.PUBLIC |
3875                         Modifiers.PROTECTED |
3876                         Modifiers.INTERNAL |
3877                         Modifiers.PRIVATE |
3878                         Modifiers.STATIC |
3879                         Modifiers.SEALED |
3880                         Modifiers.OVERRIDE |
3881                         Modifiers.ABSTRACT |
3882                     Modifiers.UNSAFE |
3883                         Modifiers.EXTERN |
3884                         Modifiers.VIRTUAL |
3885                         Modifiers.DEFAULT |
3886                         Modifiers.READONLY |
3887                         Modifiers.WRITEONLY |
3888                         Modifiers.SHADOWS;
3889
3890                 string set_parameter_name;
3891                 Parameters get_params;
3892                 Parameters set_params;
3893                 
3894                 public Property (Expression type, string name, int mod_flags,
3895                                 Accessor get_block, Accessor set_block,
3896                                 Attributes attrs, Location loc, string set_name, 
3897                                 Parameters p_get, Parameters p_set, Expression impl_what)
3898                         : base (type, name, mod_flags, AllowedModifiers,
3899                                 p_set,
3900                                 get_block, set_block, attrs, loc)
3901                 {
3902                         set_parameter_name = set_name;
3903                         get_params = p_get;
3904                         set_params = p_set;
3905                         Implements = impl_what;
3906                 }               
3907                 
3908                 public Property (Expression type, string name, int mod_flags,
3909                                  Accessor get_block, Accessor set_block,
3910                                  Attributes attrs, Location loc)
3911                         : this (type, name, mod_flags, get_block, set_block, attrs, loc, 
3912                                         "Value", Parameters.EmptyReadOnlyParameters, Parameters.EmptyReadOnlyParameters, null)
3913                 {
3914                 }
3915
3916                 public override bool Define (TypeContainer parent)
3917                 {
3918                         Type [] g_parameters=null, s_parameters=null;
3919                         Parameter [] g_parms, s_parms;
3920                         InternalParameters g_ip=null, s_ip=null;
3921
3922                         if (!DoDefine (parent))
3923                                 return false;
3924
3925                         if (!CheckBase (parent))
3926                                 return false;
3927
3928                         flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
3929
3930                         if (Get == null) {
3931                                 if ((ModFlags & Modifiers.WRITEONLY) == 0)
3932                                         Report.Error (
3933                                                 30124, Location,
3934                                                 "Property without 'Get' accessor must have a 'WriteOnly' modifier");
3935                         }
3936                         else {
3937                                 if (get_params == Parameters.EmptyReadOnlyParameters) 
3938                                 {
3939                                         g_parameters = TypeManager.NoTypes;
3940                                         g_ip = new InternalParameters (
3941                                                         parent, Parameters.EmptyReadOnlyParameters);
3942                                 }
3943                                 else
3944                                 {
3945                                         g_parameters = new Type [get_params.FixedParameters.Length];
3946                                         for (int i = 0; i < get_params.FixedParameters.Length; i ++) 
3947                                         {
3948                                                 g_parameters[i] = get_params.FixedParameters[i].ParameterType;
3949                                         }
3950                                         g_parms = new Parameter [get_params.FixedParameters.Length];
3951                                         for (int i = 0; i < get_params.FixedParameters.Length; i ++) 
3952                                         {
3953                                                 Parameter tp = get_params.FixedParameters[i];
3954                                                 g_parms[i] = new Parameter (tp.TypeName, tp.Name,
3955                                                         Parameter.Modifier.NONE, null);
3956                                         }
3957                                         g_ip = new InternalParameters (
3958                                                 parent, new Parameters (g_parms, null, Location));
3959                                 }
3960
3961                                 GetData = new MethodData (this, "get", MemberType,
3962                                                           g_parameters, g_ip, CallingConventions.Standard,
3963                                                           Get.OptAttributes, ModFlags, flags, false);
3964
3965                                 if (!GetData.Define (parent))
3966                                         return false;
3967
3968                                 GetBuilder = GetData.MethodBuilder;
3969                         }
3970
3971                         if (Set == null) {
3972                                 if ((ModFlags & Modifiers.READONLY) == 0)
3973                                         Report.Error (
3974                                                 30124, Location,
3975                                                 "Property without 'Set' accessor must have a 'ReadOnly' modifier");
3976                                                 
3977                         }
3978                         else \r
3979                         {
3980                                 if (set_params == Parameters.EmptyReadOnlyParameters) 
3981                                 {
3982                                         s_parameters = new Type [1];
3983                                         s_parameters [0] = MemberType;
3984
3985                                         s_parms = new Parameter [1];
3986                                         s_parms [0] = new Parameter (Type, set_parameter_name, 
3987                                                 Parameter.Modifier.NONE, null);
3988                                 }
3989                                 else
3990                                 {
3991                                         s_parameters = new Type [set_params.FixedParameters.Length];
3992                                         for (int i = 0; i < set_params.FixedParameters.Length; i ++) 
3993                                         {
3994                                                 s_parameters[i] = set_params.FixedParameters[i].ParameterType;
3995                                         }
3996
3997                                         s_parms = new Parameter [set_params.FixedParameters.Length];
3998                                         for (int i = 0; i < set_params.FixedParameters.Length; i ++) 
3999                                         {
4000                                                 Parameter tp = set_params.FixedParameters[i];
4001                                                 s_parms[i] = new Parameter (tp.TypeName, tp.Name,
4002                                                         Parameter.Modifier.NONE, null);
4003                                         }
4004                                 }
4005
4006                                 s_ip = new InternalParameters (
4007                                         parent, new Parameters (s_parms, null, Location));
4008
4009                                 SetData = new MethodData (this, "set", TypeManager.void_type,
4010                                         s_parameters, s_ip, CallingConventions.Standard,
4011                                         Set.OptAttributes, ModFlags, flags, false);
4012
4013                                 if (!SetData.Define (parent))
4014                                         return false;
4015
4016                                 SetBuilder = SetData.MethodBuilder;
4017                                 SetBuilder.DefineParameter (1, ParameterAttributes.None, 
4018                                         set_parameter_name); 
4019                         }
4020
4021                         // FIXME - PropertyAttributes.HasDefault ?
4022                         
4023                         PropertyAttributes prop_attr =
4024                         PropertyAttributes.RTSpecialName |
4025                         PropertyAttributes.SpecialName;
4026
4027                         if (!IsExplicitImpl){
4028                                 PropertyBuilder = parent.TypeBuilder.DefineProperty (
4029                                         Name, prop_attr, MemberType, null);
4030                                 
4031                                 PropertyBuilder.SetGetMethod (GetBuilder);
4032                                 PropertyBuilder.SetSetMethod (SetBuilder);
4033
4034                                 //
4035                                 // HACK for the reasons exposed above
4036                                 //
4037                                 if (!TypeManager.RegisterProperty (PropertyBuilder, GetBuilder, SetBuilder)) {
4038                                         Report.Error (
4039                                                 111, Location,
4040                                                 "Class `" + parent.Name +
4041                                                 "' already contains a definition for the property `" +
4042                                                 Name + "'");
4043                                         return false;
4044                                 }
4045                         }
4046                         return true;
4047                 }
4048
4049                 public override void Emit (TypeContainer tc)
4050                 {
4051                         base.Emit (tc);
4052                         
4053                         if (GetData != null) 
4054                         {
4055                                 Parameters = get_params;
4056                                 GetData.Emit (tc, Get.Block, Get);
4057                         }
4058
4059                         if (SetData != null) 
4060                         {
4061                                 Parameters = set_params;
4062                                 SetData.Emit (tc, Set.Block, Set);
4063                         }
4064                                 
4065                 }
4066         }
4067
4068         /// </summary>
4069         ///  Gigantic workaround  for lameness in SRE follows :
4070         ///  This class derives from EventInfo and attempts to basically
4071         ///  wrap around the EventBuilder so that FindMembers can quickly
4072         ///  return this in it search for members
4073         /// </summary>
4074         public class MyEventBuilder : EventInfo {
4075                 
4076                 //
4077                 // We use this to "point" to our Builder which is
4078                 // not really a MemberInfo
4079                 //
4080                 EventBuilder MyBuilder;
4081                 
4082                 //
4083                 // We "catch" and wrap these methods
4084                 //
4085                 MethodInfo raise, remove, add;
4086
4087                 EventAttributes attributes;
4088                 Type declaring_type, reflected_type, event_type;
4089                 string name;
4090
4091                 public MyEventBuilder (TypeBuilder type_builder, string name, EventAttributes event_attr, Type event_type)
4092                 {
4093                         MyBuilder = type_builder.DefineEvent (name, event_attr, event_type);
4094
4095                         // And now store the values in our own fields.
4096                         
4097                         declaring_type = type_builder;
4098
4099                         reflected_type = type_builder;
4100                         
4101                         attributes = event_attr;
4102                         this.name = name;
4103                         this.event_type = event_type;
4104                 }
4105                 
4106                 //
4107                 // Methods that you have to override.  Note that you only need 
4108                 // to "implement" the variants that take the argument (those are
4109                 // the "abstract" methods, the others (GetAddMethod()) are 
4110                 // regular.
4111                 //
4112                 public override MethodInfo GetAddMethod (bool nonPublic)
4113                 {
4114                         return add;
4115                 }
4116                 
4117                 public override MethodInfo GetRemoveMethod (bool nonPublic)
4118                 {
4119                         return remove;
4120                 }
4121                 
4122                 public override MethodInfo GetRaiseMethod (bool nonPublic)
4123                 {
4124                         return raise;
4125                 }
4126                 
4127                 //
4128                 // These methods make "MyEventInfo" look like a Builder
4129                 //
4130                 public void SetRaiseMethod (MethodBuilder raiseMethod)
4131                 {
4132                         raise = raiseMethod;
4133                         MyBuilder.SetRaiseMethod (raiseMethod);
4134                 }
4135
4136                 public void SetRemoveOnMethod (MethodBuilder removeMethod)
4137                 {
4138                         remove = removeMethod;
4139                         MyBuilder.SetRemoveOnMethod (removeMethod);
4140                 }
4141
4142                 public void SetAddOnMethod (MethodBuilder addMethod)
4143                 {
4144                         add = addMethod;
4145                         MyBuilder.SetAddOnMethod (addMethod);
4146                 }
4147
4148                 public void SetCustomAttribute (CustomAttributeBuilder cb)
4149                 {
4150                         MyBuilder.SetCustomAttribute (cb);
4151                 }
4152                 
4153                 public override object [] GetCustomAttributes (bool inherit)
4154                 {
4155                         // FIXME : There's nothing which can be seemingly done here because
4156                         // we have no way of getting at the custom attribute objects of the
4157                         // EventBuilder !
4158                         return null;
4159                 }
4160
4161                 public override object [] GetCustomAttributes (Type t, bool inherit)
4162                 {
4163                         // FIXME : Same here !
4164                         return null;
4165                 }
4166
4167                 public override bool IsDefined (Type t, bool b)
4168                 {
4169                         return true;
4170                 }
4171
4172                 public override EventAttributes Attributes {
4173                         get {
4174                                 return attributes;
4175                         }
4176                 }
4177
4178                 public override string Name {
4179                         get {
4180                                 return name;
4181                         }
4182                 }
4183
4184                 public override Type DeclaringType {
4185                         get {
4186                                 return declaring_type;
4187                         }
4188                 }
4189
4190                 public override Type ReflectedType {
4191                         get {
4192                                 return reflected_type;
4193                         }
4194                 }
4195
4196                 public Type EventType {
4197                         get {
4198                                 return event_type;
4199                         }
4200                 }
4201         }
4202         
4203         public class Event : FieldBase {
4204                 const int AllowedModifiers =
4205                         Modifiers.NEW |
4206                         Modifiers.PUBLIC |
4207                         Modifiers.PROTECTED |
4208                         Modifiers.INTERNAL |
4209                         Modifiers.PRIVATE |
4210                         Modifiers.STATIC |
4211                         Modifiers.VIRTUAL |
4212                         Modifiers.SEALED |
4213                         Modifiers.OVERRIDE |
4214                         Modifiers.UNSAFE |
4215                         Modifiers.ABSTRACT;
4216
4217                 public readonly Accessor  Add;
4218                 public readonly Accessor  Remove;
4219                 public MyEventBuilder     EventBuilder;
4220
4221                 MethodBuilder AddBuilder, RemoveBuilder;
4222                 MethodData AddData, RemoveData;
4223                 
4224                 public Event (Expression type, string name, Object init, int mod, Accessor add,
4225                               Accessor remove, Attributes attrs, Location loc)
4226                         : base (type, mod, AllowedModifiers, name, init, attrs, loc)
4227                 {
4228                         Add = add;
4229                         Remove = remove;
4230                 }
4231
4232                 public override bool Define (TypeContainer parent)
4233                 {
4234                         EventAttributes e_attr = EventAttributes.RTSpecialName | EventAttributes.SpecialName;
4235
4236                         if (!DoDefine (parent))
4237                                 return false;
4238
4239                         if (!MemberType.IsSubclassOf (TypeManager.delegate_type)) {
4240                                 Report.Error (66, Location, "'" + parent.Name + "." + Name +
4241                                               "' : event must be of a delegate type");
4242                                 return false;
4243                         }
4244
4245                         Type [] parameter_types = new Type [1];
4246                         parameter_types [0] = MemberType;
4247
4248                         Parameter [] parms = new Parameter [1];
4249                         parms [0] = new Parameter (Type, /* was "value" */ this.Name, Parameter.Modifier.NONE, null);
4250                         InternalParameters ip = new InternalParameters (
4251                                 parent, new Parameters (parms, null, Location)); 
4252
4253                         if (!CheckBase (parent))
4254                                 return false;
4255
4256                         //
4257                         // Now define the accessors
4258                         //
4259                         AddData = new MethodData (this, "add", TypeManager.void_type,
4260                                                   parameter_types, ip, CallingConventions.Standard,
4261                                                   (Add != null) ? Add.OptAttributes : null,
4262                                                   ModFlags, flags, false);
4263
4264                         if (!AddData.Define (parent))
4265                                 return false;
4266
4267                         AddBuilder = AddData.MethodBuilder;
4268                         AddBuilder.DefineParameter (1, ParameterAttributes.None, /* was "value" */ this.Name);
4269
4270                         RemoveData = new MethodData (this, "remove", TypeManager.void_type,
4271                                                      parameter_types, ip, CallingConventions.Standard,
4272                                                      (Remove != null) ? Remove.OptAttributes : null,
4273                                                      ModFlags, flags, false);
4274
4275                         if (!RemoveData.Define (parent))
4276                                 return false;
4277
4278                         RemoveBuilder = RemoveData.MethodBuilder;
4279                         RemoveBuilder.DefineParameter (1, ParameterAttributes.None, /* was "value" */ this.Name);
4280
4281                         if (!IsExplicitImpl){
4282                                 EventBuilder = new MyEventBuilder (
4283                                         parent.TypeBuilder, Name, e_attr, MemberType);
4284                                         
4285                                 if (Add == null && Remove == null) {
4286                                         FieldBuilder = parent.TypeBuilder.DefineField (
4287                                                 Name, MemberType,
4288                                                 FieldAttributes.FamANDAssem | ((ModFlags & Modifiers.STATIC) != 0 ? FieldAttributes.Static : 0));
4289                                         TypeManager.RegisterPrivateFieldOfEvent (
4290                                                 (EventInfo) EventBuilder, FieldBuilder);
4291                                         TypeManager.RegisterFieldBase (FieldBuilder, this);
4292                                 }
4293                         
4294                                 EventBuilder.SetAddOnMethod (AddBuilder);
4295                                 EventBuilder.SetRemoveOnMethod (RemoveBuilder);
4296
4297                                 if (!TypeManager.RegisterEvent (EventBuilder, AddBuilder, RemoveBuilder)) {
4298                                         Report.Error (111, Location,
4299                                                       "Class `" + parent.Name +
4300                                                       "' already contains a definition for the event `" +
4301                                                       Name + "'");
4302                                         return false;
4303                                 }
4304                         }
4305                         
4306                         return true;
4307                 }
4308
4309                 void EmitDefaultMethod (EmitContext ec, bool is_add)
4310                 {
4311                         ILGenerator ig = ec.ig;
4312                         MethodInfo method = null;
4313                         
4314                         if (is_add)
4315                                 method = TypeManager.delegate_combine_delegate_delegate;
4316                         else
4317                                 method = TypeManager.delegate_remove_delegate_delegate;
4318
4319                         if ((ModFlags & Modifiers.STATIC) != 0) {
4320                                 ig.Emit (OpCodes.Ldsfld, (FieldInfo) FieldBuilder);
4321                                 ig.Emit (OpCodes.Ldarg_0);
4322                                 ig.Emit (OpCodes.Call, method);
4323                                 ig.Emit (OpCodes.Castclass, MemberType);
4324                                 ig.Emit (OpCodes.Stsfld, (FieldInfo) FieldBuilder);
4325                         } else {
4326                                 ig.Emit (OpCodes.Ldarg_0);
4327                                 ig.Emit (OpCodes.Ldarg_0);
4328                                 ig.Emit (OpCodes.Ldfld, (FieldInfo) FieldBuilder);
4329                                 ig.Emit (OpCodes.Ldarg_1);
4330                                 ig.Emit (OpCodes.Call, method);
4331                                 ig.Emit (OpCodes.Castclass, MemberType);
4332                                 ig.Emit (OpCodes.Stfld, (FieldInfo) FieldBuilder);
4333                         }
4334                         ig.Emit (OpCodes.Ret);
4335                 }
4336
4337                 public void Emit (TypeContainer tc)
4338                 {
4339                         EmitContext ec;
4340
4341                         ec = new EmitContext (tc, Location, null, MemberType, ModFlags);
4342                         Attribute.ApplyAttributes (ec, EventBuilder, this, OptAttributes, Location);
4343
4344                         if (Add != null)
4345                                 AddData.Emit (tc, Add.Block, Add);
4346                         else {
4347                                 ILGenerator ig = AddData.MethodBuilder.GetILGenerator ();
4348                                 ec = new EmitContext (tc, Location, ig, TypeManager.void_type, ModFlags);
4349                                 EmitDefaultMethod (ec, true);
4350                         }
4351
4352                         if (Remove != null)
4353                                 RemoveData.Emit (tc, Remove.Block, Remove);
4354                         else {
4355                                 ILGenerator ig = RemoveData.MethodBuilder.GetILGenerator ();
4356                                 ec = new EmitContext (tc, Location, ig, TypeManager.void_type, ModFlags);
4357                                 EmitDefaultMethod (ec, false);
4358                         }
4359                 }
4360                 
4361         }
4362
4363         //
4364         // FIXME: This does not handle:
4365         //
4366         //   int INTERFACENAME [ args ]
4367         //   Does not 
4368         //
4369         // Only:
4370         // 
4371         // int this [ args ]
4372  
4373         public class Indexer : PropertyBase {
4374
4375                 const int AllowedModifiers =
4376                         Modifiers.NEW |
4377                         Modifiers.PUBLIC |
4378                         Modifiers.PROTECTED |
4379                         Modifiers.INTERNAL |
4380                         Modifiers.PRIVATE |
4381                         Modifiers.VIRTUAL |
4382                         Modifiers.SEALED |
4383                         Modifiers.OVERRIDE |
4384                         Modifiers.UNSAFE |
4385                         Modifiers.EXTERN |
4386                         Modifiers.ABSTRACT;
4387
4388                 public string IndexerName;
4389                 public string InterfaceIndexerName;
4390
4391                 //
4392                 // Are we implementing an interface ?
4393                 //
4394                 bool IsImplementing = false;
4395                 
4396                 public Indexer (Expression type, string int_type, int flags, Parameters parameters,
4397                                 Accessor get_block, Accessor set_block, Attributes attrs, Location loc)
4398                         : base (type, "", flags, AllowedModifiers, parameters, get_block, set_block,
4399                                 attrs, loc)
4400                 {
4401                         ExplicitInterfaceName = int_type;
4402                 }
4403
4404                 public override bool Define (TypeContainer parent)
4405                 {
4406                         PropertyAttributes prop_attr =
4407                                 PropertyAttributes.RTSpecialName |
4408                                 PropertyAttributes.SpecialName;
4409                         
4410                         if (!DoDefine (parent))
4411                                 return false;
4412
4413                         IndexerName = Attribute.ScanForIndexerName (ec, OptAttributes);
4414                         if (IndexerName == null)
4415                                 IndexerName = "Item";
4416                         else if (IsExplicitImpl)
4417                                 Report.Error (592, Location,
4418                                               "Attribute 'IndexerName' is not valid on this declaration " +
4419                                               "type. It is valid on `property' declarations only.");
4420
4421                         ShortName = IndexerName;
4422                         if (IsExplicitImpl) {
4423                                 InterfaceIndexerName = TypeManager.IndexerPropertyName (InterfaceType);
4424                                 Name = InterfaceType.FullName + "." + IndexerName;
4425                         } else {
4426                                 InterfaceIndexerName = IndexerName;
4427                                 Name = ShortName;
4428                         }
4429
4430                         if (!CheckBase (parent))
4431                                 return false;
4432
4433                         if (Get != null){
4434                                 InternalParameters ip = new InternalParameters (parent, Parameters);
4435
4436                                 GetData = new MethodData (this, "get", MemberType,
4437                                                           ParameterTypes, ip, CallingConventions.Standard,
4438                                                           Get.OptAttributes, ModFlags, flags, false);
4439
4440                                 if (!GetData.Define (parent))
4441                                         return false;
4442
4443                                 GetBuilder = GetData.MethodBuilder;
4444                         }
4445                         
4446                         if (Set != null){
4447                                 int top = ParameterTypes.Length;
4448                                 Type [] set_pars = new Type [top + 1];
4449                                 ParameterTypes.CopyTo (set_pars, 0);
4450                                 set_pars [top] = MemberType;
4451
4452                                 Parameter [] fixed_parms = Parameters.FixedParameters;
4453
4454                                 if (fixed_parms == null){
4455                                         throw new Exception ("We currently do not support only array arguments in an indexer");
4456                                         // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
4457                                         // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
4458                                         //
4459                                         // Here is the problem: the `value' parameter has
4460                                         // to come *after* the array parameter in the declaration
4461                                         // like this:
4462                                         // X (object [] x, Type value)
4463                                         // .param [0]
4464                                         //
4465                                         // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
4466                                         // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
4467                                         
4468                                 }
4469                                 
4470                                 Parameter [] tmp = new Parameter [fixed_parms.Length + 1];
4471
4472
4473                                 fixed_parms.CopyTo (tmp, 0);
4474                                 tmp [fixed_parms.Length] = new Parameter (
4475                                         Type, /* was "value" */ this.Name, Parameter.Modifier.NONE, null);
4476
4477                                 Parameters set_formal_params = new Parameters (tmp, null, Location);
4478                                 
4479                                 InternalParameters ip = new InternalParameters (parent, set_formal_params);
4480
4481                                 SetData = new MethodData (this, "set", TypeManager.void_type,
4482                                                           set_pars, ip, CallingConventions.Standard,
4483                                                           Set.OptAttributes, ModFlags, flags, false);
4484
4485                                 if (!SetData.Define (parent))
4486                                         return false;
4487
4488                                 SetBuilder = SetData.MethodBuilder;
4489                         }
4490
4491                         //
4492                         // Now name the parameters
4493                         //
4494                         Parameter [] p = Parameters.FixedParameters;
4495                         if (p != null) {
4496                                 int i;
4497                                 
4498                                 for (i = 0; i < p.Length; ++i) {
4499                                         if (Get != null)
4500                                                 GetBuilder.DefineParameter (
4501                                                         i + 1, p [i].Attributes, p [i].Name);
4502
4503                                         if (Set != null)
4504                                                 SetBuilder.DefineParameter (
4505                                                         i + 1, p [i].Attributes, p [i].Name);
4506                                 }
4507                                 
4508
4509                                 if (Set != null)
4510                                         SetBuilder.DefineParameter (
4511                                                 i + 1, ParameterAttributes.None, /* was "value" */ this.Name);
4512                                         
4513                                 if (i != ParameterTypes.Length) {
4514                                         Parameter array_param = Parameters.ArrayParameter;
4515                                         SetBuilder.DefineParameter (
4516                                                 i + 1, array_param.Attributes, array_param.Name);
4517                                 }
4518                         }
4519
4520                         if (GetData != null)
4521                                 IsImplementing = GetData.IsImplementing;
4522                         else if (SetData != null)
4523                                 IsImplementing = SetData.IsImplementing;
4524
4525                         //
4526                         // Define the PropertyBuilder if one of the following conditions are met:
4527                         // a) we're not implementing an interface indexer.
4528                         // b) the indexer has a different IndexerName and this is no
4529                         //    explicit interface implementation.
4530                         //
4531                         if (!IsExplicitImpl) {
4532                                 PropertyBuilder = parent.TypeBuilder.DefineProperty (
4533                                         IndexerName, prop_attr, MemberType, ParameterTypes);
4534
4535                                 if (GetData != null)
4536                                         PropertyBuilder.SetGetMethod (GetBuilder);
4537
4538                                 if (SetData != null)
4539                                         PropertyBuilder.SetSetMethod (SetBuilder);
4540                                 
4541                                 TypeManager.RegisterIndexer (PropertyBuilder, GetBuilder, SetBuilder,
4542                                                              ParameterTypes);
4543                         }
4544
4545                         return true;
4546                 }
4547         }
4548
4549         public class Operator : MemberCore {
4550
4551                 const int AllowedModifiers =
4552                         Modifiers.PUBLIC |
4553                         Modifiers.UNSAFE |
4554                         Modifiers.EXTERN |
4555                         Modifiers.STATIC;
4556
4557                 const int RequiredModifiers =
4558                         Modifiers.PUBLIC |
4559                         Modifiers.STATIC;
4560
4561                 public enum OpType : byte {
4562
4563                         // Unary operators
4564                         LogicalNot,
4565                         OnesComplement,
4566                         Increment,
4567                         Decrement,
4568                         True,
4569                         False,
4570
4571                         // Unary and Binary operators
4572                         Addition,
4573                         Subtraction,
4574
4575                         UnaryPlus,
4576                         UnaryNegation,
4577                         
4578                         // Binary operators
4579                         Multiply,
4580                         Division,
4581                         Modulus,
4582                         BitwiseAnd,
4583                         BitwiseOr,
4584                         ExclusiveOr,
4585                         LeftShift,
4586                         RightShift,
4587                         Equality,
4588                         Inequality,
4589                         GreaterThan,
4590                         LessThan,
4591                         GreaterThanOrEqual,
4592                         LessThanOrEqual,
4593
4594                         // Implicit and Explicit
4595                         Implicit,
4596                         Explicit
4597                 };
4598
4599                 public readonly OpType OperatorType;
4600                 public readonly Expression ReturnType;
4601                 public readonly Expression FirstArgType, SecondArgType;
4602                 public readonly string FirstArgName, SecondArgName;
4603                 public readonly Block  Block;
4604                 public Attributes      OptAttributes;
4605                 public MethodBuilder   OperatorMethodBuilder;
4606                 
4607                 public string MethodName;
4608                 public Method OperatorMethod;
4609
4610                 public Operator (OpType type, Expression ret_type, int flags,
4611                                  Expression arg1type, string arg1name,
4612                                  Expression arg2type, string arg2name,
4613                                  Block block, Attributes attrs, Location loc)
4614                         : base ("", loc)
4615                 {
4616                         OperatorType = type;
4617                         ReturnType = ret_type;
4618                         ModFlags = Modifiers.Check (AllowedModifiers, flags, Modifiers.PUBLIC, loc);
4619                         FirstArgType = arg1type;
4620                         FirstArgName = arg1name;
4621                         SecondArgType = arg2type;
4622                         SecondArgName = arg2name;
4623                         Block = block;
4624                         OptAttributes = attrs;
4625                 }
4626
4627                 string Prototype (TypeContainer parent)
4628                 {
4629                         return parent.Name + ".operator " + OperatorType + " (" + FirstArgType + "," +
4630                                 SecondArgType + ")";
4631                 }
4632                 
4633                 public override bool Define (TypeContainer parent)
4634                 {
4635                         int length = 1;
4636                         MethodName = "op_" + OperatorType;
4637                         
4638                         if (SecondArgType != null)
4639                                 length = 2;
4640                         
4641                         Parameter [] param_list = new Parameter [length];
4642
4643                         if ((ModFlags & RequiredModifiers) != RequiredModifiers){
4644                                 Report.Error (
4645                                         558, Location, 
4646                                         "User defined operators `" +
4647                                         Prototype (parent) +
4648                                         "' must be declared static and public");
4649                                 return false;
4650                         }
4651
4652                         param_list[0] = new Parameter (FirstArgType, FirstArgName,
4653                                                        Parameter.Modifier.NONE, null);
4654                         if (SecondArgType != null)
4655                                 param_list[1] = new Parameter (SecondArgType, SecondArgName,
4656                                                                Parameter.Modifier.NONE, null);
4657                         
4658                         OperatorMethod = new Method (ReturnType, ModFlags, MethodName,
4659                                                      new Parameters (param_list, null, Location),
4660                                                      OptAttributes, Mono.MonoBASIC.Location.Null);
4661
4662                         OperatorMethod.IsOperator = true;                       
4663                         OperatorMethod.Define (parent);
4664
4665                         if (OperatorMethod.MethodBuilder == null)
4666                                 return false;
4667                         
4668                         OperatorMethodBuilder = OperatorMethod.MethodBuilder;
4669
4670                         Type [] param_types = OperatorMethod.ParameterTypes;
4671                         Type declaring_type = OperatorMethodBuilder.DeclaringType;
4672                         Type return_type = OperatorMethod.GetReturnType ();
4673                         Type first_arg_type = param_types [0];
4674
4675                         // Rules for conversion operators
4676                         
4677                         if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
4678                                 if (first_arg_type == return_type && first_arg_type == declaring_type){
4679                                         Report.Error (
4680                                                 555, Location,
4681                                                 "User-defined conversion cannot take an object of the " +
4682                                                 "enclosing type and convert to an object of the enclosing" +
4683                                                 " type");
4684                                         return false;
4685                                 }
4686                                 
4687                                 if (first_arg_type != declaring_type && return_type != declaring_type){
4688                                         Report.Error (
4689                                                 556, Location, 
4690                                                 "User-defined conversion must convert to or from the " +
4691                                                 "enclosing type");
4692                                         return false;
4693                                 }
4694                                 
4695                                 if (first_arg_type == TypeManager.object_type ||
4696                                     return_type == TypeManager.object_type){
4697                                         Report.Error (
4698                                                 -8, Location,
4699                                                 "User-defined conversion cannot convert to or from " +
4700                                                 "object type");
4701                                         return false;
4702                                 }
4703
4704                                 if (first_arg_type.IsInterface || return_type.IsInterface){
4705                                         Report.Error (
4706                                                 552, Location,
4707                                                 "User-defined conversion cannot convert to or from an " +
4708                                                 "interface type");
4709                                         return false;
4710                                 }
4711                                 
4712                                 if (first_arg_type.IsSubclassOf (return_type) ||
4713                                     return_type.IsSubclassOf (first_arg_type)){
4714                                         Report.Error (
4715                                                 -10, Location,
4716                                                 "User-defined conversion cannot convert between types " +
4717                                                 "that derive from each other");
4718                                         return false;
4719                                 }
4720                         } else if (SecondArgType == null) {
4721                                 // Checks for Unary operators
4722                                 
4723                                 if (first_arg_type != declaring_type){
4724                                         Report.Error (
4725                                                 562, Location,
4726                                                 "The parameter of a unary operator must be the " +
4727                                                 "containing type");
4728                                         return false;
4729                                 }
4730                                 
4731                                 if (OperatorType == OpType.Increment || OperatorType == OpType.Decrement) {
4732                                         if (return_type != declaring_type){
4733                                                 Report.Error (
4734                                                         559, Location,
4735                                                         "The parameter and return type for ++ and -- " +
4736                                                         "must be the containing type");
4737                                                 return false;
4738                                         }
4739                                         
4740                                 }
4741                                 
4742                                 if (OperatorType == OpType.True || OperatorType == OpType.False) {
4743                                         if (return_type != TypeManager.bool_type){
4744                                                 Report.Error (
4745                                                         215, Location,
4746                                                         "The return type of operator True or False " +
4747                                                         "must be bool");
4748                                                 return false;
4749                                         }
4750                                 }
4751                                 
4752                         } else {
4753                                 // Checks for Binary operators
4754                                 
4755                                 if (first_arg_type != declaring_type &&
4756                                     param_types [1] != declaring_type){
4757                                         Report.Error (
4758                                                 563, Location,
4759                                                 "One of the parameters of a binary operator must " +
4760                                                 "be the containing type");
4761                                         return false;
4762                                 }
4763                         }
4764
4765                         return true;
4766                 }
4767                 
4768                 public void Emit (TypeContainer parent)
4769                 {
4770                         EmitContext ec = new EmitContext (parent, Location, null, null, ModFlags);
4771                         Attribute.ApplyAttributes (ec, OperatorMethodBuilder, this, OptAttributes, Location);
4772
4773                         //
4774                         // abstract or extern methods have no bodies
4775                         //
4776                         if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
4777                                 return;
4778                         
4779                         OperatorMethod.Block = Block;
4780                         OperatorMethod.Emit (parent);
4781                 }
4782
4783                 public static string GetName (OpType ot)
4784                 {
4785                         switch (ot){
4786                         case OpType.LogicalNot:
4787                                 return "!";
4788                         case OpType.OnesComplement:
4789                                 return "~";
4790                         case OpType.Increment:
4791                                 return "++";
4792                         case OpType.Decrement:
4793                                 return "--";
4794                         case OpType.True:
4795                                 return "true";
4796                         case OpType.False:
4797                                 return "false";
4798                         case OpType.Addition:
4799                                 return "+";
4800                         case OpType.Subtraction:
4801                                 return "-";
4802                         case OpType.UnaryPlus:
4803                                 return "+";
4804                         case OpType.UnaryNegation:
4805                                 return "-";
4806                         case OpType.Multiply:
4807                                 return "*";
4808                         case OpType.Division:
4809                                 return "/";
4810                         case OpType.Modulus:
4811                                 return "%";
4812                         case OpType.BitwiseAnd:
4813                                 return "&";
4814                         case OpType.BitwiseOr:
4815                                 return "|";
4816                         case OpType.ExclusiveOr:
4817                                 return "^";
4818                         case OpType.LeftShift:
4819                                 return "<<";
4820                         case OpType.RightShift:
4821                                 return ">>";
4822                         case OpType.Equality:
4823                                 return "==";
4824                         case OpType.Inequality:
4825                                 return "!=";
4826                         case OpType.GreaterThan:
4827                                 return ">";
4828                         case OpType.LessThan:
4829                                 return "<";
4830                         case OpType.GreaterThanOrEqual:
4831                                 return ">=";
4832                         case OpType.LessThanOrEqual:
4833                                 return "<=";
4834                         case OpType.Implicit:
4835                                 return "implicit";
4836                         case OpType.Explicit:
4837                                 return "explicit";
4838                         default: return "";
4839                         }
4840                 }
4841                 
4842                 public override string ToString ()
4843                 {
4844                         Type return_type = OperatorMethod.GetReturnType();
4845                         Type [] param_types = OperatorMethod.ParameterTypes;
4846                         
4847                         if (SecondArgType == null)
4848                                 return String.Format (
4849                                         "{0} operator {1}({2})",
4850                                         TypeManager.MonoBASIC_Name (return_type),
4851                                         GetName (OperatorType),
4852                                         param_types [0]);
4853                         else
4854                                 return String.Format (
4855                                         "{0} operator {1}({2}, {3})",
4856                                         TypeManager.MonoBASIC_Name (return_type),
4857                                         GetName (OperatorType),
4858                                         param_types [0], param_types [1]);
4859                 }
4860         }
4861
4862         //
4863         // This is used to compare method signatures
4864         //
4865         struct MethodSignature {
4866                 public string Name;
4867                 public Type RetType;
4868                 public Type [] Parameters;
4869                 
4870                 /// <summary>
4871                 ///    This delegate is used to extract methods which have the
4872                 ///    same signature as the argument
4873                 /// </summary>
4874                 public static MemberFilter method_signature_filter;
4875
4876                 /// <summary>
4877                 ///    This delegate is used to extract methods which have the
4878                 ///    same signature as the argument except for the name
4879                 /// </summary>
4880                 public static MemberFilter method_signature_noname_filter;
4881
4882                 /// <summary>
4883                 ///   This delegate is used to extract inheritable methods which
4884                 ///   have the same signature as the argument.  By inheritable,
4885                 ///   this means that we have permissions to override the method
4886                 ///   from the current assembly and class
4887                 /// </summary>
4888                 public static MemberFilter inheritable_method_signature_filter;
4889
4890                 /// <summary>
4891                 ///   This delegate is used to extract inheritable methods which
4892                 ///   have the same signature as the argument.  By inheritable,
4893                 ///   this means that we have permissions to override the method
4894                 ///   from the current assembly and class
4895                 /// </summary>
4896                 public static MemberFilter inheritable_property_signature_filter;
4897                 
4898                 static MethodSignature ()
4899                 {
4900                         method_signature_filter = new MemberFilter (MemberSignatureCompare);
4901                         method_signature_noname_filter = new MemberFilter (MemberSignatureCompareNoName);
4902                         inheritable_method_signature_filter = new MemberFilter (
4903                                 InheritableMemberSignatureCompare);
4904                         inheritable_property_signature_filter = new MemberFilter (
4905                                 InheritablePropertySignatureCompare);
4906                 }
4907                 
4908                 public MethodSignature (string name, Type ret_type, Type [] parameters)
4909                 {
4910                         Name = name;
4911                         RetType = ret_type;
4912
4913                         if (parameters == null)
4914                                 Parameters = TypeManager.NoTypes;
4915                         else
4916                                 Parameters = parameters;
4917                 }
4918                 
4919                 public override int GetHashCode ()
4920                 {
4921                         return Name.GetHashCode ();
4922                 }
4923
4924                 public override bool Equals (Object o)
4925                 {
4926                         MethodSignature other = (MethodSignature) o;
4927
4928                         if (other.Name != Name)
4929                                 return false;
4930
4931                         if (other.RetType != RetType)
4932                                 return false;
4933                         
4934                         if (Parameters == null){
4935                                 if (other.Parameters == null)
4936                                         return true;
4937                                 return false;
4938                         }
4939
4940                         if (other.Parameters == null)
4941                                 return false;
4942                         
4943                         int c = Parameters.Length;
4944                         if (other.Parameters.Length != c)
4945                                 return false;
4946
4947                         for (int i = 0; i < c; i++)
4948                                 if (other.Parameters [i] != Parameters [i])
4949                                         return false;
4950
4951                         return true;
4952                 }
4953
4954                 static bool MemberSignatureCompareNoName (MemberInfo m, object filter_criteria)
4955                 {
4956                         return MemberSignatureCompare (m, filter_criteria, false);
4957                 }
4958
4959                 static bool MemberSignatureCompare (MemberInfo m, object filter_criteria)
4960                 {
4961                         return MemberSignatureCompare (m, filter_criteria, true);
4962                 }
4963
4964                 static bool MemberSignatureCompare (MemberInfo m, object filter_criteria, bool use_name)
4965                 {
4966                         MethodSignature sig = (MethodSignature) filter_criteria;
4967
4968                         if (use_name && (m.Name != sig.Name))
4969                                 return false;
4970
4971                         Type ReturnType;
4972                         MethodInfo mi = m as MethodInfo;
4973                         PropertyInfo pi = m as PropertyInfo;
4974
4975                         if (mi != null)
4976                                 ReturnType = mi.ReturnType;
4977                         else if (pi != null)
4978                                 ReturnType = pi.PropertyType;
4979                         else
4980                                 return false;
4981                         
4982                         //
4983                         // we use sig.RetType == null to mean `do not check the
4984                         // method return value.  
4985                         //
4986                         if (sig.RetType != null)
4987                                 if (ReturnType != sig.RetType)
4988                                         return false;
4989
4990                         Type [] args;
4991                         if (mi != null)
4992                                 args = TypeManager.GetArgumentTypes (mi);
4993                         else
4994                                 args = TypeManager.GetArgumentTypes (pi);
4995                         Type [] sigp = sig.Parameters;
4996
4997                         if (args.Length != sigp.Length)
4998                                 return false;
4999
5000                         for (int i = args.Length; i > 0; ){
5001                                 i--;
5002                                 if (args [i] != sigp [i])
5003                                         return false;
5004                         }
5005                         return true;
5006                 }
5007
5008                 //
5009                 // This filter should be used when we are requesting methods that
5010                 // we want to override.
5011                 //
5012                 // This makes a number of assumptions, for example
5013                 // that the methods being extracted are of a parent
5014                 // class (this means we know implicitly that we are
5015                 // being called to find out about members by a derived
5016                 // class).
5017                 // 
5018                 static bool InheritableMemberSignatureCompare (MemberInfo m, object filter_criteria)
5019                 {
5020                         if (MemberSignatureCompare (m, filter_criteria)){
5021                                 MethodInfo mi = (MethodInfo) m;
5022                                 MethodAttributes prot = mi.Attributes & MethodAttributes.MemberAccessMask;
5023
5024                                 // If only accessible to the current class.
5025                                 if (prot == MethodAttributes.Private)
5026                                         return false;
5027
5028                                 // If only accessible to the defining assembly or 
5029                                 if (prot == MethodAttributes.FamANDAssem ||
5030                                     prot == MethodAttributes.Assembly){
5031                                         if (m.DeclaringType.Assembly == CodeGen.AssemblyBuilder)
5032                                                 return true;
5033                                         else
5034                                                 return false;
5035                                 }
5036
5037                                 // Anything else (FamOrAssembly and Public) is fine
5038                                 return true;
5039                         }
5040                         return false;
5041                 }
5042
5043                 //
5044                 // This filter should be used when we are requesting properties that
5045                 // we want to override.
5046                 //
5047                 // This makes a number of assumptions, for example
5048                 // that the methods being extracted are of a parent
5049                 // class (this means we know implicitly that we are
5050                 // being called to find out about members by a derived
5051                 // class).
5052                 // 
5053                 static bool InheritablePropertySignatureCompare (MemberInfo m, object filter_criteria)
5054                 {
5055                         if (MemberSignatureCompare (m, filter_criteria)){
5056                                 PropertyInfo pi = (PropertyInfo) m;
5057
5058                                 MethodInfo inherited_get = TypeManager.GetPropertyGetter (pi);
5059                                 MethodInfo inherited_set = TypeManager.GetPropertySetter (pi);
5060
5061                                 MethodInfo mi = inherited_get == null ? inherited_set : inherited_get;
5062
5063                                 MethodAttributes prot = mi.Attributes & MethodAttributes.MemberAccessMask;
5064
5065                                 // If only accessible to the current class.
5066                                 if (prot == MethodAttributes.Private)
5067                                         return false;
5068
5069                                 // If only accessible to the defining assembly or 
5070                                 if (prot == MethodAttributes.FamANDAssem ||
5071                                     prot == MethodAttributes.Assembly){
5072                                         if (m.DeclaringType.Assembly == CodeGen.AssemblyBuilder)
5073                                                 return true;
5074                                         else
5075                                                 return false;
5076                                 }
5077
5078                                 // Anything else (FamOrAssembly and Public) is fine
5079                                 return true;
5080                         }
5081                         return false;
5082                 }
5083         }
5084 }