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