SaveAdd wrappers
[mono.git] / mcs / mcs / class.cs
1 //
2 // class.cs: Class and Struct handlers
3 //
4 // Authors: Miguel de Icaza (miguel@gnu.org)
5 //          Martin Baulig (martin@gnome.org)
6 //          Marek Safar (marek.safar@seznam.cz)
7 //
8 // Licensed under the terms of the GNU GPL
9 //
10 // (C) 2001, 2002, 2003 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.Runtime.InteropServices;
39
40 namespace Mono.CSharp {
41
42         /// <summary>
43         ///   This is the base class for structs and classes.  
44         /// </summary>
45         public class TypeContainer : DeclSpace, IMemberContainer {
46                 // Holds a list of classes and structures
47                 ArrayList types;
48
49                 // Holds the list of properties
50                 ArrayList properties;
51
52                 // Holds the list of enumerations
53                 ArrayList enums;
54
55                 // Holds the list of delegates
56                 ArrayList delegates;
57                 
58                 // Holds the list of constructors
59                 ArrayList instance_constructors;
60
61                 // Holds the list of fields
62                 ArrayList fields;
63
64                 // Holds a list of fields that have initializers
65                 ArrayList initialized_fields;
66
67                 // Holds a list of static fields that have initializers
68                 ArrayList initialized_static_fields;
69
70                 // Holds the list of constants
71                 ArrayList constants;
72
73                 // Holds the list of
74                 ArrayList interfaces;
75
76                 // Holds order in which interfaces must be closed
77                 ArrayList interface_order;
78                 
79                 // Holds the methods.
80                 ArrayList methods;
81
82                 // Holds the events
83                 ArrayList events;
84
85                 // Holds the indexers
86                 ArrayList indexers;
87
88                 // Holds the operators
89                 ArrayList operators;
90
91                 // The emit context for toplevel objects.
92                 EmitContext ec;
93                 
94                 //
95                 // Pointers to the default constructor and the default static constructor
96                 //
97                 Constructor default_constructor;
98                 Constructor default_static_constructor;
99
100                 //
101                 // Whether we have seen a static constructor for this class or not
102                 //
103                 public bool UserDefinedStaticConstructor = false;
104
105                 //
106                 // Whether we have at least one non-static field
107                 //
108                 bool have_nonstatic_fields = false;
109                 
110                 //
111                 // This one is computed after we can distinguish interfaces
112                 // from classes from the arraylist `type_bases' 
113                 //
114                 string     base_class_name;
115                 public Type base_classs_type;
116
117                 ArrayList type_bases;
118
119                 bool members_defined;
120                 bool members_defined_ok;
121
122                 // The interfaces we implement.
123                 TypeExpr [] ifaces;
124                 Type[] base_inteface_types;
125
126                 // The parent member container and our member cache
127                 IMemberContainer parent_container;
128                 MemberCache member_cache;
129                 
130                 //
131                 // The indexer name for this class
132                 //
133                 public string IndexerName;
134
135                 public TypeContainer ():
136                         this (null, null, "", null, new Location (-1)) {
137                 }
138
139                 public TypeContainer (NamespaceEntry ns, TypeContainer parent, string name, Attributes attrs, Location l)
140                         : base (ns, parent, name, attrs, l)
141                 {
142                         types = new ArrayList ();
143
144                         base_class_name = null;
145                 }
146
147                 public AdditionResult AddConstant (Const constant)
148                 {
149                         AdditionResult res;
150                         string basename = constant.Name;
151                         string fullname = Name + "." + basename;
152
153                         if ((res = IsValid (basename, fullname)) != AdditionResult.Success)
154                                 return res;
155                         
156                         if (constants == null)
157                                 constants = new ArrayList ();
158
159                         constants.Add (constant);
160                         DefineName (fullname, constant);
161
162                         return AdditionResult.Success;
163                 }
164
165                 public AdditionResult AddEnum (Mono.CSharp.Enum e)
166                 {
167                         AdditionResult res;
168
169                         if ((res = IsValid (e.Basename, e.Name)) != AdditionResult.Success)
170                                 return res;
171
172                         if (enums == null)
173                                 enums = new ArrayList ();
174
175                         enums.Add (e);
176                         DefineName (e.Name, e);
177
178                         return AdditionResult.Success;
179                 }
180                 
181                 public AdditionResult AddClass (Class c)
182                 {
183                         AdditionResult res;
184                         string name = c.Basename;
185                         
186                         if ((res = IsValid (name, c.Name)) != AdditionResult.Success)
187                                 return res;
188
189                         DefineName (c.Name, c);
190                         types.Add (c);
191
192                         return AdditionResult.Success;
193                 }
194
195                 public AdditionResult AddStruct (Struct s)
196                 {
197                         AdditionResult res;
198                         string name = s.Basename;
199                         
200                         if ((res = IsValid (name, s.Name)) != AdditionResult.Success)
201                                 return res;
202
203                         DefineName (s.Name, s);
204                         types.Add (s);
205
206                         return AdditionResult.Success;
207                 }
208
209                 public AdditionResult AddDelegate (Delegate d)
210                 {
211                         AdditionResult res;
212                         string name = d.Basename;
213                         
214                         if ((res = IsValid (name, d.Name)) != AdditionResult.Success)
215                                 return res;
216
217                         if (delegates == null)
218                                 delegates = new ArrayList ();
219                         
220                         DefineName (d.Name, d);
221                         delegates.Add (d);
222
223                         return AdditionResult.Success;
224                 }
225
226                 public AdditionResult AddMethod (Method method)
227                 {
228                         string basename = method.Name;
229                         string fullname = Name + "." + basename;
230
231                         Object value = defined_names [fullname];
232
233                         if (value != null && (!(value is Method)))
234                                 return AdditionResult.NameExists;
235
236                         if (basename == Basename)
237                                 return AdditionResult.EnclosingClash;
238
239                         if (methods == null)
240                                 methods = new ArrayList ();
241
242                         if (method.Name.IndexOf ('.') != -1)
243                                 methods.Insert (0, method);
244                         else 
245                                 methods.Add (method);
246                         
247                         if (value == null)
248                                 DefineName (fullname, method);
249
250                         return AdditionResult.Success;
251                 }
252
253                 public AdditionResult AddConstructor (Constructor c)
254                 {
255                         if (c.Name != Basename) 
256                                 return AdditionResult.NotAConstructor;
257
258                         bool is_static = (c.ModFlags & Modifiers.STATIC) != 0;
259                         
260                         if (is_static){
261                                 UserDefinedStaticConstructor = true;
262                                 if (default_static_constructor != null)
263                                         return AdditionResult.MethodExists;
264
265                                 default_static_constructor = c;
266                         } else {
267                                 if (c.IsDefault ()){
268                                         if (default_constructor != null)
269                                                 return AdditionResult.MethodExists;
270                                         default_constructor = c;
271                                 }
272                                 
273                                 if (instance_constructors == null)
274                                         instance_constructors = new ArrayList ();
275                                 
276                                 instance_constructors.Add (c);
277                         }
278                         
279                         return AdditionResult.Success;
280                 }
281                 
282                 public AdditionResult AddInterface (Interface iface)
283                 {
284                         AdditionResult res;
285                         string name = iface.Basename;
286                         
287                         if ((res = IsValid (name, iface.Name)) != AdditionResult.Success)
288                                 return res;
289                         
290                         if (interfaces == null)
291                                 interfaces = new ArrayList ();
292                         interfaces.Add (iface);
293                         DefineName (iface.Name, iface);
294                         
295                         return AdditionResult.Success;
296                 }
297
298                 public AdditionResult AddField (Field field)
299                 {
300                         AdditionResult res;
301                         string basename = field.Name;
302                         string fullname = Name + "." + basename;
303
304                         if ((res = IsValid (basename, fullname)) != AdditionResult.Success)
305                                 return res;
306                         
307                         if (fields == null)
308                                 fields = new ArrayList ();
309                         
310                         fields.Add (field);
311                         
312                         if (field.HasInitializer){
313                                 if ((field.ModFlags & Modifiers.STATIC) != 0){
314                                         if (initialized_static_fields == null)
315                                                 initialized_static_fields = new ArrayList ();
316
317                                         initialized_static_fields.Add (field);
318
319                                 } else {
320                                         if (initialized_fields == null)
321                                                 initialized_fields = new ArrayList ();
322                                 
323                                         initialized_fields.Add (field);
324                                 }
325                         }
326
327                         if ((field.ModFlags & Modifiers.STATIC) == 0)
328                                 have_nonstatic_fields = true;
329
330                         DefineName (fullname, field);
331                         return AdditionResult.Success;
332                 }
333
334                 public AdditionResult AddProperty (Property prop)
335                 {
336                         AdditionResult res;
337
338                         if ((res = AddProperty (prop, prop.Name)) != AdditionResult.Success)
339                                 return res;
340
341                         if (prop.Get != null) {
342                                 if ((res = AddProperty (prop, "get_" + prop.Name)) != AdditionResult.Success)
343                                         return res;
344                         }
345
346                         if (prop.Set != null) {
347                                 if ((res = AddProperty (prop, "set_" + prop.Name)) != AdditionResult.Success)
348                                 return res;
349                         }
350
351                         if (properties == null)
352                                 properties = new ArrayList ();
353
354                         if (prop.Name.IndexOf ('.') != -1)
355                                 properties.Insert (0, prop);
356                         else
357                                 properties.Add (prop);
358
359                         return AdditionResult.Success;
360                 }
361
362                 AdditionResult AddProperty (Property prop, string basename)
363                 {
364                         AdditionResult res;
365                         string fullname = Name + "." + basename;
366
367                         if ((res = IsValid (basename, fullname)) != AdditionResult.Success)
368                                 return res;
369
370                         DefineName (fullname, prop);
371
372                         return AdditionResult.Success;
373                 }
374
375                 public AdditionResult AddEvent (Event e)
376                 {
377                         AdditionResult res;
378                         string basename = e.Name;
379                         string fullname = Name + "." + basename;
380
381                         if ((res = IsValid (basename, fullname)) != AdditionResult.Success)
382                                 return res;
383
384                         if (events == null)
385                                 events = new ArrayList ();
386                         
387                         events.Add (e);
388                         DefineName (fullname, e);
389
390                         return AdditionResult.Success;
391                 }
392
393                 public void AddIndexer (Indexer i)
394                 {
395                         if (indexers == null)
396                                 indexers = new ArrayList ();
397
398                         if (i.ExplicitInterfaceName != null)
399                                 indexers.Insert (0, i);
400                         else
401                                 indexers.Add (i);
402                 }
403
404                 public AdditionResult AddOperator (Operator op)
405                 {
406                         if (operators == null)
407                                 operators = new ArrayList ();
408
409                         operators.Add (op);
410
411                         string basename = op.Name;
412                         string fullname = Name + "." + basename;
413                         if (!defined_names.Contains (fullname))
414                         {
415                                 DefineName (fullname, op);
416                         }
417                         return AdditionResult.Success;
418                 }
419
420                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
421                 {
422                         if (a.Type == TypeManager.default_member_type) {
423                                 if (Indexers != null) {
424                                         Report.Error (646, a.Location,
425                                                       "Cannot specify the DefaultMember attribute on" +
426                                                       " a type containing an indexer");
427                                         return;
428                                 }
429                         }
430                         
431                         base.ApplyAttributeBuilder (a, cb);
432                 } 
433
434                 public override AttributeTargets AttributeTargets {
435                         get {
436                                 throw new NotSupportedException ();
437                         }
438                 }
439
440                 public void RegisterOrder (Interface iface)
441                 {
442                         if (interface_order == null)
443                                 interface_order = new ArrayList ();
444
445                         interface_order.Add (iface);
446                 }
447                 
448                 public ArrayList Types {
449                         get {
450                                 return types;
451                         }
452                 }
453
454                 public ArrayList Methods {
455                         get {
456                                 return methods;
457                         }
458                 }
459
460                 public ArrayList Constants {
461                         get {
462                                 return constants;
463                         }
464                 }
465
466                 public ArrayList Interfaces {
467                         get {
468                                 return interfaces;
469                         }
470                 }
471                 
472                 public string Base {
473                         get {
474                                 return base_class_name;
475                         }
476                 }
477                 
478                 public ArrayList Bases {
479                         get {
480                                 return type_bases;
481                         }
482
483                         set {
484                                 type_bases = value;
485                         }
486                 }
487
488                 public ArrayList Fields {
489                         get {
490                                 return fields;
491                         }
492
493                         set {
494                                 fields = value;
495                         }
496                 }
497
498                 public ArrayList InstanceConstructors {
499                         get {
500                                 return instance_constructors;
501                         }
502                 }
503
504                 public ArrayList Properties {
505                         get {
506                                 return properties;
507                         }
508                 }
509
510                 public ArrayList Events {
511                         get {
512                                 return events;
513                         }
514                 }
515                 
516                 public ArrayList Enums {
517                         get {
518                                 return enums;
519                         }
520                 }
521
522                 public ArrayList Indexers {
523                         get {
524                                 return indexers;
525                         }
526                 }
527
528                 public ArrayList Operators {
529                         get {
530                                 return operators;
531                         }
532                 }
533
534                 public ArrayList Delegates {
535                         get {
536                                 return delegates;
537                         }
538                 }
539
540                 public virtual TypeAttributes TypeAttr {
541                         get {
542                                 return Modifiers.TypeAttr (ModFlags, this);
543                         }
544                 }
545
546                 //
547                 // Emits the instance field initializers
548                 //
549                 public bool EmitFieldInitializers (EmitContext ec)
550                 {
551                         ArrayList fields;
552                         Expression instance_expr;
553                         
554                         if (ec.IsStatic){
555                                 fields = initialized_static_fields;
556                                 instance_expr = null;
557                         } else {
558                                 fields = initialized_fields;
559                                 instance_expr = new This (Location.Null).Resolve (ec);
560                         }
561
562                         if (fields == null)
563                                 return true;
564
565                         foreach (Field f in fields){
566                                 Expression e = f.GetInitializerExpression (ec);
567                                 if (e == null)
568                                         return false;
569
570                                 Location l = f.Location;
571                                 FieldExpr fe = new FieldExpr (f.FieldBuilder, l);
572                                 fe.InstanceExpression = instance_expr;
573                                 ExpressionStatement a = new Assign (fe, e, l);
574
575                                 a = a.ResolveStatement (ec);
576                                 if (a == null)
577                                         return false;
578
579                                 a.EmitStatement (ec);
580                         }
581
582                         return true;
583                 }
584                 
585                 //
586                 // Defines the default constructors
587                 //
588                 void DefineDefaultConstructor (bool is_static)
589                 {
590                         Constructor c;
591
592                         // The default constructor is public
593                         // If the class is abstract, the default constructor is protected
594                         // The default static constructor is private
595
596                         int mods = Modifiers.PUBLIC;
597                         if (is_static)
598                                 mods = Modifiers.STATIC | Modifiers.PRIVATE;
599                         else if ((ModFlags & Modifiers.ABSTRACT) != 0)
600                                 mods = Modifiers.PROTECTED;
601
602                         c = new Constructor (this, Basename, mods, Parameters.EmptyReadOnlyParameters,
603                                              new ConstructorBaseInitializer (
604                                                      null, Parameters.EmptyReadOnlyParameters,
605                                                      Location),
606                                              Location);
607                         
608                         AddConstructor (c);
609                         
610                         c.Block = new ToplevelBlock (null, Location);
611                         
612                 }
613
614                 public void ReportStructInitializedInstanceError ()
615                 {
616                         string n = TypeBuilder.FullName;
617                         
618                         foreach (Field f in initialized_fields){
619                                 Report.Error (
620                                         573, Location,
621                                         "`" + n + "." + f.Name + "': can not have " +
622                                         "instance field initializers in structs");
623                         }
624                 }
625
626                 /// <remarks>
627                 ///  The pending methods that need to be implemented (interfaces or abstract methods)
628                 /// </remarks>
629                 public PendingImplementation Pending;
630
631                 /// <summary>
632                 ///   This function computes the Base class and also the
633                 ///   list of interfaces that the class or struct @c implements.
634                 ///   
635                 ///   The return value is an array (might be null) of
636                 ///   interfaces implemented (as Types).
637                 ///   
638                 ///   The @parent argument is set to the parent object or null
639                 ///   if this is `System.Object'. 
640                 /// </summary>
641                 TypeExpr [] GetClassBases (bool is_class, bool is_iface,
642                                            out TypeExpr parent, out bool error)
643                 {
644                         ArrayList bases = Bases;
645                         int count;
646                         int start, j, i;
647
648                         error = false;
649
650                         if (is_class || is_iface)
651                                 parent = null;
652                         else
653                                 parent = TypeManager.system_valuetype_expr;
654
655                         if (bases == null){
656                                 if (is_class){
657                                         if (RootContext.StdLib)
658                                                 parent = TypeManager.system_object_expr;
659                                         else if (Name != "System.Object")
660                                                 parent = TypeManager.system_object_expr;
661                                 } else {
662                                         //
663                                         // If we are compiling our runtime,
664                                         // and we are defining ValueType, then our
665                                         // parent is `System.Object'.
666                                         //
667                                         if (!RootContext.StdLib && Name == "System.ValueType")
668                                                 parent = TypeManager.system_object_expr;
669                                 }
670
671                                 return null;
672                         }
673
674                         //
675                         // Bases should be null if there are no bases at all
676                         //
677                         count = bases.Count;
678
679                         if (is_class){
680                                 TypeExpr name = ResolveTypeExpr ((Expression) bases [0], false, Location);
681
682                                 if (name == null){
683                                         error = true;
684                                         return null;
685                                 }
686
687                                 if (name.IsClass){
688                                         parent = name;
689                                         start = 1;
690                                 } else {
691                                         parent = TypeManager.system_object_expr;
692                                         start = 0;
693                                 }
694                                 if (name.IsSealed){
695                                         string detail = "";
696                                         
697                                         if (name.IsValueType)
698                                                 detail = " (a class can not inherit from a struct/enum)";
699                                         
700                                         Report.Error (509, "class `"+ Name +
701                                                       "': Cannot inherit from sealed class `"+
702                                                       name.Name + "'" + detail);
703                                         error = true;
704                                         return null;
705                                 }
706
707                                 if (!parent.CanInheritFrom ()){
708                                         Report.Error (644, Location,
709                                                       "`{0}' cannot inherit from special class `{1}'",
710                                                       Name, parent.Name);
711                                         error = true;
712                                         return null;
713                                 }
714
715                                 if (!parent.AsAccessible (this, ModFlags))
716                                         Report.Error (60, Location,
717                                                       "Inconsistent accessibility: base class `" +
718                                                       name.Name + "' is less accessible than class `" +
719                                                       Name + "'");
720
721                         } else {
722                                 start = 0;
723                         }
724
725                         if (parent != null)
726                                 base_class_name = parent.Name;
727
728                         TypeExpr [] ifaces = new TypeExpr [count-start];
729                         
730                         for (i = start, j = 0; i < count; i++, j++){
731                                 Expression name = (Expression) bases [i];
732                                 TypeExpr resolved = ResolveTypeExpr (name, false, Location);
733                                 if (resolved == null)
734                                         return null;
735                                 
736                                 bases [i] = resolved;
737
738                                 if (is_class == false && !resolved.IsInterface){
739                                         Report.Error (527, "In Struct `" + Name + "', type `"+
740                                                       name +"' is not an interface");
741                                         error = true;
742                                         return null;
743                                 }
744                                 
745                                 if (resolved.IsClass) {
746                                         if (parent != null){
747                                                 Report.Error (527, "In Class `" + Name + "', type `"+
748                                                               name+"' is not an interface");
749                                                 error = true;
750                                                 return null;
751                                         }
752                                 }
753
754                                 for (int x = 0; x < j; x++) {
755                                         if (resolved.Equals (ifaces [x])) {
756                                                 Report.Error (528, "`" + name + "' is already listed in interface list");
757                                                 error = true;
758                                                 return null;
759                                         }
760                                 }
761
762                                 if (is_iface &&
763                                     !resolved.AsAccessible (Parent, ModFlags))
764                                         Report.Error (61, Location,
765                                                       "Inconsistent accessibility: base interface `" +
766                                                       name + "' is less accessible than interface `" +
767                                                       Name + "'");
768
769                                 ifaces [j] = resolved;
770                         }
771
772                         return TypeManager.ExpandInterfaces (ifaces);
773                 }
774
775                 bool error = false;
776                 
777                 //
778                 // Defines the type in the appropriate ModuleBuilder or TypeBuilder.
779                 //
780                 public override TypeBuilder DefineType ()
781                 {
782                         TypeExpr parent;
783                         bool is_class, is_iface;
784
785                         if (TypeBuilder != null)
786                                 return TypeBuilder;
787
788                         if (error)
789                                 return null;
790                         
791                         if (InTransit) {
792                                 Report.Error (146, Location, "Class definition is circular: `{0}'", Name);
793                                 error = true;
794                                 return null;
795                         }
796                         
797                         InTransit = true;
798
799                         if (this is Interface) {
800                                 is_iface = true;
801                                 is_class = false;
802                         } else {
803                                 is_iface = false;
804                                 if (this is Class)
805                                         is_class = true;
806                                 else
807                                         is_class = false;
808                         }
809
810                         ec = new EmitContext (this, Mono.CSharp.Location.Null, null, null, ModFlags);
811
812                         ifaces = GetClassBases (is_class, is_iface, out parent, out error); 
813
814                         if (error)
815                                 return null;
816
817                         if (!is_class && TypeManager.value_type == null)
818                                 throw new Exception ();
819
820                         TypeAttributes type_attributes = TypeAttr;
821
822                         if (parent != null)
823                                 base_classs_type = parent.ResolveType (ec);
824
825                         if (IsTopLevel){
826                                 if (TypeManager.NamespaceClash (Name, Location)) {
827                                         error = true;
828                                         return null;
829                                 }
830                                 
831                                 ModuleBuilder builder = CodeGen.Module.Builder;
832                                 TypeBuilder = builder.DefineType (
833                                         Name, type_attributes, base_classs_type, null);
834                                 
835                         } else {
836                                 TypeBuilder builder = Parent.DefineType ();
837                                 if (builder == null)
838                                         return null;
839                                 
840                                 TypeBuilder = builder.DefineNestedType (
841                                         Basename, type_attributes, base_classs_type, null);
842                         }
843                                 
844                         //
845                         // Structs with no fields need to have at least one byte.
846                         // The right thing would be to set the PackingSize in a DefineType
847                         // but there are no functions that allow interfaces *and* the size to
848                         // be specified.
849                         //
850
851                         if (!is_class && !is_iface && !have_nonstatic_fields){
852                                 TypeBuilder.DefineField ("$PRIVATE$", TypeManager.byte_type,
853                                                          FieldAttributes.Private);
854                         }
855
856                         // add interfaces that were not added at type creation
857                         if (ifaces != null) {
858                                 base_inteface_types = new Type[ifaces.Length];
859                                 for (int i = 0; i < ifaces.Length; ++i) {
860                                         Type itype = ifaces [i].ResolveType (ec);
861                                         TypeBuilder.AddInterfaceImplementation (itype);
862                                         base_inteface_types [i] = itype;
863                                 }
864                         }
865
866                         //
867                         // Finish the setup for the EmitContext
868                         //
869                         ec.ContainerType = TypeBuilder;
870
871                         TypeManager.AddUserType (Name, TypeBuilder, this, ifaces);
872
873                         if ((parent != null) && parent.IsAttribute) {
874                                 RootContext.RegisterAttribute (this);
875                         } else
876                                 RootContext.RegisterOrder (this); 
877                                 
878                         if (Interfaces != null) {
879                                 foreach (Interface iface in Interfaces)
880                                         if (iface.DefineType () == null) {
881                                                 error = true;
882                                                 return null;
883                                         }
884                         }
885                         
886                         if (Types != null) {
887                                 foreach (TypeContainer tc in Types)
888                                         if (tc.DefineType () == null) {
889                                                 error = true;
890                                                 return null;
891                                         }
892                         }
893
894                         if (Delegates != null) {
895                                 foreach (Delegate d in Delegates)
896                                         if (d.DefineType () == null) {
897                                                 error = true;
898                                                 return null;
899                                         }
900                         }
901
902                         if (Enums != null) {
903                                 foreach (Enum en in Enums)
904                                         if (en.DefineType () == null) {
905                                                 error = true;
906                                                 return null;
907                                         }
908                         }
909
910                         InTransit = false;
911                         return TypeBuilder;
912                 }
913
914
915                 /// <summary>
916                 ///   Defines the MemberCore objects that are in the `list' Arraylist
917                 ///
918                 ///   The `defined_names' array contains a list of members defined in
919                 ///   a base class
920                 /// </summary>
921                 static ArrayList remove_list = new ArrayList ();
922                 void DefineMembers (ArrayList list, MemberInfo [] defined_names)
923                 {
924                         int idx;
925                         
926                         remove_list.Clear ();
927
928                         foreach (MemberCore mc in list){
929
930                                 if (defined_names != null)
931                                         idx = Array.BinarySearch (defined_names, mc.Name, mif_compare);
932                                 else
933                                         idx = -1;
934
935                                 if (idx < 0){
936                                         if (RootContext.WarningLevel >= 4){
937                                                 if ((mc.ModFlags & Modifiers.NEW) != 0)
938                                                         Warning_KeywordNewNotRequired (mc.Location, mc);
939                                         }
940                                 } else if (mc is MethodCore)
941                                         ((MethodCore) mc).OverridesSomething = true;
942
943                                 if (!mc.Define (this)){
944                                         remove_list.Add (mc);
945                                         continue;
946                                 }
947                                                 
948                                 if (idx < 0)
949                                         continue;
950
951                                 MemberInfo match = defined_names [idx];
952
953                                 if (match is PropertyInfo && ((mc.ModFlags & Modifiers.OVERRIDE) != 0))
954                                         continue;
955
956                                 //
957                                 // If we are both methods, let the method resolution emit warnings
958                                 //
959                                 if (match is MethodBase && mc is MethodCore)
960                                         continue; 
961
962                                 if ((mc.ModFlags & Modifiers.NEW) == 0) {
963                                         if (mc is Event) {
964                                                 if (!(match is EventInfo)) {
965                                                         Error_EventCanOnlyOverrideEvent (mc.Location, defined_names [idx]);
966                                                         return;
967                                                 }
968
969                                                 if ((mc.ModFlags & Modifiers.OVERRIDE) != 0)
970                                                         continue;
971                                         }
972
973                                         Warning_KeywordNewRequired (mc.Location, defined_names [idx]);
974                                 }
975                         }
976                         
977                         foreach (object o in remove_list)
978                                 list.Remove (o);
979                         
980                         remove_list.Clear ();
981                 }
982
983                 //
984                 // Defines the indexers, and also verifies that the IndexerNameAttribute in the
985                 // class is consistent.  Either it is `Item' or it is the name defined by all the
986                 // indexers with the `IndexerName' attribute.
987                 //
988                 // Turns out that the IndexerNameAttribute is applied to each indexer,
989                 // but it is never emitted, instead a DefaultMember attribute is attached
990                 // to the class.
991                 //
992                 void DefineIndexers ()
993                 {
994                         string class_indexer_name = null;
995
996                         //
997                         // If there's both an explicit and an implicit interface implementation, the
998                         // explicit one actually implements the interface while the other one is just
999                         // a normal indexer.  See bug #37714.
1000                         //
1001
1002                         // Invariant maintained by AddIndexer(): All explicit interface indexers precede normal indexers
1003                         bool seen_normal_indexers = false;
1004
1005                         foreach (Indexer i in Indexers) {
1006                                 string name;
1007
1008                                 i.Define (this);
1009
1010                                 name = i.IndexerName;
1011
1012                                 if (i.InterfaceType != null) {
1013                                         if (seen_normal_indexers)
1014                                                 throw new Exception ("Internal Error: 'Indexers' array not sorted properly.");
1015                                         continue;
1016                                 }
1017
1018                                 seen_normal_indexers = true;
1019
1020                                 if (class_indexer_name == null)
1021                                         class_indexer_name = name;
1022                                 else if (name != class_indexer_name)
1023                                         Report.Error (668, i.Location, "Two indexers have different names, " +
1024                                                       " you should use the same name for all your indexers");
1025                         }
1026
1027                         if (seen_normal_indexers && class_indexer_name == null)
1028                                 class_indexer_name = "Item";
1029                         IndexerName = class_indexer_name;
1030                 }
1031
1032                 static void Error_KeywordNotAllowed (Location loc)
1033                 {
1034                         Report.Error (1530, loc, "Keyword new not allowed for namespace elements");
1035                 }
1036
1037                 /// <summary>
1038                 ///   Populates our TypeBuilder with fields and methods
1039                 /// </summary>
1040                 public override bool DefineMembers (TypeContainer container)
1041                 {
1042                         if (members_defined)
1043                                 return members_defined_ok;
1044
1045                         members_defined_ok = DoDefineMembers ();
1046                         members_defined = true;
1047
1048                         return members_defined_ok;
1049                 }
1050
1051                 bool DoDefineMembers ()
1052                 {
1053                         MemberInfo [] defined_names = null;
1054
1055                         //
1056                         // We need to be able to use the member cache while we are checking/defining
1057                         //
1058 #if CACHE
1059                         if (TypeBuilder.BaseType != null)
1060                                 parent_container = TypeManager.LookupMemberContainer (TypeBuilder.BaseType);
1061 #endif
1062
1063                         if (interface_order != null){
1064                                 foreach (Interface iface in interface_order)
1065                                         if ((iface.ModFlags & Modifiers.NEW) == 0)
1066                                                 iface.DefineMembers (this);
1067                                         else
1068                                                 Error_KeywordNotAllowed (iface.Location);
1069                         }
1070
1071                         if (RootContext.WarningLevel > 1){
1072                                 Type ptype;
1073
1074                                 //
1075                                 // This code throws an exception in the comparer
1076                                 // I guess the string is not an object?
1077                                 //
1078                                 ptype = TypeBuilder.BaseType;
1079                                 if (ptype != null){
1080                                         defined_names = (MemberInfo []) FindMembers (
1081                                                 ptype, MemberTypes.All & ~MemberTypes.Constructor,
1082                                                 BindingFlags.Public | BindingFlags.Instance |
1083                                                 BindingFlags.Static, null, null);
1084
1085                                         Array.Sort (defined_names, mif_compare);
1086                                 }
1087                         }
1088
1089                         Class pclass = Parent as Class;
1090                         if (pclass != null) {
1091                                 string pname = null;
1092                                 Type ptype = null;
1093                                 Type t = pclass.TypeBuilder.BaseType;
1094                                 while ((t != null) && (ptype == null)) {
1095                                         pname = t.FullName + "." + Basename;
1096                                         ptype = RootContext.LookupType (this, pname, true, Location.Null);
1097                                         t = t.BaseType;
1098                                 }
1099
1100                                 if ((ModFlags & Modifiers.NEW) != 0) {
1101                                         if (ptype == null)
1102                                                 Report.Warning (109, Location, "The member '" + Name + "' does not hide an " +
1103                                                                 "inherited member. The keyword new is not required.");
1104                                 } else if (ptype != null) {
1105                                         Report.Warning (108, Location, "The keyword new is required on `" +
1106                                                         Name + "' because it hides inherited member '" +
1107                                                         pname + "'.");
1108                                 }
1109                         } else if ((ModFlags & Modifiers.NEW) != 0)
1110                                 Error_KeywordNotAllowed (Location);
1111
1112                         if (constants != null)
1113                                 DefineMembers (constants, defined_names);
1114
1115                         if (fields != null)
1116                                 DefineMembers (fields, defined_names);
1117
1118                         if (this is Class){
1119                                 if (instance_constructors == null){
1120                                         if (default_constructor == null)
1121                                                 DefineDefaultConstructor (false);
1122                                 }
1123
1124                                 if (initialized_static_fields != null &&
1125                                     default_static_constructor == null)
1126                                         DefineDefaultConstructor (true);
1127                         }
1128
1129                         if (this is Struct){
1130                                 //
1131                                 // Structs can not have initialized instance
1132                                 // fields
1133                                 //
1134                                 if (initialized_static_fields != null &&
1135                                     default_static_constructor == null)
1136                                         DefineDefaultConstructor (true);
1137
1138                                 if (initialized_fields != null)
1139                                         ReportStructInitializedInstanceError ();
1140                         }
1141
1142                         if (!(this is Interface))
1143                                 Pending = PendingImplementation.GetPendingImplementations (this);
1144                         
1145                         //
1146                         // Constructors are not in the defined_names array
1147                         //
1148                         if (instance_constructors != null)
1149                                 DefineMembers (instance_constructors, null);
1150                 
1151                         if (default_static_constructor != null)
1152                                 default_static_constructor.Define (this);
1153                         
1154                         if (methods != null)
1155                                 DefineMembers (methods, defined_names);
1156
1157                         if (properties != null)
1158                                 DefineMembers (properties, defined_names);
1159
1160                         if (events != null)
1161                                 DefineMembers (events, defined_names);
1162
1163                         if (indexers != null)
1164                                 DefineIndexers ();
1165
1166                         if (operators != null){
1167                                 DefineMembers (operators, null);
1168
1169                                 CheckPairedOperators ();
1170                         }
1171
1172                         if (enums != null)
1173                                 DefineMembers (enums, defined_names);
1174                         
1175                         if (delegates != null)
1176                                 DefineMembers (delegates, defined_names);
1177
1178 #if CACHE
1179                         member_cache = new MemberCache (this);
1180 #endif
1181
1182                         
1183                         return true;
1184                 }
1185
1186                 public override bool Define (TypeContainer container)
1187                 {
1188                         if (interface_order != null){
1189                                 foreach (Interface iface in interface_order)
1190                                         if ((iface.ModFlags & Modifiers.NEW) == 0)
1191                                                 iface.Define (this);
1192                         }
1193
1194                         return true;
1195                 }
1196
1197                 /// <summary>
1198                 ///   This function is based by a delegate to the FindMembers routine
1199                 /// </summary>
1200                 static bool AlwaysAccept (MemberInfo m, object filterCriteria)
1201                 {
1202                         return true;
1203                 }
1204
1205                 /// <summary>
1206                 ///   This filter is used by FindMembers, and we just keep
1207                 ///   a global for the filter to `AlwaysAccept'
1208                 /// </summary>
1209                 static MemberFilter accepting_filter;
1210
1211                 
1212                 /// <summary>
1213                 ///   A member comparission method based on name only
1214                 /// </summary>
1215                 static IComparer mif_compare;
1216
1217                 static TypeContainer ()
1218                 {
1219                         accepting_filter = new MemberFilter (AlwaysAccept);
1220                         mif_compare = new MemberInfoCompare ();
1221                 }
1222
1223                 public MethodInfo[] GetMethods ()
1224                 {
1225                         ArrayList members = new ArrayList ();
1226
1227                         DefineMembers (null);
1228
1229                         if (methods != null) {
1230                                 int len = methods.Count;
1231                                 for (int i = 0; i < len; i++) {
1232                                         Method m = (Method) methods [i];
1233
1234                                         members.Add (m.MethodBuilder);
1235                                 }
1236                         }
1237
1238                         if (operators != null) {
1239                                 int len = operators.Count;
1240                                 for (int i = 0; i < len; i++) {
1241                                         Operator o = (Operator) operators [i];
1242
1243                                         members.Add (o.OperatorMethodBuilder);
1244                                 }
1245                         }
1246
1247                         if (properties != null) {
1248                                 int len = properties.Count;
1249                                 for (int i = 0; i < len; i++) {
1250                                         Property p = (Property) properties [i];
1251
1252                                         if (p.GetBuilder != null)
1253                                                 members.Add (p.GetBuilder);
1254                                         if (p.SetBuilder != null)
1255                                                 members.Add (p.SetBuilder);
1256                                 }
1257                         }
1258                                 
1259                         if (indexers != null) {
1260                                 int len = indexers.Count;
1261                                 for (int i = 0; i < len; i++) {
1262                                         Indexer ix = (Indexer) indexers [i];
1263
1264                                         if (ix.GetBuilder != null)
1265                                                 members.Add (ix.GetBuilder);
1266                                         if (ix.SetBuilder != null)
1267                                                 members.Add (ix.SetBuilder);
1268                                 }
1269                         }
1270
1271                         if (events != null) {
1272                                 int len = events.Count;
1273                                 for (int i = 0; i < len; i++) {
1274                                         Event e = (Event) events [i];
1275
1276                                         if (e.AddBuilder != null)
1277                                                 members.Add (e.AddBuilder);
1278                                         if (e.RemoveBuilder != null)
1279                                                 members.Add (e.RemoveBuilder);
1280                                 }
1281                         }
1282
1283                         MethodInfo[] retMethods = new MethodInfo [members.Count];
1284                         members.CopyTo (retMethods, 0);
1285                         return retMethods;
1286                 }
1287                 
1288                 /// <summary>
1289                 ///   This method returns the members of this type just like Type.FindMembers would
1290                 ///   Only, we need to use this for types which are _being_ defined because MS' 
1291                 ///   implementation can't take care of that.
1292                 /// </summary>
1293                 //
1294                 // FIXME: return an empty static array instead of null, that cleans up
1295                 // some code and is consistent with some coding conventions I just found
1296                 // out existed ;-)
1297                 //
1298                 //
1299                 // Notice that in various cases we check if our field is non-null,
1300                 // something that would normally mean that there was a bug elsewhere.
1301                 //
1302                 // The problem happens while we are defining p-invoke methods, as those
1303                 // will trigger a FindMembers, but this happens before things are defined
1304                 //
1305                 // Since the whole process is a no-op, it is fine to check for null here.
1306                 //
1307                 public override MemberList FindMembers (MemberTypes mt, BindingFlags bf,
1308                                                         MemberFilter filter, object criteria)
1309                 {
1310                         ArrayList members = null;
1311
1312                         int modflags = 0;
1313                         if ((bf & BindingFlags.Public) != 0)
1314                                 modflags |= Modifiers.PUBLIC | Modifiers.PROTECTED |
1315                                         Modifiers.INTERNAL;
1316                         if ((bf & BindingFlags.NonPublic) != 0)
1317                                 modflags |= Modifiers.PRIVATE;
1318
1319                         int static_mask = 0, static_flags = 0;
1320                         switch (bf & (BindingFlags.Static | BindingFlags.Instance)) {
1321                         case BindingFlags.Static:
1322                                 static_mask = static_flags = Modifiers.STATIC;
1323                                 break;
1324
1325                         case BindingFlags.Instance:
1326                                 static_mask = Modifiers.STATIC;
1327                                 static_flags = 0;
1328                                 break;
1329
1330                         default:
1331                                 static_mask = static_flags = 0;
1332                                 break;
1333                         }
1334
1335                         Timer.StartTimer (TimerType.TcFindMembers);
1336
1337                         if (filter == null)
1338                                 filter = accepting_filter; 
1339
1340                         if ((mt & MemberTypes.Field) != 0) {
1341                                 if (fields != null) {
1342                                         int len = fields.Count;
1343                                         for (int i = 0; i < len; i++) {
1344                                                 Field f = (Field) fields [i];
1345                                                 
1346                                                 if ((f.ModFlags & modflags) == 0)
1347                                                         continue;
1348                                                 if ((f.ModFlags & static_mask) != static_flags)
1349                                                         continue;
1350
1351                                                 FieldBuilder fb = f.FieldBuilder;
1352                                                 if (fb != null && filter (fb, criteria) == true) {
1353                                                         if (members == null)
1354                                                                 members = new ArrayList ();
1355                                                         
1356                                                         members.Add (fb);
1357                                                 }
1358                                         }
1359                                 }
1360
1361                                 if (constants != null) {
1362                                         int len = constants.Count;
1363                                         for (int i = 0; i < len; i++) {
1364                                                 Const con = (Const) constants [i];
1365                                                 
1366                                                 if ((con.ModFlags & modflags) == 0)
1367                                                         continue;
1368                                                 if ((con.ModFlags & static_mask) != static_flags)
1369                                                         continue;
1370
1371                                                 FieldBuilder fb = con.FieldBuilder;
1372                                                 if (fb != null && filter (fb, criteria) == true) {
1373                                                         if (members == null)
1374                                                                 members = new ArrayList ();
1375                                                         
1376                                                         members.Add (fb);
1377                                                 }
1378                                         }
1379                                 }
1380                         }
1381
1382                         if ((mt & MemberTypes.Method) != 0) {
1383                                 if (methods != null) {
1384                                         int len = methods.Count;
1385                                         for (int i = 0; i < len; i++) {
1386                                                 Method m = (Method) methods [i];
1387                                                 
1388                                                 if ((m.ModFlags & modflags) == 0)
1389                                                         continue;
1390                                                 if ((m.ModFlags & static_mask) != static_flags)
1391                                                         continue;
1392                                                 
1393                                                 MethodBuilder mb = m.MethodBuilder;
1394
1395                                                 if (mb != null && filter (mb, criteria) == true) {
1396                                                         if (members == null)
1397                                                                 members = new ArrayList ();
1398                                                         
1399                                                         members.Add (mb);
1400                                                 }
1401                                         }
1402                                 }
1403
1404                                 if (operators != null) {
1405                                         int len = operators.Count;
1406                                         for (int i = 0; i < len; i++) {
1407                                                 Operator o = (Operator) operators [i];
1408                                                 
1409                                                 if ((o.ModFlags & modflags) == 0)
1410                                                         continue;
1411                                                 if ((o.ModFlags & static_mask) != static_flags)
1412                                                         continue;
1413                                                 
1414                                                 MethodBuilder ob = o.OperatorMethodBuilder;
1415                                                 if (ob != null && filter (ob, criteria) == true) {
1416                                                         if (members == null)
1417                                                                 members = new ArrayList ();
1418                                                         
1419                                                         members.Add (ob);
1420                                                 }
1421                                         }
1422                                 }
1423
1424                                 if (properties != null) {
1425                                         int len = properties.Count;
1426                                         for (int i = 0; i < len; i++) {
1427                                                 Property p = (Property) properties [i];
1428                                                 
1429                                                 if ((p.ModFlags & modflags) == 0)
1430                                                         continue;
1431                                                 if ((p.ModFlags & static_mask) != static_flags)
1432                                                         continue;
1433                                                 
1434                                                 MethodBuilder b;
1435
1436                                                 b = p.GetBuilder;
1437                                                 if (b != null && filter (b, criteria) == true) {
1438                                                         if (members == null)
1439                                                                 members = new ArrayList ();
1440                                                         
1441                                                         members.Add (b);
1442                                                 }
1443
1444                                                 b = p.SetBuilder;
1445                                                 if (b != null && filter (b, criteria) == true) {
1446                                                         if (members == null)
1447                                                                 members = new ArrayList ();
1448                                                         
1449                                                         members.Add (b);
1450                                                 }
1451                                         }
1452                                 }
1453                                 
1454                                 if (indexers != null) {
1455                                         int len = indexers.Count;
1456                                         for (int i = 0; i < len; i++) {
1457                                                 Indexer ix = (Indexer) indexers [i];
1458                                                 
1459                                                 if ((ix.ModFlags & modflags) == 0)
1460                                                         continue;
1461                                                 if ((ix.ModFlags & static_mask) != static_flags)
1462                                                         continue;
1463                                                 
1464                                                 MethodBuilder b;
1465
1466                                                 b = ix.GetBuilder;
1467                                                 if (b != null && filter (b, criteria) == true) {
1468                                                         if (members == null)
1469                                                                 members = new ArrayList ();
1470                                                         
1471                                                         members.Add (b);
1472                                                 }
1473
1474                                                 b = ix.SetBuilder;
1475                                                 if (b != null && filter (b, criteria) == true) {
1476                                                         if (members == null)
1477                                                                 members = new ArrayList ();
1478                                                         
1479                                                         members.Add (b);
1480                                                 }
1481                                         }
1482                                 }
1483                         }
1484
1485                         if ((mt & MemberTypes.Event) != 0) {
1486                                 if (events != null) {
1487                                         int len = events.Count;
1488                                         for (int i = 0; i < len; i++) {
1489                                                 Event e = (Event) events [i];
1490                                                 
1491                                                 if ((e.ModFlags & modflags) == 0)
1492                                                         continue;
1493                                                 if ((e.ModFlags & static_mask) != static_flags)
1494                                                         continue;
1495
1496                                                 MemberInfo eb = e.EventBuilder;
1497                                                 if (eb != null && filter (eb, criteria) == true) {
1498                                                         if (members == null)
1499                                                                 members = new ArrayList ();
1500                                                         
1501                                                         members.Add (e.EventBuilder);
1502                                                 }
1503                                         }
1504                                 }
1505                         }
1506                         
1507                         if ((mt & MemberTypes.Property) != 0){
1508                                 if (properties != null) {
1509                                         int len = properties.Count;
1510                                         for (int i = 0; i < len; i++) {
1511                                                 Property p = (Property) properties [i];
1512                                                 
1513                                                 if ((p.ModFlags & modflags) == 0)
1514                                                         continue;
1515                                                 if ((p.ModFlags & static_mask) != static_flags)
1516                                                         continue;
1517
1518                                                 MemberInfo pb = p.PropertyBuilder;
1519                                                 if (pb != null && filter (pb, criteria) == true) {
1520                                                         if (members == null)
1521                                                                 members = new ArrayList ();
1522                                                         
1523                                                         members.Add (p.PropertyBuilder);
1524                                                 }
1525                                         }
1526                                 }
1527
1528                                 if (indexers != null) {
1529                                         int len = indexers.Count;
1530                                         for (int i = 0; i < len; i++) {
1531                                                 Indexer ix = (Indexer) indexers [i];
1532                                                 
1533                                                 if ((ix.ModFlags & modflags) == 0)
1534                                                         continue;
1535                                                 if ((ix.ModFlags & static_mask) != static_flags)
1536                                                         continue;
1537
1538                                                 MemberInfo ib = ix.PropertyBuilder;
1539                                                 if (ib != null && filter (ib, criteria) == true) {
1540                                                         if (members == null)
1541                                                                 members = new ArrayList ();
1542                                                         
1543                                                         members.Add (ix.PropertyBuilder);
1544                                                 }
1545                                         }
1546                                 }
1547                         }
1548                         
1549                         if ((mt & MemberTypes.NestedType) != 0) {
1550                                 if (types != null) {
1551                                         int len = types.Count;
1552                                         for (int i = 0; i < len; i++) {
1553                                                 TypeContainer t = (TypeContainer) types [i];
1554                                                 
1555                                                 if ((t.ModFlags & modflags) == 0)
1556                                                         continue;
1557
1558                                                 TypeBuilder tb = t.TypeBuilder;
1559                                                 if (tb != null && (filter (tb, criteria) == true)) {
1560                                                         if (members == null)
1561                                                                 members = new ArrayList ();
1562                                                         
1563                                                         members.Add (tb);
1564                                                 }
1565                                         }
1566                                 }
1567
1568                                 if (enums != null) {
1569                                         int len = enums.Count;
1570                                         for (int i = 0; i < len; i++) {
1571                                                 Enum en = (Enum) enums [i];
1572                                                 
1573                                                 if ((en.ModFlags & modflags) == 0)
1574                                                         continue;
1575
1576                                                 TypeBuilder tb = en.TypeBuilder;
1577                                                 if (tb != null && (filter (tb, criteria) == true)) {
1578                                                         if (members == null)
1579                                                                 members = new ArrayList ();
1580                                                         
1581                                                         members.Add (tb);
1582                                                 }
1583                                         }
1584                                 }
1585                                 
1586                                 if (delegates != null) {
1587                                         int len = delegates.Count;
1588                                         for (int i = 0; i < len; i++) {
1589                                                 Delegate d = (Delegate) delegates [i];
1590                                                 
1591                                                 if ((d.ModFlags & modflags) == 0)
1592                                                         continue;
1593
1594                                                 TypeBuilder tb = d.TypeBuilder;
1595                                                 if (tb != null && (filter (tb, criteria) == true)) {
1596                                                         if (members == null)
1597                                                                 members = new ArrayList ();
1598                                                         
1599                                                         members.Add (tb);
1600                                                 }
1601                                         }
1602                                 }
1603
1604                                 if (interfaces != null) {
1605                                         int len = interfaces.Count;
1606                                         for (int i = 0; i < len; i++) {
1607                                                 Interface iface = (Interface) interfaces [i];
1608                                                 
1609                                                 if ((iface.ModFlags & modflags) == 0)
1610                                                         continue;
1611
1612                                                 TypeBuilder tb = iface.TypeBuilder;
1613                                                 if (tb != null && (filter (tb, criteria) == true)) {
1614                                                         if (members == null)
1615                                                                 members = new ArrayList ();
1616                                                         
1617                                                         members.Add (tb);
1618                                                 }
1619                                         }
1620                                 }
1621                         }
1622
1623                         if ((mt & MemberTypes.Constructor) != 0){
1624                                 if (((bf & BindingFlags.Instance) != 0) && (instance_constructors != null)){
1625                                         int len = instance_constructors.Count;
1626                                         for (int i = 0; i < len; i++) {
1627                                                 Constructor c = (Constructor) instance_constructors [i];
1628                                                 
1629                                                 ConstructorBuilder cb = c.ConstructorBuilder;
1630                                                 if (cb != null && filter (cb, criteria) == true) {
1631                                                         if (members == null)
1632                                                                 members = new ArrayList ();
1633                                                         
1634                                                         members.Add (cb);
1635                                                 }
1636                                         }
1637                                 }
1638
1639                                 if (((bf & BindingFlags.Static) != 0) && (default_static_constructor != null)){
1640                                         ConstructorBuilder cb =
1641                                                 default_static_constructor.ConstructorBuilder;
1642                                         
1643                                         if (cb != null && filter (cb, criteria) == true) {
1644                                                 if (members == null)
1645                                                         members = new ArrayList ();
1646                                                 
1647                                                 members.Add (cb);
1648                                         }
1649                                 }
1650                         }
1651
1652                         //
1653                         // Lookup members in parent if requested.
1654                         //
1655                         if ((bf & BindingFlags.DeclaredOnly) == 0) {
1656                                 if (TypeBuilder.BaseType != null) {
1657                                         MemberList list = FindMembers (TypeBuilder.BaseType, mt, bf, filter, criteria);
1658                                         if (list.Count > 0) {
1659                                                 if (members == null)
1660                                                         members = new ArrayList ();
1661                                         
1662                                                 members.AddRange (list);
1663                                         }
1664                                 }
1665                                 if (base_inteface_types != null) {
1666                                         foreach (Type base_type in base_inteface_types) {
1667                                                 MemberList list = TypeContainer.FindMembers (base_type, mt, bf, filter, criteria);
1668
1669                                                 if (list.Count > 0) {
1670                                                         if (members == null)
1671                                                                 members = new ArrayList ();
1672                                                         members.AddRange (list);
1673                                                 }
1674                                         }
1675                                 }
1676                         }
1677
1678                         Timer.StopTimer (TimerType.TcFindMembers);
1679
1680                         if (members == null)
1681                                 return MemberList.Empty;
1682                         else
1683                                 return new MemberList (members);
1684                 }
1685
1686                 public override MemberCache MemberCache {
1687                         get {
1688                                 return member_cache;
1689                         }
1690                 }
1691
1692                 public static MemberList FindMembers (Type t, MemberTypes mt, BindingFlags bf,
1693                                                       MemberFilter filter, object criteria)
1694                 {
1695                         DeclSpace ds = TypeManager.LookupDeclSpace (t);
1696
1697                         if (ds != null)
1698                                 return ds.FindMembers (mt, bf, filter, criteria);
1699                         else
1700                                 return new MemberList (t.FindMembers (mt, bf, filter, criteria));
1701                         
1702                 }
1703
1704                 //
1705                 // FindMethods will look for methods not only in the type `t', but in
1706                 // any interfaces implemented by the type.
1707                 //
1708                 public static MethodInfo [] FindMethods (Type t, BindingFlags bf,
1709                                                          MemberFilter filter, object criteria)
1710                 {
1711                         return null;
1712                 }
1713
1714                 /// <summary>
1715                 ///   Emits the values for the constants
1716                 /// </summary>
1717                 public void EmitConstants ()
1718                 {
1719                         if (constants != null)
1720                                 foreach (Const con in constants)
1721                                         con.Emit (this);
1722                         return;
1723                 }
1724
1725                 protected virtual void VerifyMembers (EmitContext ec)
1726                 {
1727                         //
1728                         // Check for internal or private fields that were never assigned
1729                         //
1730                         if (RootContext.WarningLevel >= 3) {
1731                                 if (fields != null){
1732                                         foreach (Field f in fields) {
1733                                                 if ((f.ModFlags & Modifiers.Accessibility) != Modifiers.PRIVATE)
1734                                                         continue;
1735                                                 
1736                                                 if ((f.status & Field.Status.USED) == 0){
1737                                                         Report.Warning (
1738                                                                 169, f.Location, "Private field " +
1739                                                                 MakeName (f.Name) + " is never used");
1740                                                         continue;
1741                                                 }
1742                                                 
1743                                                 //
1744                                                 // Only report 649 on level 4
1745                                                 //
1746                                                 if (RootContext.WarningLevel < 4)
1747                                                         continue;
1748                                                 
1749                                                 if ((f.status & Field.Status.ASSIGNED) != 0)
1750                                                         continue;
1751                                                 
1752                                                 Report.Warning (
1753                                                         649, f.Location,
1754                                                         "Field " + MakeName (f.Name) + " is never assigned " +
1755                                                         " to and will always have its default value");
1756                                         }
1757                                 }
1758
1759                                 if (events != null){
1760                                         foreach (Event e in events){
1761                                                 if (e.status == 0)
1762                                                         Report.Warning (67, "The event " + MakeName (e.Name) + " is never used");
1763                                         }
1764                                 }
1765                         }
1766                 }
1767
1768                 /// <summary>
1769                 ///   Emits the code, this step is performed after all
1770                 ///   the types, enumerations, constructors
1771                 /// </summary>
1772                 public void Emit ()
1773                 {
1774                         if (OptAttributes != null)
1775                                 OptAttributes.Emit (ec, this);
1776                                 
1777                         Emit (this);
1778
1779                         if (instance_constructors != null) {
1780                                 if (TypeBuilder.IsSubclassOf (TypeManager.attribute_type) && IsClsCompliaceRequired (this)) {
1781                                         bool has_compliant_args = false;
1782
1783                                         foreach (Constructor c in instance_constructors) {
1784                                                 c.Emit (this);
1785
1786                                                 if (has_compliant_args)
1787                                                         continue;
1788
1789                                                 has_compliant_args = c.HasCompliantArgs;
1790                                         }
1791                                         if (!has_compliant_args)
1792                                                 Report.Error_T (3015, Location, GetSignatureForError ());
1793                                 } else {
1794                                         foreach (Constructor c in instance_constructors)
1795                                                 c.Emit (this);
1796                                 }
1797                         }
1798
1799                         if (default_static_constructor != null)
1800                                 default_static_constructor.Emit (this);
1801                         
1802                         if (methods != null)
1803                                 foreach (Method m in methods)
1804                                         m.Emit (this);
1805
1806                         if (operators != null)
1807                                 foreach (Operator o in operators)
1808                                         o.Emit (this);
1809
1810                         if (properties != null)
1811                                 foreach (Property p in properties)
1812                                         p.Emit (this);
1813
1814                         if (indexers != null){
1815                                 foreach (Indexer ix in indexers)
1816                                         ix.Emit (this);
1817                                 if (IndexerName != null) {
1818                                         CustomAttributeBuilder cb = EmitDefaultMemberAttr ();
1819                                         TypeBuilder.SetCustomAttribute (cb);
1820                                 }
1821                         }
1822                         
1823                         if (fields != null)
1824                                 foreach (Field f in fields)
1825                                         f.Emit (this);
1826
1827                         if (events != null){
1828                                 foreach (Event e in Events)
1829                                         e.Emit (this);
1830                         }
1831
1832                         if (delegates != null) {
1833                                 foreach (Delegate d in Delegates) {
1834                                         d.Emit (this);
1835                                 }
1836                         }
1837
1838                         if (Pending != null)
1839                                 if (Pending.VerifyPendingMethods ())
1840                                         return;
1841
1842                         VerifyMembers (ec);
1843                         
1844 //                      if (types != null)
1845 //                              foreach (TypeContainer tc in types)
1846 //                                      tc.Emit ();
1847                 }
1848
1849                 CustomAttributeBuilder EmitDefaultMemberAttr ()
1850                 {
1851                         EmitContext ec = new EmitContext (this, Location, null, null, ModFlags);
1852
1853                         Expression ml = Expression.MemberLookup (ec, TypeManager.default_member_type,
1854                                                                  ".ctor", MemberTypes.Constructor,
1855                                                                  BindingFlags.Public | BindingFlags.Instance,
1856                                                                  Location.Null);
1857                         
1858                         MethodGroupExpr mg = (MethodGroupExpr) ml;
1859
1860                         MethodBase constructor = mg.Methods [0];
1861
1862                         string [] vals = { IndexerName };
1863
1864                         CustomAttributeBuilder cb = null;
1865                         try {
1866                                 cb = new CustomAttributeBuilder ((ConstructorInfo) constructor, vals);
1867                         } catch {
1868                                 Report.Warning (-100, "Can not set the indexer default member attribute");
1869                         }
1870
1871                         return cb;
1872                 }
1873
1874                 public override void CloseType ()
1875                 {
1876                         if ((caching_flags & Flags.CloseTypeCreated) != 0)
1877                                 return;
1878                         
1879                         try {
1880                                 caching_flags |= Flags.CloseTypeCreated;
1881                                 TypeBuilder.CreateType ();
1882                         } catch (TypeLoadException){
1883                                 //
1884                                 // This is fine, the code still created the type
1885                                 //
1886 //                              Report.Warning (-20, "Exception while creating class: " + TypeBuilder.Name);
1887 //                              Console.WriteLine (e.Message);
1888                         } catch {
1889                                 Console.WriteLine ("In type: " + Name);
1890                                 throw;
1891                         }
1892                         
1893                         if (Enums != null)
1894                                 foreach (Enum en in Enums)
1895                                         en.CloseType ();
1896
1897                         if (interface_order != null){
1898                                 foreach (Interface iface in interface_order)
1899                                         iface.CloseType ();
1900                         }
1901                         
1902                         if (Types != null){
1903                                 foreach (TypeContainer tc in Types)
1904                                         if (tc is Struct)
1905                                                 tc.CloseType ();
1906
1907                                 foreach (TypeContainer tc in Types)
1908                                         if (!(tc is Struct))
1909                                                 tc.CloseType ();
1910                         }
1911
1912                         if (Delegates != null)
1913                                 foreach (Delegate d in Delegates)
1914                                         d.CloseType ();
1915                         
1916                         types = null;
1917                         properties = null;
1918                         enums = null;
1919                         delegates = null;
1920                         fields = null;
1921                         initialized_fields = null;
1922                         initialized_static_fields = null;
1923                         constants = null;
1924                         interfaces = null;
1925                         interface_order = null;
1926                         methods = null;
1927                         events = null;
1928                         indexers = null;
1929                         operators = null;
1930                         ec = null;
1931                         default_constructor = null;
1932                         default_static_constructor = null;
1933                         type_bases = null;
1934                         OptAttributes = null;
1935                         ifaces = null;
1936                         parent_container = null;
1937                         member_cache = null;
1938                 }
1939
1940                 public string MakeName (string n)
1941                 {
1942                         return "`" + Name + "." + n + "'";
1943                 }
1944
1945                 public void Warning_KeywordNewRequired (Location l, MemberInfo mi)
1946                 {
1947                         Report.Warning (
1948                                 108, l, "The keyword new is required on " + 
1949                                 MakeName (mi.Name) + " because it hides `" +
1950                                 mi.ReflectedType.Name + "." + mi.Name + "'");
1951                 }
1952
1953                 public void Warning_KeywordNewNotRequired (Location l, MemberCore mc)
1954                 {
1955                         Report.Warning (
1956                                 109, l, "The member " + MakeName (mc.Name) + " does not hide an " +
1957                                 "inherited member, the keyword new is not required");
1958                 }
1959
1960                 public void Error_EventCanOnlyOverrideEvent (Location l, MemberInfo mi)
1961                 {
1962                         Report.Error (
1963                                 72, l, MakeName (mi.Name) + " : cannot override; `" +
1964                                 mi.ReflectedType.Name + "." + mi.Name + "' is not an event");
1965                 }
1966                 
1967                 public static int CheckMember (string name, MemberInfo mi, int ModFlags)
1968                 {
1969                         return 0;
1970                 }
1971
1972                 //
1973                 // Performs the validation on a Method's modifiers (properties have
1974                 // the same properties).
1975                 //
1976                 public bool MethodModifiersValid (int flags, string n, Location loc)
1977                 {
1978                         const int vao = (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE);
1979                         const int va = (Modifiers.VIRTUAL | Modifiers.ABSTRACT);
1980                         const int nv = (Modifiers.NEW | Modifiers.VIRTUAL);
1981                         bool ok = true;
1982                         
1983                         //
1984                         // At most one of static, virtual or override
1985                         //
1986                         if ((flags & Modifiers.STATIC) != 0){
1987                                 if ((flags & vao) != 0){
1988                                         Report.Error (
1989                                                 112, loc, "static method " + MakeName (n) + "can not be marked " +
1990                                                 "as virtual, abstract or override");
1991                                         ok = false;
1992                                 }
1993                         }
1994
1995                         if (this is Struct){
1996                                 if ((flags & va) != 0){
1997                                         Modifiers.Error_InvalidModifier (loc, "virtual or abstract");
1998                                         ok = false;
1999                                 }
2000                         }
2001
2002                         if ((flags & Modifiers.OVERRIDE) != 0 && (flags & nv) != 0){
2003                                 Report.Error (
2004                                         113, loc, MakeName (n) +
2005                                         " marked as override cannot be marked as new or virtual");
2006                                 ok = false;
2007                         }
2008
2009                         //
2010                         // If the declaration includes the abstract modifier, then the
2011                         // declaration does not include static, virtual or extern
2012                         //
2013                         if ((flags & Modifiers.ABSTRACT) != 0){
2014                                 if ((flags & Modifiers.EXTERN) != 0){
2015                                         Report.Error (
2016                                                 180, loc, MakeName (n) + " can not be both abstract and extern");
2017                                         ok = false;
2018                                 }
2019
2020                                 if ((flags & Modifiers.VIRTUAL) != 0){
2021                                         Report.Error (
2022                                                 503, loc, MakeName (n) + " can not be both abstract and virtual");
2023                                         ok = false;
2024                                 }
2025
2026                                 if ((ModFlags & Modifiers.ABSTRACT) == 0){
2027                                         Report.Error (
2028                                                 513, loc, MakeName (n) +
2029                                                 " is abstract but its container class is not");
2030                                         ok = false;
2031
2032                                 }
2033                         }
2034
2035                         if ((flags & Modifiers.PRIVATE) != 0){
2036                                 if ((flags & vao) != 0){
2037                                         Report.Error (
2038                                                 621, loc, MakeName (n) +
2039                                                 " virtual or abstract members can not be private");
2040                                         ok = false;
2041                                 }
2042                         }
2043
2044                         if ((flags & Modifiers.SEALED) != 0){
2045                                 if ((flags & Modifiers.OVERRIDE) == 0){
2046                                         Report.Error (
2047                                                 238, loc, MakeName (n) +
2048                                                 " cannot be sealed because it is not an override");
2049                                         ok = false;
2050                                 }
2051                         }
2052
2053                         return ok;
2054                 }
2055
2056                 Hashtable builder_and_args;
2057                 
2058                 public bool RegisterMethod (MethodBuilder mb, InternalParameters ip, Type [] args)
2059                 {
2060                         if (builder_and_args == null)
2061                                 builder_and_args = new Hashtable ();
2062                         return true;
2063                 }
2064
2065                 protected override bool VerifyClsCompliance (DeclSpace ds)
2066                 {
2067                         if (!base.VerifyClsCompliance (ds))
2068                                 return false;
2069
2070                         // parent_container is null for System.Object
2071                         if (parent_container != null && !AttributeTester.IsClsCompliant (parent_container.Type)) {
2072                                 Report.Error_T (3009, Location, GetSignatureForError (),  TypeManager.CSharpName (parent_container.Type));
2073                         }
2074                         return true;
2075                 }
2076
2077
2078                 /// <summary>
2079                 ///   Performs checks for an explicit interface implementation.  First it
2080                 ///   checks whether the `interface_type' is a base inteface implementation.
2081                 ///   Then it checks whether `name' exists in the interface type.
2082                 /// </summary>
2083                 public bool VerifyImplements (Type interface_type, string full, string name, Location loc)
2084                 {
2085                         bool found = false;
2086
2087                         if (ifaces != null){
2088                                 foreach (TypeExpr t in ifaces){
2089                                         if (t.Type == interface_type){
2090                                                 found = true;
2091                                                 break;
2092                                         }
2093                                 }
2094                         }
2095                         
2096                         if (!found){
2097                                 Report.Error (540, "`" + full + "': containing class does not implement interface `" + interface_type.FullName + "'");
2098                                 return false;
2099                         }
2100
2101                         return true;
2102                 }
2103
2104                 protected override void VerifyObsoleteAttribute()
2105                 {
2106                         CheckUsageOfObsoleteAttribute (base_classs_type);
2107
2108                         if (ifaces == null)
2109                                 return;
2110
2111                         foreach (TypeExpr expr in ifaces) {
2112                                 CheckUsageOfObsoleteAttribute (expr.Type);
2113                         }
2114                 }
2115
2116
2117                 //
2118                 // IMemberContainer
2119                 //
2120
2121                 string IMemberContainer.Name {
2122                         get {
2123                                 return Name;
2124                         }
2125                 }
2126
2127                 Type IMemberContainer.Type {
2128                         get {
2129                                 return TypeBuilder;
2130                         }
2131                 }
2132
2133                 IMemberContainer IMemberContainer.Parent {
2134                         get {
2135                                 return parent_container;
2136                         }
2137                 }
2138
2139                 MemberCache IMemberContainer.MemberCache {
2140                         get {
2141                                 return member_cache;
2142                         }
2143                 }
2144
2145                 bool IMemberContainer.IsInterface {
2146                         get {
2147                                 return this is Interface;
2148                         }
2149                 }
2150
2151                 MemberList IMemberContainer.GetMembers (MemberTypes mt, BindingFlags bf)
2152                 {
2153                         return FindMembers (mt, bf | BindingFlags.DeclaredOnly, null, null);
2154                 }
2155
2156                 //
2157                 // Operator pair checking
2158                 //
2159
2160                 class OperatorEntry {
2161                         public int flags;
2162                         public Type ret_type;
2163                         public Type type1, type2;
2164                         public Operator op;
2165                         public Operator.OpType ot;
2166                         
2167                         public OperatorEntry (int f, Operator o)
2168                         {
2169                                 flags = f;
2170
2171                                 ret_type = o.OperatorMethod.GetReturnType ();
2172                                 Type [] pt = o.OperatorMethod.ParameterTypes;
2173                                 type1 = pt [0];
2174                                 type2 = pt [1];
2175                                 op = o;
2176                                 ot = o.OperatorType;
2177                         }
2178
2179                         public override int GetHashCode ()
2180                         {       
2181                                 return ret_type.GetHashCode ();
2182                         }
2183
2184                         public override bool Equals (object o)
2185                         {
2186                                 OperatorEntry other = (OperatorEntry) o;
2187
2188                                 if (other.ret_type != ret_type)
2189                                         return false;
2190                                 if (other.type1 != type1)
2191                                         return false;
2192                                 if (other.type2 != type2)
2193                                         return false;
2194                                 return true;
2195                         }
2196                 }
2197                                 
2198                 //
2199                 // Checks that some operators come in pairs:
2200                 //  == and !=
2201                 // > and <
2202                 // >= and <=
2203                 // true and false
2204                 //
2205                 // They are matched based on the return type and the argument types
2206                 //
2207                 void CheckPairedOperators ()
2208                 {
2209                         Hashtable pairs = new Hashtable (null, null);
2210                         Operator true_op = null;
2211                         Operator false_op = null;
2212                         bool has_equality_or_inequality = false;
2213                         
2214                         // Register all the operators we care about.
2215                         foreach (Operator op in operators){
2216                                 int reg = 0;
2217                                 
2218                                 switch (op.OperatorType){
2219                                 case Operator.OpType.Equality:
2220                                         reg = 1;
2221                                         has_equality_or_inequality = true;
2222                                         break;
2223                                 case Operator.OpType.Inequality:
2224                                         reg = 2;
2225                                         has_equality_or_inequality = true;
2226                                         break;
2227
2228                                 case Operator.OpType.True:
2229                                         true_op = op;
2230                                         break;
2231                                 case Operator.OpType.False:
2232                                         false_op = op;
2233                                         break;
2234                                         
2235                                 case Operator.OpType.GreaterThan:
2236                                         reg = 1; break;
2237                                 case Operator.OpType.LessThan:
2238                                         reg = 2; break;
2239                                         
2240                                 case Operator.OpType.GreaterThanOrEqual:
2241                                         reg = 1; break;
2242                                 case Operator.OpType.LessThanOrEqual:
2243                                         reg = 2; break;
2244                                 }
2245                                 if (reg == 0)
2246                                         continue;
2247
2248                                 OperatorEntry oe = new OperatorEntry (reg, op);
2249
2250                                 object o = pairs [oe];
2251                                 if (o == null)
2252                                         pairs [oe] = oe;
2253                                 else {
2254                                         oe = (OperatorEntry) o;
2255                                         oe.flags |= reg;
2256                                 }
2257                         }
2258
2259                         if (true_op != null){
2260                                 if (false_op == null)
2261                                         Report.Error (216, true_op.Location, "operator true requires a matching operator false");
2262                         } else if (false_op != null)
2263                                 Report.Error (216, false_op.Location, "operator false requires a matching operator true");
2264                         
2265                         //
2266                         // Look for the mistakes.
2267                         //
2268                         foreach (DictionaryEntry de in pairs){
2269                                 OperatorEntry oe = (OperatorEntry) de.Key;
2270
2271                                 if (oe.flags == 3)
2272                                         continue;
2273
2274                                 string s = "";
2275                                 switch (oe.ot){
2276                                 case Operator.OpType.Equality:
2277                                         s = "!=";
2278                                         break;
2279                                 case Operator.OpType.Inequality: 
2280                                         s = "==";
2281                                         break;
2282                                 case Operator.OpType.GreaterThan: 
2283                                         s = "<";
2284                                         break;
2285                                 case Operator.OpType.LessThan:
2286                                         s = ">";
2287                                         break;
2288                                 case Operator.OpType.GreaterThanOrEqual:
2289                                         s = "<=";
2290                                         break;
2291                                 case Operator.OpType.LessThanOrEqual:
2292                                         s = ">=";
2293                                         break;
2294                                 }
2295                                 Report.Error (216, oe.op.Location,
2296                                               "The operator `" + oe.op + "' requires a matching operator `" + s + "' to also be defined");
2297                         }
2298
2299                         if ((has_equality_or_inequality) && (RootContext.WarningLevel >= 2)) {
2300                                 MethodSignature equals_ms = new MethodSignature (
2301                                         "Equals", TypeManager.bool_type, new Type [] { TypeManager.object_type });
2302                                 MethodSignature hash_ms = new MethodSignature (
2303                                         "GetHashCode", TypeManager.int32_type, new Type [0]);
2304
2305                                 MemberList equals_ml = FindMembers (MemberTypes.Method, BindingFlags.Public | BindingFlags.Instance |
2306                                                                     BindingFlags.DeclaredOnly, MethodSignature.method_signature_filter,
2307                                                                     equals_ms);
2308                                 MemberList hash_ml = FindMembers (MemberTypes.Method, BindingFlags.Public | BindingFlags.Instance |
2309                                                                   BindingFlags.DeclaredOnly, MethodSignature.method_signature_filter,
2310                                                                   hash_ms);
2311
2312                                 bool equals_ok = false;
2313                                 if ((equals_ml != null) && (equals_ml.Count == 1))
2314                                         equals_ok = equals_ml [0].DeclaringType == TypeBuilder;
2315                                 bool hash_ok = false;
2316                                 if ((hash_ml != null) && (hash_ml.Count == 1))
2317                                         hash_ok = hash_ml [0].DeclaringType == TypeBuilder;
2318
2319                                 if (!equals_ok)
2320                                         Report.Warning (660, Location, "`" + Name + "' defines operator == or operator != but does " +
2321                                                         "not override Object.Equals (object o)");
2322                                 if (!hash_ok)
2323                                         Report.Warning (661, Location, "`" + Name + "' defines operator == or operator != but does " +
2324                                                         "not override Object.GetHashCode ()");
2325                         }
2326                 }
2327                 
2328                 
2329         }
2330
2331         public class ClassOrStruct : TypeContainer {
2332                 bool hasExplicitLayout = false;
2333                 public ClassOrStruct (NamespaceEntry ns, TypeContainer parent, string name, Attributes attrs, Location l)
2334                         : base (ns, parent, name, attrs, l)
2335                 {
2336                 }
2337
2338                 protected override void VerifyMembers (EmitContext ec) 
2339                 {
2340                         if (Fields != null) {
2341                                 foreach (Field f in Fields) {
2342                                         if ((f.ModFlags & Modifiers.STATIC) != 0)
2343                                                 continue;
2344                                         if (hasExplicitLayout) {
2345                                                 if (f.OptAttributes == null 
2346                                                     || !f.OptAttributes.Contains (TypeManager.field_offset_attribute_type, ec)) {
2347                                                         Report.Error (625, f.Location,
2348                                                                       "Instance field of type marked with" 
2349                                                                       + " StructLayout(LayoutKind.Explicit) must have a"
2350                                                                       + " FieldOffset attribute.");
2351                                                 }
2352                                         }
2353                                         else {
2354                                                 if (f.OptAttributes != null 
2355                                                     && f.OptAttributes.Contains (TypeManager.field_offset_attribute_type, ec)) {
2356                                                         Report.Error (636, f.Location,
2357                                                                       "The FieldOffset attribute can only be placed on members of "
2358                                                                       + "types marked with the StructLayout(LayoutKind.Explicit)");
2359                                                 }
2360                                         }
2361                                 }
2362                         }
2363                         base.VerifyMembers (ec);
2364                 }
2365
2366                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
2367                 {
2368                         if (a.Type == TypeManager.struct_layout_attribute_type
2369                             && (LayoutKind) a.GetPositionalValue (0) == LayoutKind.Explicit)
2370                                 hasExplicitLayout = true;
2371
2372                         base.ApplyAttributeBuilder (a, cb);
2373                 }
2374         }
2375
2376         public class Class : ClassOrStruct {
2377                 // <summary>
2378                 //   Modifiers allowed in a class declaration
2379                 // </summary>
2380                 public const int AllowedModifiers =
2381                         Modifiers.NEW |
2382                         Modifiers.PUBLIC |
2383                         Modifiers.PROTECTED |
2384                         Modifiers.INTERNAL |
2385                         Modifiers.PRIVATE |
2386                         Modifiers.ABSTRACT |
2387                         Modifiers.SEALED |
2388                         Modifiers.UNSAFE;
2389
2390
2391                 // Information in the case we are an attribute type
2392                 AttributeUsageAttribute attribute_usage;
2393
2394                 public Class (NamespaceEntry ns, TypeContainer parent, string name, int mod,
2395                               Attributes attrs, Location l)
2396                         : base (ns, parent, name, attrs, l)
2397                 {
2398                         int accmods;
2399
2400                         if (parent.Parent == null)
2401                                 accmods = Modifiers.INTERNAL;
2402                         else
2403                                 accmods = Modifiers.PRIVATE;
2404
2405                         this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
2406                         attribute_usage = new AttributeUsageAttribute (AttributeTargets.All);
2407                 }
2408
2409                 public override AttributeTargets AttributeTargets {
2410                         get {
2411                                 return AttributeTargets.Class;
2412                         }
2413                 }
2414
2415                 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
2416                 {
2417                         if (a.UsageAttribute != null)
2418                                 attribute_usage = a.UsageAttribute;
2419
2420                         base.ApplyAttributeBuilder (a, cb);
2421                 }
2422
2423                 public AttributeUsageAttribute AttributeUsage {
2424                         get {
2425                                 return attribute_usage;
2426                         }
2427                 }
2428
2429                 //
2430                 // FIXME: How do we deal with the user specifying a different
2431                 // layout?
2432                 //
2433                 public override TypeAttributes TypeAttr {
2434                         get {
2435                                 return base.TypeAttr | TypeAttributes.AutoLayout | TypeAttributes.Class;
2436                         }
2437                 }
2438         }
2439
2440         public class Struct : ClassOrStruct {
2441                 // <summary>
2442                 //   Modifiers allowed in a struct declaration
2443                 // </summary>
2444                 public const int AllowedModifiers =
2445                         Modifiers.NEW       |
2446                         Modifiers.PUBLIC    |
2447                         Modifiers.PROTECTED |
2448                         Modifiers.INTERNAL  |
2449                         Modifiers.UNSAFE    |
2450                         Modifiers.PRIVATE;
2451
2452                 public Struct (NamespaceEntry ns, TypeContainer parent, string name, int mod, Attributes attrs, Location l)
2453                         : base (ns, parent, name, attrs, l)
2454                 {
2455                         int accmods;
2456                         
2457                         if (parent.Parent == null)
2458                                 accmods = Modifiers.INTERNAL;
2459                         else
2460                                 accmods = Modifiers.PRIVATE;
2461                         
2462                         this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
2463
2464                         this.ModFlags |= Modifiers.SEALED;
2465                 }
2466
2467                 public override AttributeTargets AttributeTargets {
2468                         get {
2469                                 return AttributeTargets.Struct;
2470                         }
2471                 }
2472
2473
2474                 //
2475                 // FIXME: Allow the user to specify a different set of attributes
2476                 // in some cases (Sealed for example is mandatory for a class,
2477                 // but what SequentialLayout can be changed
2478                 //
2479                 public override TypeAttributes TypeAttr {
2480                         get {
2481                                 return base.TypeAttr |
2482                                         TypeAttributes.SequentialLayout |
2483                                         TypeAttributes.Sealed |
2484                                         TypeAttributes.BeforeFieldInit;
2485                         }
2486                 }
2487         }
2488
2489         /// <summary>
2490         ///   Interfaces
2491         /// </summary>
2492         public class Interface : TypeContainer, IMemberContainer {
2493                 /// <summary>
2494                 ///   Modifiers allowed in a class declaration
2495                 /// </summary>
2496                 public const int AllowedModifiers =
2497                         Modifiers.NEW       |
2498                         Modifiers.PUBLIC    |
2499                         Modifiers.PROTECTED |
2500                         Modifiers.INTERNAL  |
2501                         Modifiers.UNSAFE    |
2502                         Modifiers.PRIVATE;
2503
2504                 public Interface (NamespaceEntry ns, TypeContainer parent, string name, int mod,
2505                                   Attributes attrs, Location l)
2506                         : base (ns, parent, name, attrs, l)
2507                 {
2508                         int accmods;
2509
2510                         if (parent.Parent == null)
2511                                 accmods = Modifiers.INTERNAL;
2512                         else
2513                                 accmods = Modifiers.PRIVATE;
2514
2515                         this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
2516                 }
2517
2518                 public override AttributeTargets AttributeTargets {
2519                         get {
2520                                 return AttributeTargets.Interface;
2521                         }
2522                 }
2523
2524                 public override TypeAttributes TypeAttr {
2525                         get {
2526                                 return base.TypeAttr |
2527                                         TypeAttributes.AutoLayout |
2528                                         TypeAttributes.Abstract |
2529                                         TypeAttributes.Interface;
2530                         }
2531                 }
2532         }
2533
2534         public abstract class MethodCore : MemberBase {
2535                 public readonly Parameters Parameters;
2536                 protected Block block;
2537                 public DeclSpace ds;
2538                 
2539                 //
2540                 // Parameters, cached for semantic analysis.
2541                 //
2542                 protected InternalParameters parameter_info;
2543                 protected Type [] parameter_types;
2544
2545                 // <summary>
2546                 //   This is set from TypeContainer.DefineMembers if this method overrides something.
2547                 // </summary>
2548                 public bool OverridesSomething;
2549
2550                 // Whether this is an operator method.
2551                 public bool IsOperator;
2552
2553                 static string[] attribute_targets = new string [] { "method", "return" };
2554
2555                 public MethodCore (DeclSpace ds, Expression type, int mod, int allowed_mod,
2556                                    bool is_interface, string name, Attributes attrs,
2557                                    Parameters parameters, Location loc)
2558                         : base (type, mod, allowed_mod, Modifiers.PRIVATE, name, attrs, loc)
2559                 {
2560                         Parameters = parameters;
2561                         IsInterface = is_interface;
2562                         this.ds = ds;
2563                 }
2564                 
2565                 //
2566                 //  Returns the System.Type array for the parameters of this method
2567                 //
2568                 public Type [] ParameterTypes {
2569                         get {
2570                                 return parameter_types;
2571                         }
2572                 }
2573
2574                 public InternalParameters ParameterInfo
2575                 {
2576                         get {
2577                                 return parameter_info;
2578                         }
2579                 }
2580                 
2581                 public Block Block {
2582                         get {
2583                                 return block;
2584                         }
2585
2586                         set {
2587                                 block = value;
2588                         }
2589                 }
2590
2591                 protected virtual bool DoDefineParameters ()
2592                 {
2593                         // Check if arguments were correct
2594                         parameter_types = Parameters.GetParameterInfo (ds);
2595                         if ((parameter_types == null) || !CheckParameters (ds, parameter_types))
2596                                 return false;
2597
2598                         parameter_info = new InternalParameters (ds, Parameters);
2599
2600                         Parameter array_param = Parameters.ArrayParameter;
2601                         if ((array_param != null) &&
2602                             (!array_param.ParameterType.IsArray ||
2603                              (array_param.ParameterType.GetArrayRank () != 1))) {
2604                                 Report.Error (225, Location, "params parameter has to be a single dimensional array");
2605                                 return false;
2606                         }
2607
2608                         return true;
2609                 }
2610
2611                 protected override string[] ValidAttributeTargets {
2612                         get {
2613                                 return attribute_targets;
2614                         }
2615                 }
2616
2617                 protected override bool VerifyClsCompliance (DeclSpace ds)
2618                 {
2619                         if (!base.VerifyClsCompliance (ds)) {
2620                                 if ((ModFlags & Modifiers.ABSTRACT) != 0 && IsExposedFromAssembly (ds) && ds.IsClsCompliaceRequired (ds)) {
2621                                         Report.Error_T (3011, Location, GetSignatureForError ());
2622                                 }
2623                                 return false;
2624                         }
2625
2626                         AttributeTester.AreParametersCompliant (Parameters.FixedParameters, Location);
2627
2628                         if (!AttributeTester.IsClsCompliant (MemberType)) {
2629                                 Report.Error_T (3002, Location, GetSignatureForError ());
2630                         }
2631
2632                         return true;
2633                 }
2634
2635                 protected bool IsDuplicateImplementation (TypeContainer tc, MethodCore method)
2636                 {
2637                         if ((method == this) || (method.Name != Name))
2638                                 return false;
2639
2640                         Type[] param_types = method.ParameterTypes;
2641                         if (param_types == null)
2642                                 return false;
2643
2644                         if (param_types.Length != ParameterTypes.Length)
2645                                 return false;
2646
2647                         for (int i = 0; i < param_types.Length; i++)
2648                                 if (param_types [i] != ParameterTypes [i])
2649                                         return false;
2650
2651                         //
2652                         // Try to report 663: method only differs on out/ref
2653                         //
2654                         ParameterData info = ParameterInfo;
2655                         ParameterData other_info = method.ParameterInfo;
2656                         for (int i = 0; i < info.Count; i++){
2657                                 if (info.ParameterModifier (i) != other_info.ParameterModifier (i)){
2658                                         Report.Error (663, Location, "Overload method only differs in parameter modifier");
2659                                         return false;
2660                                 }
2661                         }
2662
2663                         Report.Error (111, Location, "Class `{0}' already defines a " +
2664                                       "member called `{1}' with the same parameter types",
2665                                       tc.Name, Name);
2666                         return true;
2667                 }
2668
2669                 public CallingConventions GetCallingConvention (bool is_class)
2670                 {
2671                         CallingConventions cc = 0;
2672                         
2673                         cc = Parameters.GetCallingConvention ();
2674
2675                         if (is_class)
2676                                 if ((ModFlags & Modifiers.STATIC) == 0)
2677                                         cc |= CallingConventions.HasThis;
2678
2679                         // FIXME: How is `ExplicitThis' used in C#?
2680                         
2681                         return cc;
2682                 }
2683
2684                 protected override void VerifyObsoleteAttribute()
2685                 {
2686                         base.VerifyObsoleteAttribute ();
2687
2688                         if (parameter_types == null)
2689                                 return;
2690
2691                         foreach (Type type in parameter_types) {
2692                                 CheckUsageOfObsoleteAttribute (type);
2693                         }
2694                 }
2695         }
2696
2697         public class Method : MethodCore, IIteratorContainer, IMethodData {
2698                 public MethodBuilder MethodBuilder;
2699                 public MethodData MethodData;
2700                 ReturnParameter return_attributes;
2701
2702                 /// <summary>
2703                 ///   Modifiers allowed in a class declaration
2704                 /// </summary>
2705                 const int AllowedModifiers =
2706                         Modifiers.NEW |
2707                         Modifiers.PUBLIC |
2708                         Modifiers.PROTECTED |
2709                         Modifiers.INTERNAL |
2710                         Modifiers.PRIVATE |
2711                         Modifiers.STATIC |
2712                         Modifiers.VIRTUAL |
2713                         Modifiers.SEALED |
2714                         Modifiers.OVERRIDE |
2715                         Modifiers.ABSTRACT |
2716                         Modifiers.UNSAFE |
2717                         Modifiers.METHOD_YIELDS | 
2718                         Modifiers.EXTERN;
2719
2720                 const int AllowedInterfaceModifiers =
2721                         Modifiers.NEW | Modifiers.UNSAFE;
2722
2723                 //
2724                 // return_type can be "null" for VOID values.
2725                 //
2726                 public Method (DeclSpace ds, Expression return_type, int mod, bool is_iface,
2727                                string name, Parameters parameters, Attributes attrs, Location l)
2728                         : base (ds, return_type, mod,
2729                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
2730                                 is_iface, name, attrs, parameters, l)
2731                 {
2732                 }
2733
2734                 public override AttributeTargets AttributeTargets {
2735                         get {
2736                                 return AttributeTargets.Method | AttributeTargets.ReturnValue;
2737                         }
2738                 }
2739                 
2740                 //
2741                 // Returns the `System.Type' for the ReturnType of this
2742                 // function.  Provides a nice cache.  (used between semantic analysis
2743                 // and actual code generation
2744                 //
2745                 public Type GetReturnType ()
2746                 {
2747                         return MemberType;
2748                 }
2749
2750                 public override string GetSignatureForError()
2751                 {
2752                         return TypeManager.CSharpSignature (MethodBuilder);
2753                 }
2754
2755                 /// <summary>
2756                 /// Use this method when MethodBuilder is null
2757                 /// </summary>
2758                 public override string GetSignatureForError (TypeContainer tc)
2759                 {
2760                         // TODO: move to parameters
2761                         System.Text.StringBuilder args = new System.Text.StringBuilder ();
2762                         if (parameter_info.Parameters.FixedParameters != null) {
2763                                 for (int i = 0; i < parameter_info.Parameters.FixedParameters.Length; ++i) {
2764                                         Parameter p = parameter_info.Parameters.FixedParameters [i];
2765                                         args.Append (p.GetSignatureForError ());
2766
2767                                         if (i < parameter_info.Parameters.FixedParameters.Length - 1)
2768                                                 args.Append (',');
2769                                 }
2770                         }
2771
2772                         return String.Concat (base.GetSignatureForError (tc), "(", args.ToString (), ")");
2773                 }
2774
2775                 void DuplicateEntryPoint (MethodInfo b, Location location)
2776                 {
2777                         Report.Error (
2778                                 17, location,
2779                                 "Program `" + CodeGen.FileName +
2780                                 "'  has more than one entry point defined: `" +
2781                                 TypeManager.CSharpSignature(b) + "'");
2782                 }
2783
2784                 void Report28 (MethodInfo b)
2785                 {
2786                         Report.Warning (
2787                                 28, Location,
2788                                 "`" + TypeManager.CSharpSignature(b) +
2789                                 "' has the wrong signature to be an entry point");
2790                 }
2791
2792                 public bool IsEntryPoint (MethodBuilder b, InternalParameters pinfo)
2793                 {
2794                         if (b.ReturnType != TypeManager.void_type &&
2795                             b.ReturnType != TypeManager.int32_type)
2796                                 return false;
2797
2798                         if (pinfo.Count == 0)
2799                                 return true;
2800
2801                         if (pinfo.Count > 1)
2802                                 return false;
2803
2804                         Type t = pinfo.ParameterType(0);
2805                         if (t.IsArray &&
2806                             (t.GetArrayRank() == 1) &&
2807                             (TypeManager.GetElementType(t) == TypeManager.string_type) &&
2808                             (pinfo.ParameterModifier(0) == Parameter.Modifier.NONE))
2809                                 return true;
2810                         else
2811                                 return false;
2812                 }
2813
2814                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
2815                 {
2816                         if (a.Target == "return") {
2817                                 if (return_attributes == null)
2818                                         return_attributes = new ReturnParameter (MethodBuilder, Location);
2819
2820                                 return_attributes.ApplyAttributeBuilder (a, cb);
2821                                 return;
2822                         }
2823
2824                         if (a.Type == TypeManager.methodimpl_attr_type && a.IsInternalCall) {
2825                                 MethodBuilder.SetImplementationFlags (MethodImplAttributes.InternalCall | MethodImplAttributes.Runtime);
2826                         }
2827
2828                         if (a.Type == TypeManager.dllimport_type) {
2829                                 const int extern_static = Modifiers.EXTERN | Modifiers.STATIC;
2830                                 if ((ModFlags & extern_static) != extern_static) {
2831                                         //"The DllImport attribute must be specified on a method marked `static' and `extern'"
2832                                         Report.Error_T (601, a.Location);
2833                                 }
2834
2835                                 return;
2836                         }
2837
2838                         if (a.Type == TypeManager.conditional_attribute_type) {
2839                                 if (IsOperator || IsExplicitImpl) {
2840                                         // Conditional not valid on '{0}' because it is a destructor, operator, or explicit interface implementation
2841                                         Report.Error_T (577, Location, GetSignatureForError ());
2842                                         return;
2843                                 }
2844
2845                                 if (ReturnType != TypeManager.void_type) {
2846                                         // Conditional not valid on '{0}' because its return type is not void
2847                                         Report.Error_T (578, Location, GetSignatureForError ());
2848                                         return;
2849                                 }
2850
2851                                 if ((ModFlags & Modifiers.OVERRIDE) != 0) {
2852                                         // Conditional not valid on '{0}' because it is an override method
2853                                         Report.Error_T (243, Location, GetSignatureForError ());
2854                                         return;
2855                                 }
2856
2857                                 if (IsInterface) {
2858                                         // Conditional not valid on interface members
2859                                         Report.Error_T (582, Location);
2860                                         return;
2861                                 }
2862
2863                                 if (MethodData.IsImplementing) {
2864                                         // Conditional member '{0}' cannot implement interface member
2865                                         Report.Error_T (629, Location, GetSignatureForError ());
2866                                         return;
2867                                 }
2868                         }
2869
2870                         MethodBuilder.SetCustomAttribute (cb);
2871                 }
2872
2873                 //
2874                 // Checks our base implementation if any
2875                 //
2876                 protected override bool CheckBase (TypeContainer container)
2877                 {
2878                         base.CheckBase (container);
2879                         
2880                         // Check whether arguments were correct.
2881                         if (!DoDefineParameters ())
2882                                 return false;
2883
2884                         MethodSignature ms = new MethodSignature (Name, null, ParameterTypes);
2885                         if (IsOperator) {
2886                                 flags |= MethodAttributes.SpecialName | MethodAttributes.HideBySig;
2887                         } else {
2888                                 //
2889                                 // Check in our class for dups
2890                                 //
2891                                 ArrayList ar = container.Methods;
2892                                 if (ar != null) {
2893                                         int arLen = ar.Count;
2894                                         
2895                                         for (int i = 0; i < arLen; i++) {
2896                                                 Method m = (Method) ar [i];
2897                                                 if (IsDuplicateImplementation (container, m))
2898                                                         return false;
2899                                         }
2900                                 }
2901                         }
2902                         
2903
2904                         //
2905                         // Verify if the parent has a type with the same name, and then
2906                         // check whether we have to create a new slot for it or not.
2907                         //
2908                         Type ptype = container.TypeBuilder.BaseType;
2909
2910                         // ptype is only null for System.Object while compiling corlib.
2911                         if (ptype != null) {
2912                                 
2913                                 //
2914                                 // Explicit implementations do not have `parent' methods, however,
2915                                 // the member cache stores them there. Without this check, we get
2916                                 // an incorrect warning in corlib.
2917                                 //
2918                                 if (! IsExplicitImpl) {
2919                                         parent_method = (MethodInfo)((IMemberContainer)container).Parent.MemberCache.FindMemberToOverride (
2920                                                 container.TypeBuilder, Name, ParameterTypes, false);
2921                                 }
2922                                 
2923                                 if (parent_method != null) {
2924                                         string name = parent_method.DeclaringType.Name + "." +
2925                                                 parent_method.Name;
2926
2927                                         if (!CheckMethodAgainstBase (container, flags, parent_method, name))
2928                                                 return false;
2929
2930                                         if ((ModFlags & Modifiers.NEW) == 0) {
2931                                                 Type parent_ret = TypeManager.TypeToCoreType (
2932                                                         parent_method.ReturnType);
2933
2934                                                 if (parent_ret != MemberType) {
2935                                                         Report.Error (
2936                                                                 508, Location, container.MakeName (Name) + ": cannot " +
2937                                                                 "change return type when overriding " +
2938                                                                 "inherited member " + name);
2939                                                         return false;
2940                                                 }
2941                                         }
2942
2943                                         ObsoleteAttribute oa = AttributeTester.GetMethodObsoleteAttribute (parent_method);
2944                                         if (oa != null) {
2945                                                 Report.SymbolRelatedToPreviousError (parent_method);
2946                                                 Report.Warning_T (672, Location, GetSignatureForError (container));
2947                                         }
2948                                 } else {
2949                                         if (!OverridesSomething && ((ModFlags & Modifiers.NEW) != 0))
2950                                                 WarningNotHiding (container);
2951
2952                                         if ((ModFlags & Modifiers.OVERRIDE) != 0){
2953                                                 Report.Error (115, Location,
2954                                                               container.MakeName (Name) +
2955                                                               " no suitable methods found to override");
2956                                         }
2957                                 }
2958                         } else if ((ModFlags & Modifiers.NEW) != 0)
2959                                 WarningNotHiding (container);
2960
2961                         return true;
2962                 }
2963
2964                 //
2965                 // Creates the type
2966                 //
2967                 public override bool Define (TypeContainer container)
2968                 {
2969                         if (!DoDefine (container))
2970                                 return false;
2971
2972                         if (!CheckBase (container))
2973                                 return false;
2974
2975                         MethodData = new MethodData (this, ParameterInfo, ModFlags, flags, this);
2976
2977                         if (!MethodData.Define (container))
2978                                 return false;
2979
2980                         //
2981                         // Setup iterator if we are one
2982                         //
2983                         if ((ModFlags & Modifiers.METHOD_YIELDS) != 0){
2984                                 IteratorHandler ih = new  IteratorHandler (
2985                                             Name, container, MemberType,
2986                                             ParameterTypes, ParameterInfo,
2987                                             ModFlags, Location);
2988
2989                                 Block new_block = ih.Setup (block);
2990                                 if (new_block == null)
2991                                         return false;
2992                                 block = new_block;
2993                         }
2994
2995                         MethodBuilder = MethodData.MethodBuilder;
2996                         
2997                         //
2998                         // This is used to track the Entry Point,
2999                         //
3000                         if (Name == "Main" &&
3001                             ((ModFlags & Modifiers.STATIC) != 0) && RootContext.NeedsEntryPoint && 
3002                             (RootContext.MainClass == null ||
3003                              RootContext.MainClass == container.TypeBuilder.FullName)){
3004                                 if (IsEntryPoint (MethodBuilder, ParameterInfo)) {
3005                                         if (RootContext.EntryPoint == null) {
3006                                                 RootContext.EntryPoint = MethodBuilder;
3007                                                 RootContext.EntryPointLocation = Location;
3008                                         } else {
3009                                                 DuplicateEntryPoint (RootContext.EntryPoint, RootContext.EntryPointLocation);
3010                                                 DuplicateEntryPoint (MethodBuilder, Location);
3011                                         }
3012                                 } else                                  
3013                                         Report28(MethodBuilder);
3014                         }
3015
3016                         return true;
3017                 }
3018
3019                 //
3020                 // Emits the code
3021                 // 
3022                 public override void Emit (TypeContainer container)
3023                 {
3024                         MethodData.Emit (container, this);
3025                         base.Emit (container);
3026                         Block = null;
3027                         MethodData = null;
3028                 }
3029
3030                 void IIteratorContainer.SetYields ()
3031                 {
3032                         ModFlags |= Modifiers.METHOD_YIELDS;
3033                 }
3034         
3035                 protected override bool IsIdentifierClsCompliant (DeclSpace ds)
3036                 {
3037                         return IsIdentifierAndParamClsCompliant (ds, Name, MethodBuilder, parameter_types);
3038                 }
3039
3040                 #region IMethodData Members
3041
3042                 public CallingConventions CallingConventions {
3043                         get {
3044                                 CallingConventions cc = Parameters.GetCallingConvention ();
3045                                 if (Parameters.HasArglist)
3046                                         block.HasVarargs = true;
3047
3048                                 if (!IsInterface)
3049                                         if ((ModFlags & Modifiers.STATIC) == 0)
3050                                                 cc |= CallingConventions.HasThis;
3051
3052                                 // FIXME: How is `ExplicitThis' used in C#?
3053                         
3054                                 return cc;
3055                         }
3056                 }
3057
3058                 public Type ReturnType {
3059                         get {
3060                                 return MemberType;
3061                         }
3062                 }
3063
3064                 public string MethodName {
3065                         get {
3066                                 return ShortName;
3067                         }
3068                 }
3069
3070                 public new Location Location {
3071                         get {
3072                                 return base.Location;
3073                         }
3074                 }
3075
3076                 public EmitContext CreateEmitContext (TypeContainer tc, ILGenerator ig)
3077                 {
3078                         return new EmitContext (tc, ds, Location, ig, ReturnType, ModFlags, false);
3079                 }
3080
3081                 public ObsoleteAttribute GetObsoleteAttribute ()
3082                 {
3083                         return GetObsoleteAttribute (ds);
3084                 }
3085
3086                 /// <summary>
3087                 /// Returns true if method has conditional attribute and the conditions is not defined (method is excluded).
3088                 /// </summary>
3089                 public bool IsExcluded (EmitContext ec)
3090                 {
3091                         if ((caching_flags & Flags.Excluded_Undetected) == 0)
3092                                 return (caching_flags & Flags.Excluded) != 0;
3093
3094                         caching_flags &= ~Flags.Excluded_Undetected;
3095
3096                         if (parent_method == null) {
3097                                 if (OptAttributes == null)
3098                                         return false;
3099
3100                                 Attribute[] attrs = OptAttributes.SearchMulti (TypeManager.conditional_attribute_type, ec);
3101
3102                                 if (attrs == null)
3103                                         return false;
3104
3105                                 foreach (Attribute a in attrs) {
3106                                         string condition = a.GetConditionalAttributeValue (ds);
3107                                         if (RootContext.AllDefines.Contains (condition))
3108                                                 return false;
3109                                 }
3110
3111                                 caching_flags |= Flags.Excluded;
3112                                 return true;
3113                         }
3114
3115                         IMethodData md = TypeManager.GetMethod (parent_method);
3116                         if (md == null) {
3117                                 if (AttributeTester.IsConditionalMethodExcluded (parent_method)) {
3118                                         caching_flags |= Flags.Excluded;
3119                                         return true;
3120                                 }
3121                                 return false;
3122                         }
3123
3124                         if (md.IsExcluded (ec)) {
3125                                 caching_flags |= Flags.Excluded;
3126                                 return true;
3127                         }
3128                         return false;
3129                 }
3130
3131                 #endregion
3132         }
3133
3134         public abstract class ConstructorInitializer {
3135                 ArrayList argument_list;
3136                 protected ConstructorInfo parent_constructor;
3137                 Parameters parameters;
3138                 Location loc;
3139                 
3140                 public ConstructorInitializer (ArrayList argument_list, Parameters parameters,
3141                                                Location loc)
3142                 {
3143                         this.argument_list = argument_list;
3144                         this.parameters = parameters;
3145                         this.loc = loc;
3146                 }
3147
3148                 public ArrayList Arguments {
3149                         get {
3150                                 return argument_list;
3151                         }
3152                 }
3153
3154                 public bool Resolve (ConstructorBuilder caller_builder, EmitContext ec)
3155                 {
3156                         Expression parent_constructor_group;
3157                         Type t;
3158
3159                         ec.CurrentBlock = new ToplevelBlock (Block.Flags.Implicit, parameters, loc);
3160
3161                         if (argument_list != null){
3162                                 foreach (Argument a in argument_list){
3163                                         if (!a.Resolve (ec, loc))
3164                                                 return false;
3165                                 }
3166                         }
3167                         ec.CurrentBlock = null;
3168
3169                         if (this is ConstructorBaseInitializer) {
3170                                 if (ec.ContainerType.BaseType == null)
3171                                         return true;
3172
3173                                 t = ec.ContainerType.BaseType;
3174                                 if (ec.ContainerType.IsValueType) {
3175                                         Report.Error (522, loc,
3176                                                 "structs cannot call base class constructors");
3177                                         return false;
3178                                 }
3179                         } else
3180                                 t = ec.ContainerType;
3181
3182                         parent_constructor_group = Expression.MemberLookup (
3183                                 ec, t, ".ctor", MemberTypes.Constructor,
3184                                 BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
3185                                 loc);
3186                         
3187                         if (parent_constructor_group == null){
3188                                 parent_constructor_group = Expression.MemberLookup (
3189                                         ec, t, ".ctor", MemberTypes.Constructor,
3190                                         BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly,
3191                                         loc);
3192
3193                                 if (parent_constructor_group != null)
3194                                         Report.Error (
3195                                                 112, loc, "`{0}.{1}' is inaccessible due to " +
3196                                                 "its protection level", t.FullName, t.Name);
3197                                 else
3198                                         Report.Error (
3199                                                 1501, loc, "Can not find a constructor for " +
3200                                                 "this argument list");
3201                                 return false;
3202                         }
3203                         
3204                         parent_constructor = (ConstructorInfo) Invocation.OverloadResolve (ec, 
3205                                 (MethodGroupExpr) parent_constructor_group, argument_list, loc);
3206                         
3207                         if (parent_constructor == null){
3208                                 Report.Error (1501, loc,
3209                                        "Can not find a constructor for this argument list");
3210                                 return false;
3211                         }
3212
3213                         if (parent_constructor == caller_builder){
3214                                 Report.Error (515, String.Format ("Constructor `{0}' can not call itself", TypeManager.CSharpSignature (caller_builder)));
3215                                 return false;
3216                         }
3217                         
3218                         return true;
3219                 }
3220
3221                 public void Emit (EmitContext ec)
3222                 {
3223                         if (parent_constructor != null){
3224                                 ec.Mark (loc, false);
3225                                 if (ec.IsStatic)
3226                                         Invocation.EmitCall (ec, true, true, null, parent_constructor, argument_list, loc);
3227                                 else
3228                                         Invocation.EmitCall (ec, true, false, ec.GetThis (loc), parent_constructor, argument_list, loc);
3229                         }
3230                 }
3231
3232                 /// <summary>
3233                 /// Method search for base ctor. (We do not cache it).
3234                 /// </summary>
3235                 Constructor GetOverloadedConstructor (TypeContainer tc)
3236                 {
3237                         if (tc.InstanceConstructors == null)
3238                                 return null;
3239
3240                         foreach (Constructor c in tc.InstanceConstructors) {
3241                                 if (Arguments == null) {
3242                                         if (c.ParameterTypes.Length == 0)
3243                                                 return c;
3244
3245                                         continue;
3246                                 }
3247
3248                                 bool ok = true;
3249
3250                                 int count = c.ParameterInfo.Count;
3251                                 if ((count > 0) &&
3252                                     c.ParameterInfo.ParameterModifier (count - 1) == Parameter.Modifier.PARAMS) {
3253                                         for (int i = 0; i < count-1; i++)
3254                                                 if (c.ParameterTypes [i] != ((Argument)Arguments [i]).Type) {
3255                                                         ok = false;
3256                                                         break;
3257                                                 }
3258                                 } else {
3259                                         if (c.ParameterTypes.Length != Arguments.Count)
3260                                                 continue;
3261
3262                                         for (int i = 0; i < Arguments.Count; ++i)
3263                                                 if (c.ParameterTypes [i] != ((Argument)Arguments [i]).Type) {
3264                                                         ok = false;
3265                                                         break;
3266                                                 }
3267                                 }
3268
3269                                 if (!ok)
3270                                         continue;
3271
3272                                 return c;
3273                         }
3274
3275                         throw new InternalErrorException ();
3276                 }
3277
3278                 //TODO: implement caching when it will be necessary
3279                 public virtual void CheckObsoleteAttribute (TypeContainer tc, Location loc)
3280                 {
3281                         Constructor ctor = GetOverloadedConstructor (tc);
3282                         if (ctor == null)
3283                                 return;
3284
3285                         ObsoleteAttribute oa = ctor.GetObsoleteAttribute (tc);
3286                         if (oa == null)
3287                                 return;
3288
3289                         AttributeTester.Report_ObsoleteMessage (oa, ctor.GetSignatureForError (), loc);
3290                 }
3291         }
3292
3293         public class ConstructorBaseInitializer : ConstructorInitializer {
3294                 public ConstructorBaseInitializer (ArrayList argument_list, Parameters pars, Location l) :
3295                         base (argument_list, pars, l)
3296                 {
3297                 }
3298
3299                 public override void CheckObsoleteAttribute(TypeContainer tc, Location loc) {
3300                         if (parent_constructor == null)
3301                                 return;
3302
3303                         TypeContainer type_ds = TypeManager.LookupTypeContainer (tc.base_classs_type);
3304                         if (type_ds == null) {
3305                                 ObsoleteAttribute oa = AttributeTester.GetMemberObsoleteAttribute (parent_constructor);
3306
3307                                 if (oa != null)
3308                                         AttributeTester.Report_ObsoleteMessage (oa, TypeManager.CSharpSignature (parent_constructor), loc);
3309
3310                                 return;
3311                         }
3312
3313                         base.CheckObsoleteAttribute (type_ds, loc);
3314                 }
3315
3316         }
3317
3318         public class ConstructorThisInitializer : ConstructorInitializer {
3319                 public ConstructorThisInitializer (ArrayList argument_list, Parameters pars, Location l) :
3320                         base (argument_list, pars, l)
3321                 {
3322                 }
3323         }
3324         
3325         public class Constructor : MethodCore {
3326                 public ConstructorBuilder ConstructorBuilder;
3327                 public ConstructorInitializer Initializer;
3328
3329                 // <summary>
3330                 //   Modifiers allowed for a constructor.
3331                 // </summary>
3332                 public const int AllowedModifiers =
3333                         Modifiers.PUBLIC |
3334                         Modifiers.PROTECTED |
3335                         Modifiers.INTERNAL |
3336                         Modifiers.STATIC |
3337                         Modifiers.UNSAFE |
3338                         Modifiers.EXTERN |              
3339                         Modifiers.PRIVATE;
3340
3341                 bool has_compliant_args = false;
3342                 //
3343                 // The spec claims that static is not permitted, but
3344                 // my very own code has static constructors.
3345                 //
3346                 public Constructor (DeclSpace ds, string name, int mod, Parameters args,
3347                                     ConstructorInitializer init, Location l)
3348                         : base (ds, null, mod, AllowedModifiers, false, name, null, args, l)
3349                 {
3350                         Initializer = init;
3351                 }
3352
3353                 public override string GetSignatureForError()
3354                 {
3355                         return TypeManager.CSharpSignature (ConstructorBuilder);
3356                 }
3357
3358                 public bool HasCompliantArgs {
3359                         get {
3360                                 return has_compliant_args;
3361                         }
3362                 }
3363
3364                 public override AttributeTargets AttributeTargets {
3365                         get {
3366                                 return AttributeTargets.Constructor;
3367                         }
3368                 }
3369
3370
3371                 //
3372                 // Returns true if this is a default constructor
3373                 //
3374                 public bool IsDefault ()
3375                 {
3376                         if ((ModFlags & Modifiers.STATIC) != 0)
3377                                 return  (Parameters.FixedParameters == null ? true : Parameters.Empty) &&
3378                                         (Parameters.ArrayParameter == null ? true : Parameters.Empty);
3379                         
3380                         else
3381                                 return  (Parameters.FixedParameters == null ? true : Parameters.Empty) &&
3382                                         (Parameters.ArrayParameter == null ? true : Parameters.Empty) &&
3383                                         (Initializer is ConstructorBaseInitializer) &&
3384                                         (Initializer.Arguments == null);
3385                 }
3386
3387                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
3388                 {
3389                         ConstructorBuilder.SetCustomAttribute (cb);
3390                 }
3391                 
3392                 protected override bool CheckBase (TypeContainer container)
3393                 {
3394                         base.CheckBase (container);
3395                         
3396                         // Check whether arguments were correct.
3397                         if (!DoDefineParameters ())
3398                                 return false;
3399                         
3400                         if ((ModFlags & Modifiers.STATIC) != 0)
3401                                 return true;
3402                         
3403                         if (container is Struct && ParameterTypes.Length == 0) {
3404                                 Report.Error (568, Location, 
3405                                         "Structs can not contain explicit parameterless " +
3406                                         "constructors");
3407                                 return false;
3408                         }
3409                                 
3410                         //
3411                         // Check in our class for dups
3412                         //
3413                         ArrayList ar = container.InstanceConstructors;
3414                         if (ar != null) {
3415                                 int arLen = ar.Count;
3416                                         
3417                                 for (int i = 0; i < arLen; i++) {
3418                                         Constructor m = (Constructor) ar [i];
3419                                         if (IsDuplicateImplementation (container, m))
3420                                                 return false;
3421                                 }
3422                         }
3423                         
3424                         return true;
3425                 }
3426                 
3427                 //
3428                 // Creates the ConstructorBuilder
3429                 //
3430                 public override bool Define (TypeContainer container)
3431                 {
3432                         MethodAttributes ca = (MethodAttributes.RTSpecialName |
3433                                                MethodAttributes.SpecialName);
3434                         
3435                         if ((ModFlags & Modifiers.STATIC) != 0) {
3436                                 ca |= MethodAttributes.Static | MethodAttributes.Private;
3437                         } else {
3438                                 ca |= MethodAttributes.HideBySig;
3439
3440                                 if ((ModFlags & Modifiers.PUBLIC) != 0)
3441                                         ca |= MethodAttributes.Public;
3442                                 else if ((ModFlags & Modifiers.PROTECTED) != 0){
3443                                         if ((ModFlags & Modifiers.INTERNAL) != 0)
3444                                                 ca |= MethodAttributes.FamORAssem;
3445                                         else 
3446                                                 ca |= MethodAttributes.Family;
3447                                 } else if ((ModFlags & Modifiers.INTERNAL) != 0)
3448                                         ca |= MethodAttributes.Assembly;
3449                                 else if (IsDefault ())
3450                                         ca |= MethodAttributes.Public;
3451                                 else
3452                                         ca |= MethodAttributes.Private;
3453                         }
3454                         
3455                         // Check if arguments were correct.
3456                         if (!CheckBase (container))
3457                                 return false;
3458
3459                         ConstructorBuilder = container.TypeBuilder.DefineConstructor (
3460                                 ca, GetCallingConvention (container is Class), ParameterTypes);
3461
3462                         if ((ModFlags & Modifiers.UNSAFE) != 0)
3463                                 ConstructorBuilder.InitLocals = false;
3464                         
3465                         //
3466                         // HACK because System.Reflection.Emit is lame
3467                         //
3468                         TypeManager.RegisterMethod (ConstructorBuilder, ParameterInfo, ParameterTypes);
3469
3470                         return true;
3471                 }
3472
3473                 //
3474                 // Emits the code
3475                 //
3476                 public override void Emit (TypeContainer container)
3477                 {
3478                         ILGenerator ig = ConstructorBuilder.GetILGenerator ();
3479                         EmitContext ec = new EmitContext (container, Location, ig, null, ModFlags, true);
3480
3481                         //
3482                         // extern methods have no bodies
3483                         //
3484                         if ((ModFlags & Modifiers.EXTERN) != 0) {
3485                                 if ((block != null) && ((ModFlags & Modifiers.EXTERN) != 0)) {
3486                                         Report.Error (
3487                                                 179, Location, "External constructor `" +
3488                                                 TypeManager.CSharpSignature (ConstructorBuilder) +
3489                                                 "' can not have a body");
3490                                         return;
3491                                 }
3492                         } else if (block == null) {
3493                                 Report.Error (
3494                                         501, Location, "Constructor `" +
3495                                         TypeManager.CSharpSignature (ConstructorBuilder) +
3496                                         "' must declare a body since it is not marked extern");
3497                                 return;
3498                         }
3499
3500                         if ((ModFlags & Modifiers.STATIC) == 0){
3501                                 if (container is Class && Initializer == null)
3502                                         Initializer = new ConstructorBaseInitializer (
3503                                                 null, Parameters.EmptyReadOnlyParameters, Location);
3504
3505
3506                                 //
3507                                 // Spec mandates that Initializers will not have
3508                                 // `this' access
3509                                 //
3510                                 ec.IsStatic = true;
3511                                 if (Initializer != null && !Initializer.Resolve (ConstructorBuilder, ec))
3512                                         return;
3513                                 ec.IsStatic = false;
3514                         }
3515
3516                         Parameters.LabelParameters (ec, ConstructorBuilder, Location);
3517                         
3518                         SymbolWriter sw = CodeGen.SymbolWriter;
3519                         bool generate_debugging = false;
3520
3521                         if ((sw != null) && (block != null) &&
3522                                 !Location.IsNull (Location) &&
3523                                 !Location.IsNull (block.EndLocation) &&
3524                                 (Location.SymbolDocument != null)) {
3525                                 sw.OpenMethod (container, ConstructorBuilder, Location, block.EndLocation);
3526
3527                                 generate_debugging = true;
3528                         }
3529
3530                         //
3531                         // Classes can have base initializers and instance field initializers.
3532                         //
3533                         if (container is Class){
3534                                 if ((ModFlags & Modifiers.STATIC) == 0){
3535
3536                                         //
3537                                         // If we use a "this (...)" constructor initializer, then
3538                                         // do not emit field initializers, they are initialized in the other constructor
3539                                         //
3540                                         if (!(Initializer != null && Initializer is ConstructorThisInitializer))
3541                                                 container.EmitFieldInitializers (ec);
3542                                 }
3543                         }
3544                         if (Initializer != null) {
3545                                 Initializer.CheckObsoleteAttribute (container, Location);
3546                                 Initializer.Emit (ec);
3547                         }
3548                         
3549                         if ((ModFlags & Modifiers.STATIC) != 0)
3550                                 container.EmitFieldInitializers (ec);
3551
3552                         if (OptAttributes != null) 
3553                                 OptAttributes.Emit (ec, this);
3554
3555                         // If this is a non-static `struct' constructor and doesn't have any
3556                         // initializer, it must initialize all of the struct's fields.
3557                         if ((container is Struct) && ((ModFlags & Modifiers.STATIC) == 0) && (Initializer == null))
3558                                 Block.AddThisVariable (container, Location);
3559
3560                         ec.EmitTopBlock (block, ParameterInfo, Location);
3561
3562                         if (generate_debugging)
3563                                 sw.CloseMethod ();
3564
3565                         base.Emit (container);
3566
3567                         block = null;
3568                 }
3569
3570                 // For constructors is needed to test only parameters
3571                 protected override bool IsIdentifierClsCompliant (DeclSpace ds)
3572                 {
3573                         if (parameter_types == null || parameter_types.Length == 0)
3574                                 return true;
3575
3576                         TypeContainer tc = ds as TypeContainer;
3577
3578                         for (int i = 0; i < tc.InstanceConstructors.Count; i++) {
3579                                 Constructor c = (Constructor) tc.InstanceConstructors [i];
3580                                                 
3581                                 if (c == this || c.ParameterTypes.Length == 0)
3582                                         continue;
3583
3584                                 if (!c.IsClsCompliaceRequired (ds))
3585                                         continue;
3586                                 
3587                                 if (!AttributeTester.AreOverloadedMethodParamsClsCompliant (parameter_types, c.ParameterTypes)) {
3588                                         Report.Error_T (3006, Location, GetSignatureForError ());
3589                                         return false;
3590                                 }
3591                         }
3592
3593                         if (tc.TypeBuilder.BaseType == null)
3594                                 return true;
3595
3596                         DeclSpace temp_ds = TypeManager.LookupDeclSpace (tc.TypeBuilder.BaseType);
3597                         if (temp_ds != null)
3598                                 return IsIdentifierClsCompliant (temp_ds);
3599
3600                         MemberInfo[] ml = tc.TypeBuilder.BaseType.FindMembers (MemberTypes.Constructor, BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance, null, null);
3601                         // Skip parameter-less ctor
3602                         if (ml.Length < 2)
3603                                 return true;
3604
3605                         foreach (ConstructorInfo ci in ml) {
3606                                 object[] cls_attribute = ci.GetCustomAttributes (TypeManager.cls_compliant_attribute_type, false);
3607                                 if (cls_attribute.Length == 1 && (!((CLSCompliantAttribute)cls_attribute[0]).IsCompliant))
3608                                         continue;
3609
3610                                 if (!AttributeTester.AreOverloadedMethodParamsClsCompliant (parameter_types, TypeManager.GetArgumentTypes (ci))) {
3611                                         Report.Error_T (3006, Location, GetSignatureForError ());
3612                                         return false;
3613                                 }
3614                         }
3615                         
3616                         return true;
3617                 }
3618
3619                 protected override bool VerifyClsCompliance (DeclSpace ds)
3620                 {
3621                         if (!base.VerifyClsCompliance (ds) || !IsExposedFromAssembly (ds)) {
3622                                 return false;
3623                         }
3624                         
3625                         if (ds.TypeBuilder.IsSubclassOf (TypeManager.attribute_type)) {
3626                                 foreach (Type param in parameter_types) {
3627                                         if (param.IsArray) {
3628                                                 return false;
3629                                         }
3630                                 }
3631                         }
3632                         has_compliant_args = true;
3633                         return true;
3634                 }
3635
3636         }
3637
3638         /// <summary>
3639         /// Interface for MethodData class. Holds links to parent members to avoid member duplication.
3640         /// </summary>
3641         public interface IMethodData
3642         {
3643                 CallingConventions CallingConventions { get; }
3644                 Location Location { get; }
3645                 string MethodName { get; }
3646                 Type[] ParameterTypes { get; }
3647                 Type ReturnType { get; }
3648
3649                 Attributes OptAttributes { get; }
3650                 Block Block { get; }
3651
3652                 EmitContext CreateEmitContext (TypeContainer tc, ILGenerator ig);
3653                 ObsoleteAttribute GetObsoleteAttribute ();
3654                 string GetSignatureForError (TypeContainer tc);
3655                 bool IsExcluded (EmitContext ec);
3656         }
3657
3658         //
3659         // Encapsulates most of the Method's state
3660         //
3661         public class MethodData {
3662
3663                 readonly IMethodData method;
3664
3665                 //
3666                 // The return type of this method
3667                 //
3668                 public readonly InternalParameters ParameterInfo;
3669
3670                 //
3671                 // Are we implementing an interface ?
3672                 //
3673                 public bool IsImplementing = false;
3674
3675                 //
3676                 // Protected data.
3677                 //
3678                 protected MemberBase member;
3679                 protected int modifiers;
3680                 protected MethodAttributes flags;
3681
3682                 MethodBuilder builder = null;
3683                 public MethodBuilder MethodBuilder {
3684                         get {
3685                                 return builder;
3686                         }
3687                 }
3688
3689                 public MethodData (MemberBase member, InternalParameters parameters,
3690                                    int modifiers, MethodAttributes flags, IMethodData method)
3691                 {
3692                         this.member = member;
3693                         this.ParameterInfo = parameters;
3694                         this.modifiers = modifiers;
3695                         this.flags = flags;
3696
3697                         this.method = method;
3698                 }
3699
3700                 public bool Define (TypeContainer container)
3701                 {
3702                         MethodInfo implementing = null;
3703                         string prefix;
3704
3705                         if (member.IsExplicitImpl)
3706                                 prefix = member.InterfaceType.FullName + ".";
3707                         else
3708                                 prefix = "";
3709
3710                         string name = method.MethodName;
3711                         string method_name = prefix + name;
3712                         Type[] ParameterTypes = method.ParameterTypes;
3713
3714                         if (container.Pending != null){
3715                                 if (member is Indexer)
3716                                         implementing = container.Pending.IsInterfaceIndexer (
3717                                                 member.InterfaceType, method.ReturnType, ParameterTypes);
3718                                 else
3719                                         implementing = container.Pending.IsInterfaceMethod (
3720                                                 member.InterfaceType, name, method.ReturnType, ParameterTypes);
3721
3722                                 if (member.InterfaceType != null && implementing == null){
3723                                         Report.Error (539, method.Location, "'{0}' in explicit interface declaration is not an interface", method_name);
3724                                         return false;
3725                                 }
3726                         }
3727
3728                         //
3729                         // For implicit implementations, make sure we are public, for
3730                         // explicit implementations, make sure we are private.
3731                         //
3732                         if (implementing != null){
3733                                 //
3734                                 // Setting null inside this block will trigger a more
3735                                 // verbose error reporting for missing interface implementations
3736                                 //
3737                                 // The "candidate" function has been flagged already
3738                                 // but it wont get cleared
3739                                 //
3740                                 if (member.IsExplicitImpl){
3741                                         if ((modifiers & (Modifiers.PUBLIC | Modifiers.ABSTRACT | Modifiers.VIRTUAL)) != 0){
3742                                                 Modifiers.Error_InvalidModifier (method.Location, "public, virtual or abstract");
3743                                                 implementing = null;
3744                                         }
3745                                 } else if ((flags & MethodAttributes.MemberAccessMask) != MethodAttributes.Public){
3746                                         if (TypeManager.IsInterfaceType (implementing.DeclaringType)){
3747                                                 //
3748                                                 // If this is an interface method implementation,
3749                                                 // check for public accessibility
3750                                                 //
3751                                                 implementing = null;
3752                                         } else if ((flags & MethodAttributes.MemberAccessMask) == MethodAttributes.Private){
3753                                                 // We may never be private.
3754                                                 implementing = null;
3755                                         } else if ((modifiers & Modifiers.OVERRIDE) == 0){
3756                                                 //
3757                                                 // We may be protected if we're overriding something.
3758                                                 //
3759                                                 implementing = null;
3760                                         }
3761                                 } 
3762                                         
3763                                 //
3764                                 // Static is not allowed
3765                                 //
3766                                 if ((modifiers & Modifiers.STATIC) != 0){
3767                                         implementing = null;
3768                                         Modifiers.Error_InvalidModifier (method.Location, "static");
3769                                 }
3770                         }
3771                         
3772                         //
3773                         // If implementing is still valid, set flags
3774                         //
3775                         if (implementing != null){
3776                                 //
3777                                 // When implementing interface methods, set NewSlot
3778                                 // unless, we are overwriting a method.
3779                                 //
3780                                 if (implementing.DeclaringType.IsInterface){
3781                                         if ((modifiers & Modifiers.OVERRIDE) == 0)
3782                                                 flags |= MethodAttributes.NewSlot;
3783                                 }
3784                                 flags |=
3785                                         MethodAttributes.Virtual |
3786                                         MethodAttributes.HideBySig;
3787
3788                                 // Set Final unless we're virtual, abstract or already overriding a method.
3789                                 if ((modifiers & (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE)) == 0)
3790                                         flags |= MethodAttributes.Final;
3791
3792                                 // Get the method name from the explicit interface.
3793                                 if (member.InterfaceType != null) {
3794                                         name = implementing.Name;
3795                                         method_name = prefix + name;
3796                                 }
3797
3798                                 IsImplementing = true;
3799                         }
3800
3801                         EmitContext ec = method.CreateEmitContext (container, null);
3802
3803                         DefineMethodBuilder (ec, container, method_name, ParameterTypes);
3804
3805                         if (builder == null)
3806                                 return false;
3807
3808                         if ((modifiers & Modifiers.UNSAFE) != 0)
3809                                 builder.InitLocals = false;
3810
3811                         if (IsImplementing){
3812                                 //
3813                                 // clear the pending implemntation flag
3814                                 //
3815                                 if (member is Indexer) {
3816                                         container.Pending.ImplementIndexer (
3817                                                 member.InterfaceType, builder, method.ReturnType,
3818                                                 ParameterTypes, true);
3819                                 } else
3820                                         container.Pending.ImplementMethod (
3821                                                 member.InterfaceType, name, method.ReturnType,
3822                                                 ParameterTypes, member.IsExplicitImpl);
3823
3824                                 if (member.IsExplicitImpl)
3825                                         container.TypeBuilder.DefineMethodOverride (
3826                                                 builder, implementing);
3827
3828                         }
3829
3830                         if (!TypeManager.RegisterMethod (builder, ParameterInfo, ParameterTypes)) {
3831                                 Report.Error (111, method.Location,
3832                                               "Class `" + container.Name +
3833                                               "' already contains a definition with the " +
3834                                               "same return value and parameter types as the " +
3835                                               "'get' method of property `" + member.Name + "'");
3836                                 return false;
3837                         }
3838
3839                         TypeManager.AddMethod (builder, method);
3840
3841                         return true;
3842                 }
3843
3844
3845                 /// <summary>
3846                 /// Create the MethodBuilder for the method 
3847                 /// </summary>
3848                 void DefineMethodBuilder (EmitContext ec, TypeContainer container, string method_name, Type[] ParameterTypes)
3849                 {
3850                         const int extern_static = Modifiers.EXTERN | Modifiers.STATIC;
3851
3852                         if ((modifiers & extern_static) == extern_static) {
3853
3854                                 if (method.OptAttributes != null) {
3855                                         Attribute dllimport_attribute = method.OptAttributes.Search (TypeManager.dllimport_type, ec);
3856                                         if (dllimport_attribute != null) {
3857                                                 flags |= MethodAttributes.PinvokeImpl;
3858                                                 builder = dllimport_attribute.DefinePInvokeMethod (
3859                                                         ec, container.TypeBuilder, method_name, flags,
3860                                                         method.ReturnType, ParameterTypes);
3861
3862                                                 return;
3863                                         }
3864                                 }
3865
3866                                 // for extern static method must be specified either DllImport attribute or MethodImplAttribute.
3867                                 // We are more strict than Microsoft and report CS0626 like error
3868                                 if (method.OptAttributes == null ||
3869                                         !method.OptAttributes.Contains (TypeManager.methodimpl_attr_type, ec)) {
3870                                         //"Method, operator, or accessor '{0}' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation"
3871                                         Report.Error_T (626, method.Location, method.GetSignatureForError (container));
3872                                         return;
3873                                 }
3874                         }
3875
3876                         builder = container.TypeBuilder.DefineMethod (
3877                                 method_name, flags, method.CallingConventions,
3878                                 method.ReturnType, ParameterTypes);
3879                 }
3880
3881                 //
3882                 // Emits the code
3883                 // 
3884                 public void Emit (TypeContainer container, Attributable kind)
3885                 {
3886                         EmitContext ec;
3887
3888                         if ((flags & MethodAttributes.PinvokeImpl) == 0)
3889                                 ec = method.CreateEmitContext (container, builder.GetILGenerator ());
3890                         else
3891                                 ec = method.CreateEmitContext (container, null);
3892
3893                         Location loc = method.Location;
3894                         Attributes OptAttributes = method.OptAttributes;
3895
3896                         if (OptAttributes != null)
3897                                 OptAttributes.Emit (ec, kind);
3898
3899                         if (member is MethodCore)
3900                                 ((MethodCore) member).Parameters.LabelParameters (ec, MethodBuilder, loc);
3901
3902                         SymbolWriter sw = CodeGen.SymbolWriter;
3903                         Block block = method.Block;
3904                         
3905                         //
3906                         // abstract or extern methods have no bodies
3907                         //
3908                         if ((modifiers & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0){
3909                                 if (block == null) {
3910                                         if ((sw != null) && ((modifiers & Modifiers.EXTERN) != 0) &&
3911                                             !Location.IsNull (loc) &&
3912                                             (method.Location.SymbolDocument != null)) {
3913                                                 sw.OpenMethod (container, MethodBuilder, loc, loc);
3914                                                 sw.CloseMethod ();
3915                                         }
3916
3917                                         return;
3918                                 }
3919
3920                                 //
3921                                 // abstract or extern methods have no bodies.
3922                                 //
3923                                 if ((modifiers & Modifiers.ABSTRACT) != 0)
3924                                         Report.Error (
3925                                                 500, method.Location, "Abstract method `" +
3926                                                 TypeManager.CSharpSignature (builder) +
3927                                                 "' can not have a body");
3928
3929                                 if ((modifiers & Modifiers.EXTERN) != 0)
3930                                         Report.Error (
3931                                                 179, method.Location, "External method `" +
3932                                                 TypeManager.CSharpSignature (builder) +
3933                                                 "' can not have a body");
3934
3935                                 return;
3936                         }
3937
3938                         //
3939                         // Methods must have a body unless they're extern or abstract
3940                         //
3941                         if (block == null) {
3942                                 Report.Error (
3943                                         501, method.Location, "Method `" +
3944                                         TypeManager.CSharpSignature (builder) +
3945                                         "' must declare a body since it is not marked " +
3946                                         "abstract or extern");
3947                                 return;
3948                         }
3949
3950                         //
3951                         // Handle destructors specially
3952                         //
3953                         // FIXME: This code generates buggy code
3954                         //
3955                         if ((sw != null) && !Location.IsNull (loc) &&
3956                             !Location.IsNull (block.EndLocation) &&
3957                             (loc.SymbolDocument != null)) {
3958                                 sw.OpenMethod (container, MethodBuilder, loc, block.EndLocation);
3959
3960                                 if (member is Destructor)
3961                                         EmitDestructor (ec, block);
3962                                 else
3963                                         ec.EmitTopBlock (block, ParameterInfo, loc);
3964
3965                                 sw.CloseMethod ();
3966                         } else {
3967                                 if (member is Destructor)
3968                                         EmitDestructor (ec, block);
3969                                 else
3970                                         ec.EmitTopBlock (block, ParameterInfo, loc);
3971                         }
3972                 }
3973
3974                 void EmitDestructor (EmitContext ec, Block block)
3975                 {
3976                         ILGenerator ig = ec.ig;
3977                         
3978                         Label finish = ig.DefineLabel ();
3979
3980                         block.SetDestructor ();
3981                         
3982                         ig.BeginExceptionBlock ();
3983                         ec.ReturnLabel = finish;
3984                         ec.HasReturnLabel = true;
3985                         ec.EmitTopBlock (block, null, method.Location);
3986                         
3987                         // ig.MarkLabel (finish);
3988                         ig.BeginFinallyBlock ();
3989                         
3990                         if (ec.ContainerType.BaseType != null) {
3991                                 Expression member_lookup = Expression.MemberLookup (
3992                                         ec, ec.ContainerType.BaseType, null, ec.ContainerType.BaseType,
3993                                         "Finalize", MemberTypes.Method, Expression.AllBindingFlags, method.Location);
3994
3995                                 if (member_lookup != null){
3996                                         MethodGroupExpr parent_destructor = ((MethodGroupExpr) member_lookup);
3997                                 
3998                                         ig.Emit (OpCodes.Ldarg_0);
3999                                         ig.Emit (OpCodes.Call, (MethodInfo) parent_destructor.Methods [0]);
4000                                 }
4001                         }
4002                         
4003                         ig.EndExceptionBlock ();
4004                         //ig.MarkLabel (ec.ReturnLabel);
4005                         ig.Emit (OpCodes.Ret);
4006                 }
4007         }
4008
4009         public class Destructor : Method {
4010
4011                 public Destructor (DeclSpace ds, Expression return_type, int mod, string name,
4012                                    Parameters parameters, Attributes attrs, Location l)
4013                         : base (ds, return_type, mod, false, name, parameters, attrs, l)
4014                 { }
4015
4016                 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
4017                 {
4018                         if (a.Type == TypeManager.conditional_attribute_type) {
4019                                 // Conditional not valid on '{0}' because it is a destructor, operator, or explicit interface implementation
4020                                 Report.Error_T (577, Location, GetSignatureForError ());
4021                                 return;
4022                         }
4023
4024                         base.ApplyAttributeBuilder (a, cb);
4025                 }
4026         }
4027         
4028         abstract public class MemberBase : MemberCore {
4029                 public Expression Type;
4030
4031                 public MethodAttributes flags;
4032                         
4033                 protected readonly int explicit_mod_flags;
4034
4035                 //
4036                 // The "short" name of this property / indexer / event.  This is the
4037                 // name without the explicit interface.
4038                 //
4039                 public string ShortName;
4040
4041                 //
4042                 // The type of this property / indexer / event
4043                 //
4044                 public Type MemberType;
4045
4046                 //
4047                 // If true, this is an explicit interface implementation
4048                 //
4049                 public bool IsExplicitImpl = false;
4050
4051                 //
4052                 // The name of the interface we are explicitly implementing
4053                 //
4054                 public string ExplicitInterfaceName = null;
4055
4056                 //
4057                 // Whether this is an interface member.
4058                 //
4059                 public bool IsInterface;
4060
4061                 //
4062                 // If true, the interface type we are explicitly implementing
4063                 //
4064                 public Type InterfaceType = null;
4065
4066                 //
4067                 // The method we're overriding if this is an override method.
4068                 //
4069                 protected MethodInfo parent_method = null;
4070                 public MethodInfo ParentMethod {
4071                         get {
4072                                 return parent_method;
4073                         }
4074                 }
4075
4076                 //
4077                 // The constructor is only exposed to our children
4078                 //
4079                 protected MemberBase (Expression type, int mod, int allowed_mod, int def_mod, string name,
4080                                       Attributes attrs, Location loc)
4081                         : base (name, attrs, loc)
4082                 {
4083                         explicit_mod_flags = mod;
4084                         Type = type;
4085                         ModFlags = Modifiers.Check (allowed_mod, mod, def_mod, loc);
4086                 }
4087
4088                 protected virtual bool CheckBase (TypeContainer container)
4089                 {
4090                         if ((container is Struct) || (RootContext.WarningLevel > 3)){
4091                                 if ((ModFlags & Modifiers.PROTECTED) != 0 && (container.ModFlags & Modifiers.SEALED) != 0){
4092                                         if (container is Struct){
4093                                                 Report.Error (666, Location, "Protected member in struct declaration");
4094                                                 return false;
4095                                         } else
4096                                                 Report.Warning (628, Location, "Member " + container.MakeName (Name) + " protected in sealed class");
4097                                 }
4098                         }
4099                         return true;
4100                 }
4101
4102                 protected void WarningNotHiding (TypeContainer parent)
4103                 {
4104                         Report.Warning (
4105                                 109, Location,
4106                                 "The member " + parent.MakeName (Name) + " does not hide an " +
4107                                 "inherited member.  The keyword new is not required");
4108                                                            
4109                 }
4110
4111                 void Error_CannotChangeAccessModifiers (TypeContainer parent, MethodInfo parent_method,
4112                                                         string name)
4113                 {
4114                         //
4115                         // FIXME: report the old/new permissions?
4116                         //
4117                         Report.Error (
4118                                 507, Location, parent.MakeName (Name) +
4119                                 ": can't change the access modifiers when overriding inherited " +
4120                                 "member `" + name + "'");
4121                 }
4122                 
4123                 //
4124                 // Performs various checks on the MethodInfo `mb' regarding the modifier flags
4125                 // that have been defined.
4126                 //
4127                 // `name' is the user visible name for reporting errors (this is used to
4128                 // provide the right name regarding method names and properties)
4129                 //
4130                 protected bool CheckMethodAgainstBase (TypeContainer parent, MethodAttributes my_attrs,
4131                                                        MethodInfo mb, string name)
4132                 {
4133                         bool ok = true;
4134                         
4135                         if ((ModFlags & Modifiers.OVERRIDE) != 0){
4136                                 if (!(mb.IsAbstract || mb.IsVirtual)){
4137                                         Report.Error (
4138                                                 506, Location, parent.MakeName (Name) +
4139                                                 ": cannot override inherited member `" +
4140                                                 name + "' because it is not " +
4141                                                 "virtual, abstract or override");
4142                                         ok = false;
4143                                 }
4144                                 
4145                                 // Now we check that the overriden method is not final
4146                                 
4147                                 if (mb.IsFinal) {
4148                                         // This happens when implementing interface methods.
4149                                         if (mb.IsHideBySig && mb.IsVirtual) {
4150                                                 Report.Error (
4151                                                         506, Location, parent.MakeName (Name) +
4152                                                         ": cannot override inherited member `" +
4153                                                         name + "' because it is not " +
4154                                                         "virtual, abstract or override");
4155                                         } else
4156                                                 Report.Error (239, Location, parent.MakeName (Name) + " : cannot " +
4157                                                               "override inherited member `" + name +
4158                                                               "' because it is sealed.");
4159                                         ok = false;
4160                                 }
4161                                 //
4162                                 // Check that the permissions are not being changed
4163                                 //
4164                                 MethodAttributes thisp = my_attrs & MethodAttributes.MemberAccessMask;
4165                                 MethodAttributes parentp = mb.Attributes & MethodAttributes.MemberAccessMask;
4166
4167                                 //
4168                                 // special case for "protected internal"
4169                                 //
4170
4171                                 if ((parentp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
4172                                         //
4173                                         // when overriding protected internal, the method can be declared
4174                                         // protected internal only within the same assembly
4175                                         //
4176
4177                                         if ((thisp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
4178                                                 if (parent.TypeBuilder.Assembly != mb.DeclaringType.Assembly){
4179                                                         //
4180                                                         // assemblies differ - report an error
4181                                                         //
4182                                                         
4183                                                         Error_CannotChangeAccessModifiers (parent, mb, name);
4184                                                     ok = false;
4185                                                 } else if (thisp != parentp) {
4186                                                         //
4187                                                         // same assembly, but other attributes differ - report an error
4188                                                         //
4189                                                         
4190                                                         Error_CannotChangeAccessModifiers (parent, mb, name);
4191                                                         ok = false;
4192                                                 };
4193                                         } else if ((thisp & MethodAttributes.Family) != MethodAttributes.Family) {
4194                                                 //
4195                                                 // if it's not "protected internal", it must be "protected"
4196                                                 //
4197
4198                                                 Error_CannotChangeAccessModifiers (parent, mb, name);
4199                                                 ok = false;
4200                                         } else if (parent.TypeBuilder.Assembly == mb.DeclaringType.Assembly) {
4201                                                 //
4202                                                 // protected within the same assembly - an error
4203                                                 //
4204                                                 Error_CannotChangeAccessModifiers (parent, mb, name);
4205                                                 ok = false;
4206                                         } else if ((thisp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem)) != 
4207                                                    (parentp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem))) {
4208                                                 //
4209                                                 // protected ok, but other attributes differ - report an error
4210                                                 //
4211                                                 Error_CannotChangeAccessModifiers (parent, mb, name);
4212                                                 ok = false;
4213                                         }
4214                                 } else {
4215                                         if (thisp != parentp){
4216                                                 Error_CannotChangeAccessModifiers (parent, mb, name);
4217                                                 ok = false;
4218                                         }
4219                                 }
4220                         }
4221
4222                         if (mb.IsVirtual || mb.IsAbstract){
4223                                 if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE)) == 0){
4224                                         if (Name != "Finalize"){
4225                                                 Report.Warning (
4226                                                         114, 2, Location, parent.MakeName (Name) + 
4227                                                         " hides inherited member `" + name +
4228                                                         "'.  To make the current member override that " +
4229                                                         "implementation, add the override keyword, " +
4230                                                         "otherwise use the new keyword");
4231                                                 ModFlags |= Modifiers.NEW;
4232                                         }
4233                                 }
4234                         } else {
4235                                 if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE)) == 0){
4236                                         if (Name != "Finalize"){
4237                                                 Report.Warning (
4238                                                         108, 1, Location, "The keyword new is required on " +
4239                                                         parent.MakeName (Name) + " because it hides " +
4240                                                         "inherited member `" + name + "'");
4241                                                 ModFlags |= Modifiers.NEW;
4242                                         }
4243                                 }
4244                         }
4245
4246                         return ok;
4247                 }
4248
4249                 protected virtual bool CheckParameters (DeclSpace ds, Type [] parameters)
4250                 {
4251                         bool error = false;
4252
4253                         foreach (Type partype in parameters){
4254                                 if (partype == TypeManager.void_type) {
4255                                         Report.Error (
4256                                                 1547, Location, "Keyword 'void' cannot " +
4257                                                 "be used in this context");
4258                                         return false;
4259                                 }
4260
4261                                 if (partype.IsPointer){
4262                                         if (!UnsafeOK (ds))
4263                                                 error = true;
4264                                         if (!TypeManager.VerifyUnManaged (TypeManager.GetElementType (partype), Location))
4265                                                 error = true;
4266                                 }
4267
4268                                 if (ds.AsAccessible (partype, ModFlags))
4269                                         continue;
4270
4271                                 if (this is Indexer)
4272                                         Report.Error (55, Location,
4273                                                       "Inconsistent accessibility: parameter type `" +
4274                                                       TypeManager.CSharpName (partype) + "' is less " +
4275                                                       "accessible than indexer `" + Name + "'");
4276                                 else if ((this is Method) && ((Method) this).IsOperator)
4277                                         Report.Error (57, Location,
4278                                                       "Inconsistent accessibility: parameter type `" +
4279                                                       TypeManager.CSharpName (partype) + "' is less " +
4280                                                       "accessible than operator `" + Name + "'");
4281                                 else
4282                                         Report.Error (51, Location,
4283                                                       "Inconsistent accessibility: parameter type `" +
4284                                                       TypeManager.CSharpName (partype) + "' is less " +
4285                                                       "accessible than method `" + Name + "'");
4286                                 error = true;
4287                         }
4288
4289                         return !error;
4290                 }
4291
4292                 protected virtual bool DoDefine (TypeContainer container)
4293                 {
4294                         if (Name == null)
4295                                 Name = "this";
4296
4297                         if (IsInterface) {
4298                                 ModFlags = Modifiers.PUBLIC |
4299                                         Modifiers.ABSTRACT |
4300                                         Modifiers.VIRTUAL | (ModFlags & Modifiers.UNSAFE);
4301
4302                                 flags = MethodAttributes.Public |
4303                                         MethodAttributes.Abstract |
4304                                         MethodAttributes.HideBySig |
4305                                         MethodAttributes.NewSlot |
4306                                         MethodAttributes.Virtual;
4307                         } else {
4308                                 if (!container.MethodModifiersValid (ModFlags, Name, Location))
4309                                         return false;
4310
4311                                 flags = Modifiers.MethodAttr (ModFlags);
4312                         }
4313
4314                         // Lookup Type, verify validity
4315                         MemberType = container.ResolveType (Type, false, Location);
4316                         if (MemberType == null)
4317                                 return false;
4318
4319                         if ((container.ModFlags & Modifiers.SEALED) != 0){
4320                                 if ((ModFlags & (Modifiers.VIRTUAL|Modifiers.ABSTRACT)) != 0){
4321                                         Report.Error (549, Location, "Virtual method can not be contained in sealed class");
4322                                         return false;
4323                                 }
4324                         }
4325                         
4326                         // verify accessibility
4327                         if (!container.AsAccessible (MemberType, ModFlags)) {
4328                                 if (this is Property)
4329                                         Report.Error (53, Location,
4330                                                       "Inconsistent accessibility: property type `" +
4331                                                       TypeManager.CSharpName (MemberType) + "' is less " +
4332                                                       "accessible than property `" + Name + "'");
4333                                 else if (this is Indexer)
4334                                         Report.Error (54, Location,
4335                                                       "Inconsistent accessibility: indexer return type `" +
4336                                                       TypeManager.CSharpName (MemberType) + "' is less " +
4337                                                       "accessible than indexer `" + Name + "'");
4338                                 else if (this is Method) {
4339                                         if (((Method) this).IsOperator)
4340                                                 Report.Error (56, Location,
4341                                                               "Inconsistent accessibility: return type `" +
4342                                                               TypeManager.CSharpName (MemberType) + "' is less " +
4343                                                               "accessible than operator `" + Name + "'");
4344                                         else
4345                                                 Report.Error (50, Location,
4346                                                               "Inconsistent accessibility: return type `" +
4347                                                               TypeManager.CSharpName (MemberType) + "' is less " +
4348                                                               "accessible than method `" + Name + "'");
4349                                 } else
4350                                         Report.Error (52, Location,
4351                                                       "Inconsistent accessibility: field type `" +
4352                                                       TypeManager.CSharpName (MemberType) + "' is less " +
4353                                                       "accessible than field `" + Name + "'");
4354                                 return false;
4355                         }
4356
4357                         if (MemberType.IsPointer && !UnsafeOK (container))
4358                                 return false;
4359                         
4360                         //
4361                         // Check for explicit interface implementation
4362                         //
4363                         if ((ExplicitInterfaceName == null) && (Name.IndexOf ('.') != -1)){
4364                                 int pos = Name.LastIndexOf ('.');
4365
4366                                 ExplicitInterfaceName = Name.Substring (0, pos);
4367                                 ShortName = Name.Substring (pos + 1);
4368                         } else
4369                                 ShortName = Name;
4370
4371                         if (ExplicitInterfaceName != null) {
4372                                 InterfaceType  = container.FindType (
4373                                         Location, ExplicitInterfaceName);
4374                                 if (InterfaceType == null)
4375                                         return false;
4376
4377                                 if (InterfaceType.IsClass) {
4378                                         Report.Error (538, Location, "'{0}' in explicit interface declaration is not an interface", ExplicitInterfaceName);
4379                                         return false;
4380                                 }
4381
4382                                 // Compute the full name that we need to export.
4383                                 Name = InterfaceType.FullName + "." + ShortName;
4384                                 
4385                                 if (!container.VerifyImplements (InterfaceType, ShortName, Name, Location))
4386                                         return false;
4387                                 
4388                                 Modifiers.Check (Modifiers.AllowedExplicitImplFlags, explicit_mod_flags, 0, Location);
4389                                 
4390                                 IsExplicitImpl = true;
4391                         } else
4392                                 IsExplicitImpl = false;
4393
4394                         return true;
4395                 }
4396
4397                 /// <summary>
4398                 /// Use this method when MethodBuilder is null
4399                 /// </summary>
4400                 public virtual string GetSignatureForError (TypeContainer tc)
4401                 {
4402                         return String.Concat (tc.Name, '.', Name);
4403                 }
4404
4405                 protected override bool IsIdentifierClsCompliant (DeclSpace ds)
4406                 {
4407                         return IsIdentifierAndParamClsCompliant (ds, Name, null, null);
4408                 }
4409
4410                 protected override bool VerifyClsCompliance(DeclSpace ds)
4411                 {
4412                         if (base.VerifyClsCompliance (ds)) {
4413                                 return true;
4414                         }
4415
4416                         if (IsInterface && HasClsCompliantAttribute && ds.IsClsCompliaceRequired (ds)) {
4417                                 Report.Error_T (3010, Location, GetSignatureForError ());
4418                         }
4419                         return false;
4420                 }
4421
4422                 protected override void VerifyObsoleteAttribute()
4423                 {
4424                         CheckUsageOfObsoleteAttribute (MemberType);
4425                 }
4426         }
4427
4428         //
4429         // Fields and Events both generate FieldBuilders, we use this to share 
4430         // their common bits.  This is also used to flag usage of the field
4431         //
4432         abstract public class FieldBase : MemberBase {
4433                 public FieldBuilder  FieldBuilder;
4434                 public Status status;
4435
4436                 [Flags]
4437                 public enum Status : byte { ASSIGNED = 1, USED = 2 }
4438
4439                 static string[] attribute_targets = new string [] { "field" };
4440
4441                 //
4442                 // The constructor is only exposed to our children
4443                 //
4444                 protected FieldBase (Expression type, int mod, int allowed_mod, string name,
4445                                      object init, Attributes attrs, Location loc)
4446                         : base (type, mod, allowed_mod, Modifiers.PRIVATE, name, attrs, loc)
4447                 {
4448                         this.init = init;
4449                 }
4450
4451                 public override AttributeTargets AttributeTargets {
4452                         get {
4453                                 return AttributeTargets.Field;
4454                         }
4455                 }
4456
4457                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
4458                 {
4459                         if (a.Type == TypeManager.marshal_as_attr_type) {
4460                                 UnmanagedMarshal marshal = a.GetMarshal ();
4461                                 if (marshal != null) {
4462                                         FieldBuilder.SetMarshal (marshal);
4463                                         return;
4464                                 }
4465                                 Report.Warning_T (-24, a.Location);
4466                                 return;
4467                         }
4468
4469                         
4470                         FieldBuilder.SetCustomAttribute (cb);
4471                 }
4472
4473                 //
4474                 // Whether this field has an initializer.
4475                 //
4476                 public bool HasInitializer {
4477                         get {
4478                                 return init != null;
4479                         }
4480                 }
4481
4482                 protected readonly Object init;
4483                 // Private.
4484                 Expression init_expr;
4485                 bool init_expr_initialized = false;
4486
4487                 //
4488                 // Resolves and returns the field initializer.
4489                 //
4490                 public Expression GetInitializerExpression (EmitContext ec)
4491                 {
4492                         if (init_expr_initialized)
4493                                 return init_expr;
4494
4495                         Expression e;
4496                         if (init is Expression)
4497                                 e = (Expression) init;
4498                         else
4499                                 e = new ArrayCreation (Type, "", (ArrayList)init, Location);
4500
4501                         ec.IsFieldInitializer = true;
4502                         e = e.DoResolve (ec);
4503                         ec.IsFieldInitializer = false;
4504
4505                         init_expr = e;
4506                         init_expr_initialized = true;
4507
4508                         return init_expr;
4509                 }
4510
4511                 protected override bool DoDefine (TypeContainer container)
4512                 {
4513                         if (!base.DoDefine (container))
4514                                 return false;
4515
4516                         if (MemberType == TypeManager.void_type) {
4517                                 Report.Error (1547, Location,
4518                                               "Keyword 'void' cannot be used in this context");
4519                                 return false;
4520                         }
4521
4522                         return true;
4523                 }
4524
4525                 public override string GetSignatureForError ()
4526                 {
4527                         return TypeManager.GetFullNameSignature (FieldBuilder);
4528                 }
4529
4530                 protected override string[] ValidAttributeTargets {
4531                         get {
4532                                 return attribute_targets;
4533                         }
4534                 }
4535
4536                 protected override bool VerifyClsCompliance (DeclSpace ds)
4537                 {
4538                         if (!base.VerifyClsCompliance (ds))
4539                                 return false;
4540
4541                         if (FieldBuilder == null) {
4542                                 return true;
4543                         }
4544
4545                         if (!AttributeTester.IsClsCompliant (FieldBuilder.FieldType)) {
4546                                 Report.Error_T (3003, Location, GetSignatureForError ());
4547                         }
4548                         return true;
4549                 }
4550
4551
4552                 public void SetAssigned ()
4553                 {
4554                         status |= Status.ASSIGNED;
4555                 }
4556         }
4557
4558         //
4559         // The Field class is used to represents class/struct fields during parsing.
4560         //
4561         public class Field : FieldBase {
4562                 // <summary>
4563                 //   Modifiers allowed in a class declaration
4564                 // </summary>
4565                 const int AllowedModifiers =
4566                         Modifiers.NEW |
4567                         Modifiers.PUBLIC |
4568                         Modifiers.PROTECTED |
4569                         Modifiers.INTERNAL |
4570                         Modifiers.PRIVATE |
4571                         Modifiers.STATIC |
4572                         Modifiers.VOLATILE |
4573                         Modifiers.UNSAFE |
4574                         Modifiers.READONLY;
4575
4576                 public Field (Expression type, int mod, string name, Object expr_or_array_init,
4577                               Attributes attrs, Location loc)
4578                         : base (type, mod, AllowedModifiers, name, expr_or_array_init, attrs, loc)
4579                 {
4580                 }
4581
4582                 public override bool Define (TypeContainer container)
4583                 {
4584                         MemberType = container.ResolveType (Type, false, Location);
4585                         
4586                         if (MemberType == null)
4587                                 return false;
4588
4589                         CheckBase (container);
4590                         
4591                         if (!container.AsAccessible (MemberType, ModFlags)) {
4592                                 Report.Error (52, Location,
4593                                               "Inconsistent accessibility: field type `" +
4594                                               TypeManager.CSharpName (MemberType) + "' is less " +
4595                                               "accessible than field `" + Name + "'");
4596                                 return false;
4597                         }
4598
4599                         if (MemberType.IsPointer && !UnsafeOK (container))
4600                                 return false;
4601                         
4602                         if (RootContext.WarningLevel > 1){
4603                                 Type ptype = container.TypeBuilder.BaseType;
4604
4605                                 // ptype is only null for System.Object while compiling corlib.
4606                                 if (ptype != null){
4607                                         TypeContainer.FindMembers (
4608                                                 ptype, MemberTypes.Method,
4609                                                 BindingFlags.Public |
4610                                                 BindingFlags.Static | BindingFlags.Instance,
4611                                                 System.Type.FilterName, Name);
4612                                 }
4613                         }
4614
4615                         if ((ModFlags & Modifiers.VOLATILE) != 0){
4616                                 if (!MemberType.IsClass){
4617                                         Type vt = MemberType;
4618                                         
4619                                         if (TypeManager.IsEnumType (vt))
4620                                                 vt = TypeManager.EnumToUnderlying (MemberType);
4621
4622                                         if (!((vt == TypeManager.bool_type) ||
4623                                               (vt == TypeManager.sbyte_type) ||
4624                                               (vt == TypeManager.byte_type) ||
4625                                               (vt == TypeManager.short_type) ||
4626                                               (vt == TypeManager.ushort_type) ||
4627                                               (vt == TypeManager.int32_type) ||
4628                                               (vt == TypeManager.uint32_type) ||    
4629                                               (vt == TypeManager.char_type) ||
4630                                               (vt == TypeManager.float_type) ||
4631                                               (!vt.IsValueType))){
4632                                                 Report.Error (
4633                                                         677, Location, container.MakeName (Name) +
4634                                                         " A volatile field can not be of type `" +
4635                                                         TypeManager.CSharpName (vt) + "'");
4636                                                 return false;
4637                                         }
4638                                 }
4639
4640                                 if ((ModFlags & Modifiers.READONLY) != 0){
4641                                         Report.Error (
4642                                                       678, Location,
4643                                                       "A field can not be both volatile and readonly");
4644                                         return false;
4645                                 }
4646                         }
4647
4648                         FieldAttributes fa = Modifiers.FieldAttr (ModFlags);
4649
4650                         if (container is Struct && 
4651                             ((fa & FieldAttributes.Static) == 0) &&
4652                             MemberType == container.TypeBuilder &&
4653                             !TypeManager.IsBuiltinType (MemberType)){
4654                                 Report.Error (523, Location, "Struct member `" + container.Name + "." + Name + 
4655                                               "' causes a cycle in the structure layout");
4656                                 return false;
4657                         }
4658
4659                         try {
4660                                 FieldBuilder = container.TypeBuilder.DefineField (
4661                                         Name, MemberType, Modifiers.FieldAttr (ModFlags));
4662
4663                                 TypeManager.RegisterFieldBase (FieldBuilder, this);
4664                         }
4665                         catch (ArgumentException) {
4666                                 Report.Warning (-24, Location, "The Microsoft runtime is unable to use [void|void*] as a field type, try using the Mono runtime.");
4667                                 return false;
4668                         }
4669
4670                         return true;
4671                 }
4672
4673                 public override void Emit (TypeContainer tc)
4674                 {
4675                         if (OptAttributes != null) {
4676                                 EmitContext ec = new EmitContext (tc, Location, null, FieldBuilder.FieldType, ModFlags);
4677                                 OptAttributes.Emit (ec, this);
4678                         }
4679
4680                         base.Emit (tc);
4681                 }
4682         }
4683
4684         //
4685         // `set' and `get' accessors are represented with an Accessor.
4686         // 
4687         public class Accessor {
4688                 //
4689                 // Null if the accessor is empty, or a Block if not
4690                 //
4691                 public Block Block;
4692                 public Attributes Attributes;
4693                 
4694                 public Accessor (Block b, Attributes attrs)
4695                 {
4696                         Block = b;
4697                         Attributes = attrs;
4698                 }
4699         }
4700
4701         //
4702         // Properties and Indexers both generate PropertyBuilders, we use this to share 
4703         // their common bits.
4704         //
4705         abstract public class PropertyBase : MethodCore {
4706
4707                 public class GetMethod: PropertyMethod
4708                 {
4709                         static string[] attribute_targets = new string [] { "method", "return" };
4710
4711                         public GetMethod (MethodCore method, Accessor accessor):
4712                                 base (method, accessor)
4713                         {
4714                         }
4715
4716                         public override MethodBuilder Define(TypeContainer container)
4717                         {
4718                                 method_data = new MethodData (method, method.ParameterInfo, method.ModFlags, method.flags, this);
4719
4720                                 if (!method_data.Define (container))
4721                                         return null;
4722
4723                                 return method_data.MethodBuilder;
4724                         }
4725
4726                         public override string GetSignatureForError (TypeContainer tc)
4727                         {
4728                                 return String.Concat (base.GetSignatureForError (tc), ".get");
4729                         }
4730
4731                         public override string MethodName 
4732                         {
4733                                 get {
4734                                         return "get_" + method.ShortName;
4735                                 }
4736                         }
4737
4738                         public override Type ReturnType {
4739                                 get {
4740                                         return method.MemberType;
4741                                 }
4742                         }
4743
4744                         protected override string[] ValidAttributeTargets {
4745                                 get {
4746                                         return attribute_targets;
4747                                 }
4748                         }
4749                 }
4750
4751                 public class SetMethod: PropertyMethod {
4752
4753                         static string[] attribute_targets = new string [] { "method", "param", "return" };
4754                         ImplicitParameter param_attr;
4755
4756                         public SetMethod (MethodCore method, Accessor accessor):
4757                                 base (method, accessor)
4758                         {
4759                         }
4760
4761                         public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
4762                         {
4763                                 if (a.Target == "param") {
4764                                         if (param_attr == null)
4765                                                 param_attr = new ImplicitParameter (method_data.MethodBuilder);
4766
4767                                         param_attr.ApplyAttributeBuilder (a, cb);
4768                                         return;
4769                                 }
4770
4771                                 base.ApplyAttributeBuilder (a, cb);
4772                         }
4773
4774                         protected virtual InternalParameters GetParameterInfo (TypeContainer container)
4775                         {
4776                                 Parameter [] parms = new Parameter [1];
4777                                 parms [0] = new Parameter (method.Type, "value", Parameter.Modifier.NONE, null);
4778                                 return new InternalParameters (
4779                                         container, new Parameters (parms, null, method.Location));
4780                         }
4781
4782                         public override MethodBuilder Define(TypeContainer container)
4783                         {
4784                                 method_data = new MethodData (method, GetParameterInfo (container), method.ModFlags, method.flags, this);
4785
4786                                 if (!method_data.Define (container))
4787                                         return null;
4788
4789                                 return method_data.MethodBuilder;
4790                         }
4791
4792                         public override string GetSignatureForError (TypeContainer tc)
4793                         {
4794                                 return String.Concat (base.GetSignatureForError (tc), ".set");
4795                         }
4796
4797                         public override string MethodName {
4798                                 get {
4799                                         return "set_" + method.ShortName;
4800                                 }
4801                         }
4802
4803                         public override Type[] ParameterTypes {
4804                                 get {
4805                                         return new Type[] { method.MemberType };
4806                                 }
4807                         }
4808
4809                         public override Type ReturnType {
4810                                 get {
4811                                         return TypeManager.void_type;
4812                                 }
4813                         }
4814
4815                         protected override string[] ValidAttributeTargets {
4816                                 get {
4817                                         return attribute_targets;
4818                                 }
4819                         }
4820                 }
4821
4822
4823                 static string[] attribute_targets = new string [] { "property" };
4824
4825                 public abstract class PropertyMethod: Attributable, IMethodData 
4826                 {
4827                         protected readonly MethodCore method;
4828                         protected MethodData method_data;
4829                         Block block;
4830
4831                         ReturnParameter return_attributes;
4832
4833                         public PropertyMethod (MethodCore method, Accessor accessor):
4834                                 base (accessor.Attributes)
4835                         {
4836                                 this.method = method;
4837                                 this.block = accessor.Block;
4838                         }
4839
4840                         public override AttributeTargets AttributeTargets {
4841                                 get {
4842                                         return AttributeTargets.Method | AttributeTargets.ReturnValue;
4843                                 }
4844                         }
4845
4846                         public override bool IsClsCompliaceRequired(DeclSpace ds)
4847                         {
4848                                 return method.IsClsCompliaceRequired (ds);
4849                         }
4850
4851                         public InternalParameters ParameterInfo 
4852                         {
4853                                 get {
4854                                         return method_data.ParameterInfo;
4855                                 }
4856                         }
4857
4858                         #region IMethodData Members
4859
4860                         public Block Block {
4861                                 get {
4862                                         return block;
4863                                 }
4864                         }
4865
4866                         public CallingConventions CallingConventions {
4867                                 get {
4868                                         return CallingConventions.Standard;
4869                                 }
4870                         }
4871
4872                         public abstract MethodBuilder Define (TypeContainer container);
4873
4874                         public void Emit (TypeContainer container)
4875                         {
4876                                 method_data.Emit (container, this);
4877                                 block = null;
4878                         }
4879
4880                         public virtual string GetSignatureForError (TypeContainer tc)
4881                         {
4882                                 return String.Concat (tc.Name, '.', method.Name);
4883                         }
4884
4885                         public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
4886                         {
4887                                 if (a.Target == "return") {
4888                                         if (return_attributes == null)
4889                                                 return_attributes = new ReturnParameter (method_data.MethodBuilder, Location);
4890
4891                                         return_attributes.ApplyAttributeBuilder (a, cb);
4892                                         return;
4893                                 }
4894
4895                                 method_data.MethodBuilder.SetCustomAttribute (cb);
4896                         }
4897
4898                         public virtual Type[] ParameterTypes {
4899                                 get {
4900                                         return TypeManager.NoTypes;
4901                                 }
4902                         }
4903
4904                         public abstract Type ReturnType { get; }
4905
4906                         public Location Location {
4907                                 get {
4908                                         return method.Location;
4909                                 }
4910                         }
4911
4912                         public abstract string MethodName { get; }
4913
4914                         public EmitContext CreateEmitContext (TypeContainer tc, ILGenerator ig)
4915                         {
4916                                 return new EmitContext (tc, method.ds, method.Location, ig, ReturnType, method.ModFlags, false);
4917                         }
4918
4919                         public ObsoleteAttribute GetObsoleteAttribute ()
4920                         {
4921                                 return method.GetObsoleteAttribute (method.ds);
4922                         }
4923
4924                         public bool IsExcluded (EmitContext ec)
4925                         {
4926                                 return false;
4927                         }
4928
4929                         #endregion
4930                 }
4931
4932
4933                 public PropertyMethod Get, Set;
4934                 public PropertyBuilder PropertyBuilder;
4935                 public MethodBuilder GetBuilder, SetBuilder;
4936
4937                 protected EmitContext ec;
4938
4939                 public PropertyBase (DeclSpace ds, Expression type, int mod_flags,
4940                                      int allowed_mod, bool is_iface, string name,
4941                                      Parameters parameters, Attributes attrs,
4942                                      Location loc)
4943                         : base (ds, type, mod_flags, allowed_mod, is_iface, name,
4944                                 attrs, parameters, loc)
4945                 {
4946                 }
4947
4948                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
4949                 {
4950                         PropertyBuilder.SetCustomAttribute (cb);
4951                 }
4952
4953                 public override AttributeTargets AttributeTargets {
4954                         get {
4955                                 return AttributeTargets.Property;
4956                         }
4957                 }
4958
4959                 protected override bool DoDefine (TypeContainer container)
4960                 {
4961                         if (!base.DoDefine (container))
4962                                 return false;
4963
4964                         ec = new EmitContext (container, Location, null, MemberType, ModFlags);
4965
4966                         return true;
4967                 }
4968
4969                 public override string GetSignatureForError()
4970                 {
4971                         return TypeManager.CSharpSignature (PropertyBuilder, false);
4972                 }
4973
4974                 protected virtual string RealMethodName {
4975                         get {
4976                                 return Name;
4977                         }
4978                 }
4979
4980                 protected override bool IsIdentifierClsCompliant (DeclSpace ds)
4981                 {
4982                         if (!IsIdentifierAndParamClsCompliant (ds, RealMethodName, null, null))
4983                                 return false;
4984
4985                         if (Get != null && !IsIdentifierAndParamClsCompliant (ds, "get_" + RealMethodName, null, null))
4986                                 return false;
4987
4988                         if (Set != null && !IsIdentifierAndParamClsCompliant (ds, "set_" + RealMethodName, null, null))
4989                                 return false;
4990
4991                         return true;
4992                 }
4993
4994
4995                 //
4996                 // Checks our base implementation if any
4997                 //
4998                 protected override bool CheckBase (TypeContainer container)
4999                 {
5000                         base.CheckBase (container);
5001                         
5002                         // Check whether arguments were correct.
5003                         if (!DoDefineParameters ())
5004                                 return false;
5005
5006                         if (IsExplicitImpl)
5007                                 return true;
5008
5009                         //
5010                         // Check in our class for dups
5011                         //
5012                         ArrayList ar = container.Properties;
5013                         if (ar != null) {
5014                                 int arLen = ar.Count;
5015                                         
5016                                 for (int i = 0; i < arLen; i++) {
5017                                         Property m = (Property) ar [i];
5018                                         if (IsDuplicateImplementation (container, m))
5019                                                 return false;
5020                                 }
5021                         }
5022
5023                         if (IsInterface)
5024                                 return true;
5025
5026                         string report_name;
5027                         MethodSignature ms, base_ms;
5028                         if (this is Indexer) {
5029                                 string name, base_name;
5030
5031                                 report_name = "this";
5032                                 name = TypeManager.IndexerPropertyName (container.TypeBuilder);
5033                                 ms = new MethodSignature (name, null, ParameterTypes);
5034                                 base_name = TypeManager.IndexerPropertyName (container.TypeBuilder.BaseType);
5035                                 base_ms = new MethodSignature (base_name, null, ParameterTypes);
5036                         } else {
5037                                 report_name = Name;
5038                                 ms = base_ms = new MethodSignature (Name, null, ParameterTypes);
5039                         }
5040
5041                         //
5042                         // Verify if the parent has a type with the same name, and then
5043                         // check whether we have to create a new slot for it or not.
5044                         //
5045                         Type ptype = container.TypeBuilder.BaseType;
5046
5047                         // ptype is only null for System.Object while compiling corlib.
5048                         if (ptype == null) {
5049                                 if ((ModFlags & Modifiers.NEW) != 0)
5050                                         WarningNotHiding (container);
5051
5052                                 return true;
5053                         }
5054
5055                         MemberInfo parent_member = null;
5056                         
5057                         //
5058                         // Explicit implementations do not have `parent' methods, however,
5059                         // the member cache stores them there. Without this check, we get
5060                         // an incorrect warning in corlib.
5061                         //
5062                         if (! IsExplicitImpl) {
5063                                 parent_member = ((IMemberContainer)container).Parent.MemberCache.FindMemberToOverride (
5064                                         container.TypeBuilder, Name, ParameterTypes, true);
5065                         }
5066
5067                         if (parent_member is PropertyInfo) {
5068                                 PropertyInfo parent_property = (PropertyInfo)parent_member;
5069
5070                                 string name = parent_property.DeclaringType.Name + "." +
5071                                         parent_property.Name;
5072
5073                                 MethodInfo get, set, parent_method;
5074                                 get = parent_property.GetGetMethod (true);
5075                                 set = parent_property.GetSetMethod (true);
5076
5077                                 if (get != null)
5078                                         parent_method = get;
5079                                 else if (set != null)
5080                                         parent_method = set;
5081                                 else
5082                                         throw new Exception ("Internal error!");
5083
5084                                 if (!CheckMethodAgainstBase (container, flags, parent_method, name))
5085                                         return false;
5086
5087                                 if ((ModFlags & Modifiers.NEW) == 0) {
5088                                         Type parent_type = TypeManager.TypeToCoreType (
5089                                                 parent_property.PropertyType);
5090
5091                                         if (parent_type != MemberType) {
5092                                                 Report.Error (
5093                                                         508, Location, container.MakeName (Name) + ": cannot " +
5094                                                         "change return type when overriding " +
5095                                                         "inherited member " + name);
5096                                                 return false;
5097                                         }
5098                                 }
5099                         } else if (parent_member == null){
5100                                 if ((ModFlags & Modifiers.NEW) != 0)
5101                                         WarningNotHiding (container);
5102
5103                                 if ((ModFlags & Modifiers.OVERRIDE) != 0){
5104                                         if (this is Indexer)
5105                                                 Report.Error (115, Location,
5106                                                               container.MakeName (Name) +
5107                                                               " no suitable indexers found to override");
5108                                         else
5109                                                 Report.Error (115, Location,
5110                                                               container.MakeName (Name) +
5111                                                               " no suitable properties found to override");
5112                                         return false;
5113                                 }
5114                         }
5115                         return true;
5116                 }
5117
5118                 public override void Emit (TypeContainer tc)
5119                 {
5120                         //
5121                         // The PropertyBuilder can be null for explicit implementations, in that
5122                         // case, we do not actually emit the ".property", so there is nowhere to
5123                         // put the attribute
5124                         //
5125                         if (PropertyBuilder != null && OptAttributes != null)
5126                                 OptAttributes.Emit (ec, this);
5127
5128                         if (Get != null)
5129                                 Get.Emit (tc);
5130
5131                         if (Set != null)
5132                                 Set.Emit (tc);
5133
5134                         base.Emit (tc);
5135                 }
5136
5137                 protected override string[] ValidAttributeTargets {
5138                         get {
5139                                 return attribute_targets;
5140                         }
5141                 }
5142         }
5143                         
5144         public class Property : PropertyBase, IIteratorContainer {
5145                 const int AllowedModifiers =
5146                         Modifiers.NEW |
5147                         Modifiers.PUBLIC |
5148                         Modifiers.PROTECTED |
5149                         Modifiers.INTERNAL |
5150                         Modifiers.PRIVATE |
5151                         Modifiers.STATIC |
5152                         Modifiers.SEALED |
5153                         Modifiers.OVERRIDE |
5154                         Modifiers.ABSTRACT |
5155                         Modifiers.UNSAFE |
5156                         Modifiers.EXTERN |
5157                         Modifiers.METHOD_YIELDS |
5158                         Modifiers.VIRTUAL;
5159
5160                 const int AllowedInterfaceModifiers =
5161                         Modifiers.NEW;
5162
5163                 public Property (DeclSpace ds, Expression type, int mod_flags, bool is_iface,
5164                                  string name, Attributes attrs, Accessor get_block,
5165                                  Accessor set_block, Location loc)
5166                         : base (ds, type, mod_flags,
5167                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
5168                                 is_iface, name, Parameters.EmptyReadOnlyParameters, attrs,
5169                                 loc)
5170                 {
5171                         if (get_block != null)
5172                                 Get = new GetMethod (this, get_block);
5173
5174                         if (set_block != null)
5175                                 Set = new SetMethod (this, set_block);
5176                 }
5177
5178                 public override bool Define (TypeContainer container)
5179                 {
5180                         if (!DoDefine (container))
5181                                 return false;
5182
5183                         if (!CheckBase (container))
5184                                 return false;
5185
5186                         flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
5187
5188                         if (Get != null) {
5189
5190                                 GetBuilder = Get.Define (container);
5191                                 if (GetBuilder == null)
5192                                         return false;
5193
5194                                 //
5195                                 // Setup iterator if we are one
5196                                 //
5197                                 if ((ModFlags & Modifiers.METHOD_YIELDS) != 0){
5198                                         IteratorHandler ih = new  IteratorHandler (
5199                                                                                    "get", container, MemberType,
5200                                                                                    TypeManager.NoTypes, Get.ParameterInfo, ModFlags, Location);
5201                                         
5202                                         Block new_block = ih.Setup (block);
5203                                         if (new_block == null)
5204                                                 return false;
5205                                         block = new_block;
5206                                 }
5207                         }
5208
5209                         if (Set != null) {
5210                                 SetBuilder = Set.Define (container);
5211                                 if (SetBuilder == null)
5212                                         return false;
5213
5214                                 SetBuilder.DefineParameter (1, ParameterAttributes.None, "value"); 
5215                         }
5216
5217                         // FIXME - PropertyAttributes.HasDefault ?
5218                         
5219                         PropertyAttributes prop_attr = PropertyAttributes.None;
5220                         if (!IsInterface)
5221                                 prop_attr |= PropertyAttributes.RTSpecialName |
5222                                         PropertyAttributes.SpecialName;
5223
5224                         if (!IsExplicitImpl){
5225                                 PropertyBuilder = container.TypeBuilder.DefineProperty (
5226                                         Name, prop_attr, MemberType, null);
5227                                 
5228                                 if (Get != null)
5229                                         PropertyBuilder.SetGetMethod (GetBuilder);
5230                                 
5231                                 if (Set != null)
5232                                         PropertyBuilder.SetSetMethod (SetBuilder);
5233
5234                                 //
5235                                 // HACK for the reasons exposed above
5236                                 //
5237                                 if (!TypeManager.RegisterProperty (PropertyBuilder, GetBuilder, SetBuilder)) {
5238                                         Report.Error (
5239                                                 111, Location,
5240                                                 "Class `" + container.Name +
5241                                                 "' already contains a definition for the property `" +
5242                                                 Name + "'");
5243                                         return false;
5244                                 }
5245                         }
5246                         return true;
5247                 }
5248
5249                 public void SetYields ()
5250                 {
5251                         ModFlags |= Modifiers.METHOD_YIELDS;
5252                 }
5253         }
5254
5255         /// </summary>
5256         ///  Gigantic workaround  for lameness in SRE follows :
5257         ///  This class derives from EventInfo and attempts to basically
5258         ///  wrap around the EventBuilder so that FindMembers can quickly
5259         ///  return this in it search for members
5260         /// </summary>
5261         public class MyEventBuilder : EventInfo {
5262                 
5263                 //
5264                 // We use this to "point" to our Builder which is
5265                 // not really a MemberInfo
5266                 //
5267                 EventBuilder MyBuilder;
5268                 
5269                 //
5270                 // We "catch" and wrap these methods
5271                 //
5272                 MethodInfo raise, remove, add;
5273
5274                 EventAttributes attributes;
5275                 Type declaring_type, reflected_type, event_type;
5276                 string name;
5277
5278                 Event my_event;
5279
5280                 public MyEventBuilder (Event ev, TypeBuilder type_builder, string name, EventAttributes event_attr, Type event_type)
5281                 {
5282                         MyBuilder = type_builder.DefineEvent (name, event_attr, event_type);
5283
5284                         // And now store the values in our own fields.
5285                         
5286                         declaring_type = type_builder;
5287
5288                         reflected_type = type_builder;
5289                         
5290                         attributes = event_attr;
5291                         this.name = name;
5292                         my_event = ev;
5293                         this.event_type = event_type;
5294                 }
5295                 
5296                 //
5297                 // Methods that you have to override.  Note that you only need 
5298                 // to "implement" the variants that take the argument (those are
5299                 // the "abstract" methods, the others (GetAddMethod()) are 
5300                 // regular.
5301                 //
5302                 public override MethodInfo GetAddMethod (bool nonPublic)
5303                 {
5304                         return add;
5305                 }
5306                 
5307                 public override MethodInfo GetRemoveMethod (bool nonPublic)
5308                 {
5309                         return remove;
5310                 }
5311                 
5312                 public override MethodInfo GetRaiseMethod (bool nonPublic)
5313                 {
5314                         return raise;
5315                 }
5316                 
5317                 //
5318                 // These methods make "MyEventInfo" look like a Builder
5319                 //
5320                 public void SetRaiseMethod (MethodBuilder raiseMethod)
5321                 {
5322                         raise = raiseMethod;
5323                         MyBuilder.SetRaiseMethod (raiseMethod);
5324                 }
5325
5326                 public void SetRemoveOnMethod (MethodBuilder removeMethod)
5327                 {
5328                         remove = removeMethod;
5329                         MyBuilder.SetRemoveOnMethod (removeMethod);
5330                 }
5331
5332                 public void SetAddOnMethod (MethodBuilder addMethod)
5333                 {
5334                         add = addMethod;
5335                         MyBuilder.SetAddOnMethod (addMethod);
5336                 }
5337
5338                 public void SetCustomAttribute (CustomAttributeBuilder cb)
5339                 {
5340                         MyBuilder.SetCustomAttribute (cb);
5341                 }
5342                 
5343                 public override object [] GetCustomAttributes (bool inherit)
5344                 {
5345                         // FIXME : There's nothing which can be seemingly done here because
5346                         // we have no way of getting at the custom attribute objects of the
5347                         // EventBuilder !
5348                         return null;
5349                 }
5350
5351                 public override object [] GetCustomAttributes (Type t, bool inherit)
5352                 {
5353                         // FIXME : Same here !
5354                         return null;
5355                 }
5356
5357                 public override bool IsDefined (Type t, bool b)
5358                 {
5359                         return true;
5360                 }
5361
5362                 public override EventAttributes Attributes {
5363                         get {
5364                                 return attributes;
5365                         }
5366                 }
5367
5368                 public override string Name {
5369                         get {
5370                                 return name;
5371                         }
5372                 }
5373
5374                 public override Type DeclaringType {
5375                         get {
5376                                 return declaring_type;
5377                         }
5378                 }
5379
5380                 public override Type ReflectedType {
5381                         get {
5382                                 return reflected_type;
5383                         }
5384                 }
5385
5386                 public Type EventType {
5387                         get {
5388                                 return event_type;
5389                         }
5390                 }
5391                 
5392                 public void SetUsed ()
5393                 {
5394                         if (my_event != null)
5395                                 my_event.status = (FieldBase.Status.ASSIGNED | FieldBase.Status.USED);
5396                 }
5397         }
5398         
5399         /// <summary>
5400         /// For case when event is declared like property (with add and remove accessors).
5401         /// </summary>
5402         public class EventProperty: Event {
5403
5404                 static string[] attribute_targets = new string [] { "event", "property" };
5405
5406                 public EventProperty (DeclSpace ds, Expression type, int mod_flags, bool is_iface, string name,
5407                         Object init, Attributes attrs, Accessor add, Accessor remove, Location loc)
5408                         : base (ds, type, mod_flags, is_iface, name, init, attrs, loc)
5409                 {
5410                         Add = new AddDelegateMethod (this, add);
5411                         Remove = new RemoveDelegateMethod (this, remove);
5412                 }
5413
5414                 protected override string[] ValidAttributeTargets {
5415                         get {
5416                                 return attribute_targets;
5417                         }
5418                 }
5419         }
5420
5421         /// <summary>
5422         /// Event is declared like field.
5423         /// </summary>
5424         public class EventField: Event {
5425
5426                 static string[] attribute_targets = new string [] { "event", "field", "method" };
5427
5428                 public EventField (DeclSpace ds, Expression type, int mod_flags, bool is_iface, string name,
5429                         Object init, Attributes attrs, Location loc)
5430                         : base (ds, type, mod_flags, is_iface, name, init, attrs, loc)
5431                 {
5432                         Add = new AddDelegateMethod (this);
5433                         Remove = new RemoveDelegateMethod (this);
5434                 }
5435
5436                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
5437                 {
5438                         if (a.Target == "field") {
5439                                 FieldBuilder.SetCustomAttribute (cb);
5440                                 return;
5441                         }
5442
5443                         if (a.Target == "method") {
5444                                 AddBuilder.SetCustomAttribute (cb);
5445                                 RemoveBuilder.SetCustomAttribute (cb);
5446                                 return;
5447                         }
5448
5449                         base.ApplyAttributeBuilder (a, cb);
5450                 }
5451
5452                 protected override string[] ValidAttributeTargets {
5453                         get {
5454                                 return attribute_targets;
5455                         }
5456                 }
5457         }
5458
5459         public abstract class Event : FieldBase {
5460
5461                 protected sealed class AddDelegateMethod: DelegateMethod
5462                 {
5463                         public AddDelegateMethod (Event method):
5464                                 base (method)
5465                         {
5466                         }
5467
5468                         public AddDelegateMethod (Event method, Accessor accessor):
5469                                 base (method, accessor)
5470                         {
5471                         }
5472
5473                         public override string MethodName {
5474                                 get {
5475                                         return "add_" + method.ShortName;
5476                                 }
5477                         }
5478
5479                         protected override MethodInfo DelegateMethodInfo {
5480                                 get {
5481                                         return TypeManager.delegate_combine_delegate_delegate;
5482                                 }
5483                         }
5484
5485                 }
5486
5487                 protected sealed class RemoveDelegateMethod: DelegateMethod
5488                 {
5489                         public RemoveDelegateMethod (Event method):
5490                                 base (method)
5491                         {
5492                         }
5493
5494                         public RemoveDelegateMethod (Event method, Accessor accessor):
5495                                 base (method, accessor)
5496                         {
5497                         }
5498
5499                         public override string MethodName {
5500                                 get {
5501                                         return "remove_" + method.ShortName;
5502                                 }
5503                         }
5504
5505                         protected override MethodInfo DelegateMethodInfo {
5506                                 get {
5507                                         return TypeManager.delegate_remove_delegate_delegate;
5508                                 }
5509                         }
5510
5511                 }
5512
5513                 public abstract class DelegateMethod: Attributable, IMethodData
5514                 {
5515                         protected readonly Event method;
5516                         protected MethodData method_data;
5517                         Block block;
5518                         ReturnParameter return_attributes;
5519                         ImplicitParameter param_attr;
5520
5521                         static string[] attribute_targets = new string [] { "method", "param", "return" };
5522
5523                         public DelegateMethod (Event method):
5524                                 base (null)
5525                         {
5526                                 this.method = method;
5527                         }
5528
5529                         public DelegateMethod (Event method, Accessor accessor):
5530                                 base (accessor.Attributes)
5531                         {
5532                                 this.method = method;
5533                                 this.block = accessor.Block;
5534                         }
5535
5536                         public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
5537                         {
5538                                 if (a.Target == "return") {
5539                                         if (return_attributes == null)
5540                                                 return_attributes = new ReturnParameter (method_data.MethodBuilder, Location);
5541
5542                                         return_attributes.ApplyAttributeBuilder (a, cb);
5543                                         return;
5544                                 }
5545
5546                                 if (a.Target == "param") {
5547                                         if (param_attr == null)
5548                                                 param_attr = new ImplicitParameter (method_data.MethodBuilder);
5549
5550                                         param_attr.ApplyAttributeBuilder (a, cb);
5551                                         return;
5552                                 }
5553
5554                                 method_data.MethodBuilder.SetCustomAttribute (cb);
5555                         }
5556
5557                         public override AttributeTargets AttributeTargets {
5558                                 get {
5559                                         return AttributeTargets.Method;
5560                                 }
5561                         }
5562
5563                         public override bool IsClsCompliaceRequired(DeclSpace ds)
5564                         {
5565                                 return method.IsClsCompliaceRequired (ds);
5566                         }
5567
5568                         public MethodBuilder Define (TypeContainer container, InternalParameters ip)
5569                         {
5570                                 method_data = new MethodData (method, ip, method.ModFlags,
5571                                         method.flags | MethodAttributes.HideBySig | MethodAttributes.SpecialName, this);
5572
5573                                 if (!method_data.Define (container))
5574                                         return null;
5575
5576                                 MethodBuilder mb = method_data.MethodBuilder;
5577                                 mb.DefineParameter (1, ParameterAttributes.None, "value");
5578                                 return mb;
5579                         }
5580
5581                         #region IMethodData Members
5582
5583                         public Block Block {
5584                                 get {
5585                                         return block;
5586                                 }
5587                         }
5588
5589                         public CallingConventions CallingConventions {
5590                                 get {
5591                                         return CallingConventions.Standard;
5592                                 }
5593                         }
5594
5595                         public void Emit (TypeContainer tc)
5596                         {
5597                                 if (block != null) {
5598                                         method_data.Emit (tc, this);
5599                                         block = null;
5600                                         return;
5601                                 }
5602
5603                                 ILGenerator ig = method_data.MethodBuilder.GetILGenerator ();
5604                                 EmitContext ec = CreateEmitContext (tc, ig);
5605                                 FieldInfo field_info = (FieldInfo)method.FieldBuilder;
5606
5607                                 if ((method.ModFlags & Modifiers.STATIC) != 0) {
5608                                         ig.Emit (OpCodes.Ldsfld, field_info);
5609                                         ig.Emit (OpCodes.Ldarg_0);
5610                                         ig.Emit (OpCodes.Call, DelegateMethodInfo);
5611                                         ig.Emit (OpCodes.Castclass, method.MemberType);
5612                                         ig.Emit (OpCodes.Stsfld, field_info);
5613                                 } else {
5614                                         ig.Emit (OpCodes.Ldarg_0);
5615                                         ig.Emit (OpCodes.Ldarg_0);
5616                                         ig.Emit (OpCodes.Ldfld, field_info);
5617                                         ig.Emit (OpCodes.Ldarg_1);
5618                                         ig.Emit (OpCodes.Call, DelegateMethodInfo);
5619                                         ig.Emit (OpCodes.Castclass, method.MemberType);
5620                                         ig.Emit (OpCodes.Stfld, field_info);
5621                                 }
5622                                 ig.Emit (OpCodes.Ret);
5623                         }
5624
5625                         public string GetSignatureForError (TypeContainer tc)
5626                         {
5627                                 return String.Concat (tc.Name, '.', method.Name);
5628                         }
5629
5630                         protected abstract MethodInfo DelegateMethodInfo { get; }
5631
5632                         public Type[] ParameterTypes {
5633                                 get {
5634                                         return new Type[] { method.MemberType };
5635                                 }
5636                         }
5637
5638                         public Type ReturnType {
5639                                 get {
5640                                         return TypeManager.void_type;
5641                                 }
5642                         }
5643
5644                         public Location Location {
5645                                 get {
5646                                         return method.Location;
5647                                 }
5648                         }
5649
5650                         public EmitContext CreateEmitContext (TypeContainer tc, ILGenerator ig)
5651                         {
5652                                 return new EmitContext (tc, method.ds, Location, ig, ReturnType, method.ModFlags, false);
5653                         }
5654
5655                         public ObsoleteAttribute GetObsoleteAttribute ()
5656                         {
5657                                 return method.GetObsoleteAttribute (method.ds);
5658                         }
5659
5660                         public bool IsExcluded (EmitContext ec)
5661                         {
5662                                 return false;
5663                         }
5664
5665                         public abstract string MethodName { get; }
5666
5667                         #endregion
5668
5669                         protected override string[] ValidAttributeTargets {
5670                                 get {
5671                                         return attribute_targets;
5672                                 }
5673                         }
5674                 }
5675
5676
5677                 const int AllowedModifiers =
5678                         Modifiers.NEW |
5679                         Modifiers.PUBLIC |
5680                         Modifiers.PROTECTED |
5681                         Modifiers.INTERNAL |
5682                         Modifiers.PRIVATE |
5683                         Modifiers.STATIC |
5684                         Modifiers.VIRTUAL |
5685                         Modifiers.SEALED |
5686                         Modifiers.OVERRIDE |
5687                         Modifiers.UNSAFE |
5688                         Modifiers.ABSTRACT;
5689
5690                 const int AllowedInterfaceModifiers =
5691                         Modifiers.NEW;
5692
5693                 protected DelegateMethod Add, Remove;
5694                 public MyEventBuilder     EventBuilder;
5695                 public MethodBuilder AddBuilder, RemoveBuilder;
5696                 public DeclSpace ds;
5697
5698                 public Event (DeclSpace ds, Expression type, int mod_flags, bool is_iface, string name,
5699                                 Object init, Attributes attrs, Location loc)
5700                         : base (type, mod_flags, is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
5701                                 name, init, attrs, loc)
5702                 {
5703                         IsInterface = is_iface;
5704                         this.ds = ds;
5705                 }
5706
5707                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
5708                 {
5709                         EventBuilder.SetCustomAttribute (cb);
5710                 }
5711
5712                 public override AttributeTargets AttributeTargets {
5713                         get {
5714                                 return AttributeTargets.Event;
5715                         }
5716                 }
5717
5718                 public override bool Define (TypeContainer container)
5719                 {
5720                         EventAttributes e_attr;
5721                         if (IsInterface)
5722                                 e_attr = EventAttributes.None;
5723                         else
5724                                 e_attr = EventAttributes.RTSpecialName |
5725                                         EventAttributes.SpecialName;
5726
5727                         if (!DoDefine (container))
5728                                 return false;
5729
5730                         if (init != null && ((ModFlags & Modifiers.ABSTRACT) != 0)){
5731                                 Report.Error (74, Location, "'" + container.Name + "." + Name +
5732                                               "': abstract event can not have an initializer");
5733                                 return false;
5734                         }
5735                         
5736                         if (!MemberType.IsSubclassOf (TypeManager.delegate_type)) {
5737                                 Report.Error (66, Location, "'" + container.Name + "." + Name +
5738                                               "' : event must be of a delegate type");
5739                                 return false;
5740                         }
5741
5742                         Parameter [] parms = new Parameter [1];
5743                         parms [0] = new Parameter (Type, "value", Parameter.Modifier.NONE, null);
5744                         InternalParameters ip = new InternalParameters (
5745                                 container, new Parameters (parms, null, Location)); 
5746
5747                         if (!CheckBase (container))
5748                                 return false;
5749
5750                         //
5751                         // Now define the accessors
5752                         //
5753
5754                         AddBuilder = Add.Define (container, ip);
5755                         if (AddBuilder == null)
5756                                 return false;
5757
5758                         RemoveBuilder = Remove.Define (container, ip);
5759                         if (RemoveBuilder == null)
5760                                 return false;
5761
5762                         if (!IsExplicitImpl){
5763                                 EventBuilder = new MyEventBuilder (this,
5764                                         container.TypeBuilder, Name, e_attr, MemberType);
5765                                         
5766                                 if (Add.Block == null && Remove.Block == null &&
5767                                     !IsInterface) {
5768                                         FieldBuilder = container.TypeBuilder.DefineField (
5769                                                 Name, MemberType,
5770                                                 FieldAttributes.Private | ((ModFlags & Modifiers.STATIC) != 0 ? FieldAttributes.Static : 0));
5771                                         TypeManager.RegisterPrivateFieldOfEvent (
5772                                                 (EventInfo) EventBuilder, FieldBuilder);
5773                                         TypeManager.RegisterFieldBase (FieldBuilder, this);
5774                                 }
5775                         
5776                                 EventBuilder.SetAddOnMethod (AddBuilder);
5777                                 EventBuilder.SetRemoveOnMethod (RemoveBuilder);
5778
5779                                 if (!TypeManager.RegisterEvent (EventBuilder, AddBuilder, RemoveBuilder)) {
5780                                         Report.Error (111, Location,
5781                                                       "Class `" + container.Name +
5782                                                       "' already contains a definition for the event `" +
5783                                                       Name + "'");
5784                                         return false;
5785                                 }
5786                         }
5787                         
5788                         return true;
5789                 }
5790
5791                 public override void Emit (TypeContainer tc)
5792                 {
5793                         if (OptAttributes != null) {
5794                                 EmitContext ec = new EmitContext (tc, Location, null, MemberType, ModFlags);
5795                                 OptAttributes.Emit (ec, this);
5796                         }
5797
5798                         if (!IsInterface) {
5799                                 Add.Emit (tc);
5800                                 Remove.Emit (tc);
5801                         }
5802
5803                         base.Emit (tc);
5804                 }
5805         }
5806
5807         //
5808         // FIXME: This does not handle:
5809         //
5810         //   int INTERFACENAME [ args ]
5811         //   Does not 
5812         //
5813         // Only:
5814         // 
5815         // int this [ args ]
5816  
5817         public class Indexer : PropertyBase {
5818
5819                 class GetIndexerMethod: GetMethod
5820                 {
5821                         public GetIndexerMethod (MethodCore method, Accessor accessor):
5822                                 base (method, accessor)
5823                         {
5824                         }
5825
5826                         public override Type[] ParameterTypes {
5827                                 get {
5828                                         return method.ParameterTypes;
5829                                 }
5830                         }
5831                 }
5832
5833                 class SetIndexerMethod: SetMethod
5834                 {
5835                         readonly Parameters parameters;
5836
5837                         public SetIndexerMethod (MethodCore method, Parameters parameters, Accessor accessor):
5838                                 base (method, accessor)
5839                         {
5840                                 this.parameters = parameters;
5841                         }
5842
5843                         public override Type[] ParameterTypes {
5844                                 get {
5845                                         int top = method.ParameterTypes.Length;
5846                                         Type [] set_pars = new Type [top + 1];
5847                                         method.ParameterTypes.CopyTo (set_pars, 0);
5848                                         set_pars [top] = method.MemberType;
5849                                         return set_pars;
5850                                 }
5851                         }
5852
5853                         protected override InternalParameters GetParameterInfo (TypeContainer container)
5854                         {
5855                                 Parameter [] fixed_parms = parameters.FixedParameters;
5856
5857                                 if (fixed_parms == null){
5858                                         throw new Exception ("We currently do not support only array arguments in an indexer at: " + method.Location);
5859                                         // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
5860                                         // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
5861                                         //
5862                                         // Here is the problem: the `value' parameter has
5863                                         // to come *after* the array parameter in the declaration
5864                                         // like this:
5865                                         // X (object [] x, Type value)
5866                                         // .param [0]
5867                                         //
5868                                         // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
5869                                         // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
5870                                         
5871                                 }
5872                                 
5873                                 Parameter [] tmp = new Parameter [fixed_parms.Length + 1];
5874
5875                                 fixed_parms.CopyTo (tmp, 0);
5876                                 tmp [fixed_parms.Length] = new Parameter (
5877                                         method.Type, "value", Parameter.Modifier.NONE, null);
5878
5879                                 Parameters set_formal_params = new Parameters (tmp, null, method.Location);
5880                                 
5881                                 return new InternalParameters (container, set_formal_params);
5882                         }
5883
5884                 }
5885
5886
5887                 const int AllowedModifiers =
5888                         Modifiers.NEW |
5889                         Modifiers.PUBLIC |
5890                         Modifiers.PROTECTED |
5891                         Modifiers.INTERNAL |
5892                         Modifiers.PRIVATE |
5893                         Modifiers.VIRTUAL |
5894                         Modifiers.SEALED |
5895                         Modifiers.OVERRIDE |
5896                         Modifiers.UNSAFE |
5897                         Modifiers.EXTERN |
5898                         Modifiers.ABSTRACT;
5899
5900                 const int AllowedInterfaceModifiers =
5901                         Modifiers.NEW;
5902
5903                 public string IndexerName;
5904                 public string InterfaceIndexerName;
5905
5906                 //
5907                 // Are we implementing an interface ?
5908                 //
5909                 public Indexer (DeclSpace ds, Expression type, string int_type, int mod_flags,
5910                                 bool is_iface, Parameters parameters, Attributes attrs,
5911                                 Accessor get_block, Accessor set_block, Location loc)
5912                         : base (ds, type, mod_flags,
5913                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
5914                                 is_iface, "", parameters, attrs, loc)
5915                 {
5916                         ExplicitInterfaceName = int_type;
5917
5918                         if (get_block != null)
5919                                 Get = new GetIndexerMethod (this, get_block);
5920
5921                         if (set_block != null)
5922                                 Set = new SetIndexerMethod (this, parameters, set_block);
5923                 }
5924                        
5925                 public override bool Define (TypeContainer container)
5926                 {
5927                         PropertyAttributes prop_attr =
5928                                 PropertyAttributes.RTSpecialName |
5929                                 PropertyAttributes.SpecialName;
5930                         
5931                         if (!DoDefine (container))
5932                                 return false;
5933
5934                         if (OptAttributes != null)
5935                                 IndexerName = OptAttributes.ScanForIndexerName (ec);
5936
5937                         if (IndexerName == null)
5938                                 IndexerName = "Item";
5939                         else {
5940                                 if (! Tokenizer.IsValidIdentifier (IndexerName)) {
5941                                         Report.Error (633, Location, "The IndexerName specified is an invalid identifier");
5942                                         return false;
5943                                 }
5944                                 
5945                                 if (IsExplicitImpl) {
5946                                         Report.Error (592, Location,
5947                                                       "Attribute 'IndexerName' is not valid on explicit implementations.");
5948                                         return false;
5949                                 }
5950                         }
5951
5952                         ShortName = IndexerName;
5953                         if (IsExplicitImpl) {
5954                                 InterfaceIndexerName = TypeManager.IndexerPropertyName (InterfaceType);
5955                                 Name = InterfaceType.FullName + "." + IndexerName;
5956                         } else {
5957                                 InterfaceIndexerName = IndexerName;
5958                                 Name = ShortName;
5959                         }
5960
5961                         if (!CheckNameCollision (container))
5962                                 return false;
5963
5964                         if (!CheckBase (container))
5965                                 return false;
5966
5967                         flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
5968                         if (Get != null){
5969                                 GetBuilder = Get.Define (container);
5970                                 if (GetBuilder == null)
5971                                         return false;
5972                         }
5973                         
5974                         if (Set != null){
5975                                 SetBuilder = Set.Define (container);
5976                                 if (SetBuilder == null)
5977                                         return false;
5978                         }
5979
5980                         //
5981                         // Now name the parameters
5982                         //
5983                         Parameter [] p = Parameters.FixedParameters;
5984                         if (p != null) {
5985                                 int i;
5986                                 
5987                                 for (i = 0; i < p.Length; ++i) {
5988                                         if (Get != null)
5989                                                 GetBuilder.DefineParameter (
5990                                                         i + 1, p [i].Attributes, p [i].Name);
5991
5992                                         if (Set != null)
5993                                                 SetBuilder.DefineParameter (
5994                                                         i + 1, p [i].Attributes, p [i].Name);
5995                                 }
5996
5997                                 if (Set != null)
5998                                         SetBuilder.DefineParameter (
5999                                                 i + 1, ParameterAttributes.None, "value");
6000                                         
6001                                 if (i != ParameterTypes.Length) {
6002                                         Parameter array_param = Parameters.ArrayParameter;
6003
6004                                         SetBuilder.DefineParameter (
6005                                                 i + 1, array_param.Attributes, array_param.Name);
6006                                 }
6007                         }
6008
6009                         //
6010                         // Define the PropertyBuilder if one of the following conditions are met:
6011                         // a) we're not implementing an interface indexer.
6012                         // b) the indexer has a different IndexerName and this is no
6013                         //    explicit interface implementation.
6014                         //
6015                         if (!IsExplicitImpl) {
6016                                 PropertyBuilder = container.TypeBuilder.DefineProperty (
6017                                         IndexerName, prop_attr, MemberType, ParameterTypes);
6018
6019                                 if (Get != null)
6020                                         PropertyBuilder.SetGetMethod (GetBuilder);
6021
6022                                 if (Set != null)
6023                                         PropertyBuilder.SetSetMethod (SetBuilder);
6024                                 
6025                                 TypeManager.RegisterIndexer (PropertyBuilder, GetBuilder, SetBuilder,
6026                                                              ParameterTypes);
6027                         }
6028
6029                         return true;
6030                 }
6031
6032                 bool CheckNameCollision (TypeContainer container) {
6033                         switch (VerifyName (container)){
6034                                 case DeclSpace.AdditionResult.NameExists:
6035                                         Report.Error (102, Location, "The container '{0}' already contains a definition for '{1}'", container.GetSignatureForError (), Name);
6036                                         return false;
6037
6038                                 case DeclSpace.AdditionResult.Success:
6039                                         return true;
6040                         }
6041                         throw new NotImplementedException ();
6042                 }
6043
6044                 DeclSpace.AdditionResult VerifyName (TypeContainer container) {
6045                         if (!AddIndexer (container, container.Name + "." + Name))
6046                                 return DeclSpace.AdditionResult.NameExists;
6047
6048                         if (Get != null) {
6049                                 if (!AddIndexer (container, container.Name + ".get_" + Name))
6050                                         return DeclSpace.AdditionResult.NameExists;
6051                         }
6052
6053                         if (Set != null) {
6054                                 if (!AddIndexer (container, container.Name + ".set_" + Name))
6055                                         return DeclSpace.AdditionResult.NameExists;
6056                         }
6057                         return DeclSpace.AdditionResult.Success;
6058                 }
6059
6060                 bool AddIndexer (TypeContainer container, string fullname)
6061                 {
6062                         object value = container.GetDefinition (fullname);
6063
6064                         if (value != null) {
6065                                 return value.GetType () != GetType () ? false : true;
6066                         }
6067
6068                         container.DefineName (fullname, this);
6069                         return true;
6070                 }
6071
6072                 public override string GetSignatureForError ()
6073                 {
6074                         return TypeManager.CSharpSignature (PropertyBuilder, true);
6075                 }
6076
6077                 protected override string RealMethodName {
6078                         get {
6079                                 return IndexerName;
6080                         }
6081                 }
6082         }
6083
6084         public class Operator : MemberBase, IIteratorContainer {
6085
6086                 const int AllowedModifiers =
6087                         Modifiers.PUBLIC |
6088                         Modifiers.UNSAFE |
6089                         Modifiers.EXTERN |
6090                         Modifiers.STATIC;
6091
6092                 const int RequiredModifiers =
6093                         Modifiers.PUBLIC |
6094                         Modifiers.STATIC;
6095
6096                 public enum OpType : byte {
6097
6098                         // Unary operators
6099                         LogicalNot,
6100                         OnesComplement,
6101                         Increment,
6102                         Decrement,
6103                         True,
6104                         False,
6105
6106                         // Unary and Binary operators
6107                         Addition,
6108                         Subtraction,
6109
6110                         UnaryPlus,
6111                         UnaryNegation,
6112                         
6113                         // Binary operators
6114                         Multiply,
6115                         Division,
6116                         Modulus,
6117                         BitwiseAnd,
6118                         BitwiseOr,
6119                         ExclusiveOr,
6120                         LeftShift,
6121                         RightShift,
6122                         Equality,
6123                         Inequality,
6124                         GreaterThan,
6125                         LessThan,
6126                         GreaterThanOrEqual,
6127                         LessThanOrEqual,
6128
6129                         // Implicit and Explicit
6130                         Implicit,
6131                         Explicit
6132                 };
6133
6134                 public readonly OpType OperatorType;
6135                 public readonly Expression ReturnType;
6136                 public readonly Expression FirstArgType, SecondArgType;
6137                 public readonly string FirstArgName, SecondArgName;
6138                 public Block           Block;
6139                 public MethodBuilder   OperatorMethodBuilder;
6140                 
6141                 public string MethodName;
6142                 public Method OperatorMethod;
6143
6144                 static string[] attribute_targets = new string [] { "method", "return" };
6145
6146                 public Operator (OpType type, Expression ret_type, int mod_flags,
6147                                  Expression arg1type, string arg1name,
6148                                  Expression arg2type, string arg2name,
6149                                  Block block, Attributes attrs, Location loc)
6150                         : base (ret_type, mod_flags, AllowedModifiers, Modifiers.PUBLIC, "", attrs, loc)
6151                 {
6152                         OperatorType = type;
6153                         Name = "op_" + OperatorType;
6154                         ReturnType = ret_type;
6155                         FirstArgType = arg1type;
6156                         FirstArgName = arg1name;
6157                         SecondArgType = arg2type;
6158                         SecondArgName = arg2name;
6159                         Block = block;
6160                 }
6161
6162                 string Prototype (TypeContainer container)
6163                 {
6164                         return container.Name + ".operator " + OperatorType + " (" + FirstArgType + "," +
6165                                 SecondArgType + ")";
6166                 }
6167
6168                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb) 
6169                 {
6170                         OperatorMethod.ApplyAttributeBuilder (a, cb);
6171                 }
6172
6173                 public override AttributeTargets AttributeTargets {
6174                         get {
6175                                 return AttributeTargets.Method; 
6176                         }
6177                 }
6178                 
6179                 public override bool Define (TypeContainer container)
6180                 {
6181                         int length = 1;
6182                         MethodName = "op_" + OperatorType;
6183                         
6184                         if (SecondArgType != null)
6185                                 length = 2;
6186                         
6187                         Parameter [] param_list = new Parameter [length];
6188
6189                         if ((ModFlags & RequiredModifiers) != RequiredModifiers){
6190                                 Report.Error (
6191                                         558, Location, 
6192                                         "User defined operators `" +
6193                                         Prototype (container) +
6194                                         "' must be declared static and public");
6195                                 return false;
6196                         }
6197
6198                         param_list[0] = new Parameter (FirstArgType, FirstArgName,
6199                                                        Parameter.Modifier.NONE, null);
6200                         if (SecondArgType != null)
6201                                 param_list[1] = new Parameter (SecondArgType, SecondArgName,
6202                                                                Parameter.Modifier.NONE, null);
6203                         
6204                         OperatorMethod = new Method (
6205                                 container, ReturnType, ModFlags, false, MethodName,
6206                                 new Parameters (param_list, null, Location),
6207                                 OptAttributes, Location);
6208
6209                         OperatorMethod.Block = Block;
6210                         OperatorMethod.IsOperator = true;                       
6211                         OperatorMethod.Define (container);
6212
6213                         if (OperatorMethod.MethodBuilder == null)
6214                                 return false;
6215                         
6216                         OperatorMethodBuilder = OperatorMethod.MethodBuilder;
6217
6218                         Type [] param_types = OperatorMethod.ParameterTypes;
6219                         Type declaring_type = OperatorMethodBuilder.DeclaringType;
6220                         Type return_type = OperatorMethod.GetReturnType ();
6221                         Type first_arg_type = param_types [0];
6222
6223                         // Rules for conversion operators
6224                         
6225                         if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
6226                                 if (first_arg_type == return_type && first_arg_type == declaring_type){
6227                                         Report.Error (
6228                                                 555, Location,
6229                                                 "User-defined conversion cannot take an object of the " +
6230                                                 "enclosing type and convert to an object of the enclosing" +
6231                                                 " type");
6232                                         return false;
6233                                 }
6234                                 
6235                                 if (first_arg_type != declaring_type && return_type != declaring_type){
6236                                         Report.Error (
6237                                                 556, Location, 
6238                                                 "User-defined conversion must convert to or from the " +
6239                                                 "enclosing type");
6240                                         return false;
6241                                 }
6242                                 
6243                                 if (first_arg_type == TypeManager.object_type ||
6244                                     return_type == TypeManager.object_type){
6245                                         Report.Error (
6246                                                 -8, Location,
6247                                                 "User-defined conversion cannot convert to or from " +
6248                                                 "object type");
6249                                         return false;
6250                                 }
6251
6252                                 if (first_arg_type.IsInterface || return_type.IsInterface){
6253                                         Report.Error (
6254                                                 552, Location,
6255                                                 "User-defined conversion cannot convert to or from an " +
6256                                                 "interface type");
6257                                         return false;
6258                                 }
6259                                 
6260                                 if (first_arg_type.IsSubclassOf (return_type) ||
6261                                     return_type.IsSubclassOf (first_arg_type)){
6262                                         Report.Error (
6263                                                 -10, Location,
6264                                                 "User-defined conversion cannot convert between types " +
6265                                                 "that derive from each other");
6266                                         return false;
6267                                 }
6268                         } else if (SecondArgType == null) {
6269                                 // Checks for Unary operators
6270                                 
6271                                 if (first_arg_type != declaring_type){
6272                                         Report.Error (
6273                                                 562, Location,
6274                                                 "The parameter of a unary operator must be the " +
6275                                                 "containing type");
6276                                         return false;
6277                                 }
6278                                 
6279                                 if (OperatorType == OpType.Increment || OperatorType == OpType.Decrement) {
6280                                         if (return_type != declaring_type){
6281                                                 Report.Error (
6282                                                         559, Location,
6283                                                         "The parameter and return type for ++ and -- " +
6284                                                         "must be the containing type");
6285                                                 return false;
6286                                         }
6287                                         
6288                                 }
6289                                 
6290                                 if (OperatorType == OpType.True || OperatorType == OpType.False) {
6291                                         if (return_type != TypeManager.bool_type){
6292                                                 Report.Error (
6293                                                         215, Location,
6294                                                         "The return type of operator True or False " +
6295                                                         "must be bool");
6296                                                 return false;
6297                                         }
6298                                 }
6299                                 
6300                         } else {
6301                                 // Checks for Binary operators
6302                                 
6303                                 if (first_arg_type != declaring_type &&
6304                                     param_types [1] != declaring_type){
6305                                         Report.Error (
6306                                                 563, Location,
6307                                                 "One of the parameters of a binary operator must " +
6308                                                 "be the containing type");
6309                                         return false;
6310                                 }
6311                         }
6312
6313                         return true;
6314                 }
6315                 
6316                 public override void Emit (TypeContainer container)
6317                 {
6318                         //
6319                         // abstract or extern methods have no bodies
6320                         //
6321                         if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
6322                                 return;
6323                         
6324                         OperatorMethod.Emit (container);
6325                         Block = null;
6326                 }
6327
6328                 public static string GetName (OpType ot)
6329                 {
6330                         switch (ot){
6331                         case OpType.LogicalNot:
6332                                 return "!";
6333                         case OpType.OnesComplement:
6334                                 return "~";
6335                         case OpType.Increment:
6336                                 return "++";
6337                         case OpType.Decrement:
6338                                 return "--";
6339                         case OpType.True:
6340                                 return "true";
6341                         case OpType.False:
6342                                 return "false";
6343                         case OpType.Addition:
6344                                 return "+";
6345                         case OpType.Subtraction:
6346                                 return "-";
6347                         case OpType.UnaryPlus:
6348                                 return "+";
6349                         case OpType.UnaryNegation:
6350                                 return "-";
6351                         case OpType.Multiply:
6352                                 return "*";
6353                         case OpType.Division:
6354                                 return "/";
6355                         case OpType.Modulus:
6356                                 return "%";
6357                         case OpType.BitwiseAnd:
6358                                 return "&";
6359                         case OpType.BitwiseOr:
6360                                 return "|";
6361                         case OpType.ExclusiveOr:
6362                                 return "^";
6363                         case OpType.LeftShift:
6364                                 return "<<";
6365                         case OpType.RightShift:
6366                                 return ">>";
6367                         case OpType.Equality:
6368                                 return "==";
6369                         case OpType.Inequality:
6370                                 return "!=";
6371                         case OpType.GreaterThan:
6372                                 return ">";
6373                         case OpType.LessThan:
6374                                 return "<";
6375                         case OpType.GreaterThanOrEqual:
6376                                 return ">=";
6377                         case OpType.LessThanOrEqual:
6378                                 return "<=";
6379                         case OpType.Implicit:
6380                                 return "implicit";
6381                         case OpType.Explicit:
6382                                 return "explicit";
6383                         default: return "";
6384                         }
6385                 }
6386
6387                 public override string GetSignatureForError(TypeContainer tc)
6388                 {
6389                         return Prototype (tc);
6390                 }
6391                 
6392                 public override string ToString ()
6393                 {
6394                         Type return_type = OperatorMethod.GetReturnType();
6395                         Type [] param_types = OperatorMethod.ParameterTypes;
6396                         
6397                         if (SecondArgType == null)
6398                                 return String.Format (
6399                                         "{0} operator {1}({2})",
6400                                         TypeManager.CSharpName (return_type),
6401                                         GetName (OperatorType),
6402                                         param_types [0]);
6403                         else
6404                                 return String.Format (
6405                                         "{0} operator {1}({2}, {3})",
6406                                         TypeManager.CSharpName (return_type),
6407                                         GetName (OperatorType),
6408                                         param_types [0], param_types [1]);
6409                 }
6410
6411                 protected override string[] ValidAttributeTargets {
6412                         get {
6413                                 return attribute_targets;
6414                         }
6415                 }
6416
6417                 public void SetYields ()
6418                 {
6419                         ModFlags |= Modifiers.METHOD_YIELDS;
6420                 }
6421         }
6422
6423         //
6424         // This is used to compare method signatures
6425         //
6426         struct MethodSignature {
6427                 public string Name;
6428                 public Type RetType;
6429                 public Type [] Parameters;
6430                 
6431                 /// <summary>
6432                 ///    This delegate is used to extract methods which have the
6433                 ///    same signature as the argument
6434                 /// </summary>
6435                 public static MemberFilter method_signature_filter = new MemberFilter (MemberSignatureCompare);
6436                 
6437                 public MethodSignature (string name, Type ret_type, Type [] parameters)
6438                 {
6439                         Name = name;
6440                         RetType = ret_type;
6441
6442                         if (parameters == null)
6443                                 Parameters = TypeManager.NoTypes;
6444                         else
6445                                 Parameters = parameters;
6446                 }
6447
6448                 public override string ToString ()
6449                 {
6450                         string pars = "";
6451                         if (Parameters.Length != 0){
6452                                 System.Text.StringBuilder sb = new System.Text.StringBuilder ();
6453                                 for (int i = 0; i < Parameters.Length; i++){
6454                                         sb.Append (Parameters [i]);
6455                                         if (i+1 < Parameters.Length)
6456                                                 sb.Append (", ");
6457                                 }
6458                                 pars = sb.ToString ();
6459                         }
6460
6461                         return String.Format ("{0} {1} ({2})", RetType, Name, pars);
6462                 }
6463                 
6464                 public override int GetHashCode ()
6465                 {
6466                         return Name.GetHashCode ();
6467                 }
6468
6469                 public override bool Equals (Object o)
6470                 {
6471                         MethodSignature other = (MethodSignature) o;
6472
6473                         if (other.Name != Name)
6474                                 return false;
6475
6476                         if (other.RetType != RetType)
6477                                 return false;
6478                         
6479                         if (Parameters == null){
6480                                 if (other.Parameters == null)
6481                                         return true;
6482                                 return false;
6483                         }
6484
6485                         if (other.Parameters == null)
6486                                 return false;
6487                         
6488                         int c = Parameters.Length;
6489                         if (other.Parameters.Length != c)
6490                                 return false;
6491
6492                         for (int i = 0; i < c; i++)
6493                                 if (other.Parameters [i] != Parameters [i])
6494                                         return false;
6495
6496                         return true;
6497                 }
6498
6499                 static bool MemberSignatureCompare (MemberInfo m, object filter_criteria)
6500                 {
6501                         MethodSignature sig = (MethodSignature) filter_criteria;
6502
6503                         if (m.Name != sig.Name)
6504                                 return false;
6505
6506                         Type ReturnType;
6507                         MethodInfo mi = m as MethodInfo;
6508                         PropertyInfo pi = m as PropertyInfo;
6509
6510                         if (mi != null)
6511                                 ReturnType = mi.ReturnType;
6512                         else if (pi != null)
6513                                 ReturnType = pi.PropertyType;
6514                         else
6515                                 return false;
6516                         
6517                         //
6518                         // we use sig.RetType == null to mean `do not check the
6519                         // method return value.  
6520                         //
6521                         if (sig.RetType != null)
6522                                 if (ReturnType != sig.RetType)
6523                                         return false;
6524
6525                         Type [] args;
6526                         if (mi != null)
6527                                 args = TypeManager.GetArgumentTypes (mi);
6528                         else
6529                                 args = TypeManager.GetArgumentTypes (pi);
6530                         Type [] sigp = sig.Parameters;
6531
6532                         if (args.Length != sigp.Length)
6533                                 return false;
6534
6535                         for (int i = args.Length; i > 0; ){
6536                                 i--;
6537                                 if (args [i] != sigp [i])
6538                                         return false;
6539                         }
6540                         return true;
6541                 }
6542         }
6543 }