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