This commit was manufactured by cvs2svn to create branch 'mono-1-0'.
[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 (enums != null) {
1839                                 foreach (Enum e in enums) {
1840                                         e.Emit (this);
1841                                 }
1842                         }
1843
1844                         if (Pending != null)
1845                                 if (Pending.VerifyPendingMethods ())
1846                                         return;
1847
1848                         VerifyMembers (ec);
1849                         
1850 //                      if (types != null)
1851 //                              foreach (TypeContainer tc in types)
1852 //                                      tc.Emit ();
1853                 }
1854
1855                 CustomAttributeBuilder EmitDefaultMemberAttr ()
1856                 {
1857                         EmitContext ec = new EmitContext (this, Location, null, null, ModFlags);
1858
1859                         Expression ml = Expression.MemberLookup (ec, TypeManager.default_member_type,
1860                                                                  ".ctor", MemberTypes.Constructor,
1861                                                                  BindingFlags.Public | BindingFlags.Instance,
1862                                                                  Location.Null);
1863                         
1864                         MethodGroupExpr mg = (MethodGroupExpr) ml;
1865
1866                         MethodBase constructor = mg.Methods [0];
1867
1868                         string [] vals = { IndexerName };
1869
1870                         CustomAttributeBuilder cb = null;
1871                         try {
1872                                 cb = new CustomAttributeBuilder ((ConstructorInfo) constructor, vals);
1873                         } catch {
1874                                 Report.Warning (-100, "Can not set the indexer default member attribute");
1875                         }
1876
1877                         return cb;
1878                 }
1879
1880                 public override void CloseType ()
1881                 {
1882                         if ((caching_flags & Flags.CloseTypeCreated) != 0)
1883                                 return;
1884                         
1885                         try {
1886                                 caching_flags |= Flags.CloseTypeCreated;
1887                                 TypeBuilder.CreateType ();
1888                         } catch (TypeLoadException){
1889                                 //
1890                                 // This is fine, the code still created the type
1891                                 //
1892 //                              Report.Warning (-20, "Exception while creating class: " + TypeBuilder.Name);
1893 //                              Console.WriteLine (e.Message);
1894                         } catch {
1895                                 Console.WriteLine ("In type: " + Name);
1896                                 throw;
1897                         }
1898                         
1899                         if (Enums != null)
1900                                 foreach (Enum en in Enums)
1901                                         en.CloseType ();
1902
1903                         if (interface_order != null){
1904                                 foreach (Interface iface in interface_order)
1905                                         iface.CloseType ();
1906                         }
1907                         
1908                         if (Types != null){
1909                                 foreach (TypeContainer tc in Types)
1910                                         if (tc is Struct)
1911                                                 tc.CloseType ();
1912
1913                                 foreach (TypeContainer tc in Types)
1914                                         if (!(tc is Struct))
1915                                                 tc.CloseType ();
1916                         }
1917
1918                         if (Delegates != null)
1919                                 foreach (Delegate d in Delegates)
1920                                         d.CloseType ();
1921                         
1922                         types = null;
1923                         properties = null;
1924                         enums = null;
1925                         delegates = null;
1926                         fields = null;
1927                         initialized_fields = null;
1928                         initialized_static_fields = null;
1929                         constants = null;
1930                         interfaces = null;
1931                         interface_order = null;
1932                         methods = null;
1933                         events = null;
1934                         indexers = null;
1935                         operators = null;
1936                         ec = null;
1937                         default_constructor = null;
1938                         default_static_constructor = null;
1939                         type_bases = null;
1940                         OptAttributes = null;
1941                         ifaces = null;
1942                         parent_container = null;
1943                         member_cache = null;
1944                 }
1945
1946                 public string MakeName (string n)
1947                 {
1948                         return "`" + Name + "." + n + "'";
1949                 }
1950
1951                 public void Warning_KeywordNewRequired (Location l, MemberInfo mi)
1952                 {
1953                         Report.Warning (
1954                                 108, l, "The keyword new is required on " + 
1955                                 MakeName (mi.Name) + " because it hides `" +
1956                                 mi.ReflectedType.Name + "." + mi.Name + "'");
1957                 }
1958
1959                 public void Warning_KeywordNewNotRequired (Location l, MemberCore mc)
1960                 {
1961                         Report.Warning (
1962                                 109, l, "The member " + MakeName (mc.Name) + " does not hide an " +
1963                                 "inherited member, the keyword new is not required");
1964                 }
1965
1966                 public void Error_EventCanOnlyOverrideEvent (Location l, MemberInfo mi)
1967                 {
1968                         Report.Error (
1969                                 72, l, MakeName (mi.Name) + " : cannot override; `" +
1970                                 mi.ReflectedType.Name + "." + mi.Name + "' is not an event");
1971                 }
1972                 
1973                 public static int CheckMember (string name, MemberInfo mi, int ModFlags)
1974                 {
1975                         return 0;
1976                 }
1977
1978                 //
1979                 // Performs the validation on a Method's modifiers (properties have
1980                 // the same properties).
1981                 //
1982                 public bool MethodModifiersValid (int flags, string n, Location loc)
1983                 {
1984                         const int vao = (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE);
1985                         const int va = (Modifiers.VIRTUAL | Modifiers.ABSTRACT);
1986                         const int nv = (Modifiers.NEW | Modifiers.VIRTUAL);
1987                         bool ok = true;
1988                         
1989                         //
1990                         // At most one of static, virtual or override
1991                         //
1992                         if ((flags & Modifiers.STATIC) != 0){
1993                                 if ((flags & vao) != 0){
1994                                         Report.Error (
1995                                                 112, loc, "static method " + MakeName (n) + "can not be marked " +
1996                                                 "as virtual, abstract or override");
1997                                         ok = false;
1998                                 }
1999                         }
2000
2001                         if (this is Struct){
2002                                 if ((flags & va) != 0){
2003                                         Modifiers.Error_InvalidModifier (loc, "virtual or abstract");
2004                                         ok = false;
2005                                 }
2006                         }
2007
2008                         if ((flags & Modifiers.OVERRIDE) != 0 && (flags & nv) != 0){
2009                                 Report.Error (
2010                                         113, loc, MakeName (n) +
2011                                         " marked as override cannot be marked as new or virtual");
2012                                 ok = false;
2013                         }
2014
2015                         //
2016                         // If the declaration includes the abstract modifier, then the
2017                         // declaration does not include static, virtual or extern
2018                         //
2019                         if ((flags & Modifiers.ABSTRACT) != 0){
2020                                 if ((flags & Modifiers.EXTERN) != 0){
2021                                         Report.Error (
2022                                                 180, loc, MakeName (n) + " can not be both abstract and extern");
2023                                         ok = false;
2024                                 }
2025
2026                                 if ((flags & Modifiers.VIRTUAL) != 0){
2027                                         Report.Error (
2028                                                 503, loc, MakeName (n) + " can not be both abstract and virtual");
2029                                         ok = false;
2030                                 }
2031
2032                                 if ((ModFlags & Modifiers.ABSTRACT) == 0){
2033                                         Report.Error (
2034                                                 513, loc, MakeName (n) +
2035                                                 " is abstract but its container class is not");
2036                                         ok = false;
2037
2038                                 }
2039                         }
2040
2041                         if ((flags & Modifiers.PRIVATE) != 0){
2042                                 if ((flags & vao) != 0){
2043                                         Report.Error (
2044                                                 621, loc, MakeName (n) +
2045                                                 " virtual or abstract members can not be private");
2046                                         ok = false;
2047                                 }
2048                         }
2049
2050                         if ((flags & Modifiers.SEALED) != 0){
2051                                 if ((flags & Modifiers.OVERRIDE) == 0){
2052                                         Report.Error (
2053                                                 238, loc, MakeName (n) +
2054                                                 " cannot be sealed because it is not an override");
2055                                         ok = false;
2056                                 }
2057                         }
2058
2059                         return ok;
2060                 }
2061
2062                 Hashtable builder_and_args;
2063                 
2064                 public bool RegisterMethod (MethodBuilder mb, InternalParameters ip, Type [] args)
2065                 {
2066                         if (builder_and_args == null)
2067                                 builder_and_args = new Hashtable ();
2068                         return true;
2069                 }
2070
2071                 protected override bool VerifyClsCompliance (DeclSpace ds)
2072                 {
2073                         if (!base.VerifyClsCompliance (ds))
2074                                 return false;
2075
2076                         // parent_container is null for System.Object
2077                         if (parent_container != null && !AttributeTester.IsClsCompliant (parent_container.Type)) {
2078                                 Report.Error_T (3009, Location, GetSignatureForError (),  TypeManager.CSharpName (parent_container.Type));
2079                         }
2080                         return true;
2081                 }
2082
2083
2084                 /// <summary>
2085                 ///   Performs checks for an explicit interface implementation.  First it
2086                 ///   checks whether the `interface_type' is a base inteface implementation.
2087                 ///   Then it checks whether `name' exists in the interface type.
2088                 /// </summary>
2089                 public bool VerifyImplements (Type interface_type, string full, string name, Location loc)
2090                 {
2091                         bool found = false;
2092
2093                         if (ifaces != null){
2094                                 foreach (TypeExpr t in ifaces){
2095                                         if (t.Type == interface_type){
2096                                                 found = true;
2097                                                 break;
2098                                         }
2099                                 }
2100                         }
2101                         
2102                         if (!found){
2103                                 Report.Error (540, "`" + full + "': containing class does not implement interface `" + interface_type.FullName + "'");
2104                                 return false;
2105                         }
2106
2107                         return true;
2108                 }
2109
2110                 protected override void VerifyObsoleteAttribute()
2111                 {
2112                         CheckUsageOfObsoleteAttribute (base_classs_type);
2113
2114                         if (ifaces == null)
2115                                 return;
2116
2117                         foreach (TypeExpr expr in ifaces) {
2118                                 CheckUsageOfObsoleteAttribute (expr.Type);
2119                         }
2120                 }
2121
2122
2123                 //
2124                 // IMemberContainer
2125                 //
2126
2127                 string IMemberContainer.Name {
2128                         get {
2129                                 return Name;
2130                         }
2131                 }
2132
2133                 Type IMemberContainer.Type {
2134                         get {
2135                                 return TypeBuilder;
2136                         }
2137                 }
2138
2139                 IMemberContainer IMemberContainer.Parent {
2140                         get {
2141                                 return parent_container;
2142                         }
2143                 }
2144
2145                 MemberCache IMemberContainer.MemberCache {
2146                         get {
2147                                 return member_cache;
2148                         }
2149                 }
2150
2151                 bool IMemberContainer.IsInterface {
2152                         get {
2153                                 return this is Interface;
2154                         }
2155                 }
2156
2157                 MemberList IMemberContainer.GetMembers (MemberTypes mt, BindingFlags bf)
2158                 {
2159                         return FindMembers (mt, bf | BindingFlags.DeclaredOnly, null, null);
2160                 }
2161
2162                 //
2163                 // Operator pair checking
2164                 //
2165
2166                 class OperatorEntry {
2167                         public int flags;
2168                         public Type ret_type;
2169                         public Type type1, type2;
2170                         public Operator op;
2171                         public Operator.OpType ot;
2172                         
2173                         public OperatorEntry (int f, Operator o)
2174                         {
2175                                 flags = f;
2176
2177                                 ret_type = o.OperatorMethod.GetReturnType ();
2178                                 Type [] pt = o.OperatorMethod.ParameterTypes;
2179                                 type1 = pt [0];
2180                                 type2 = pt [1];
2181                                 op = o;
2182                                 ot = o.OperatorType;
2183                         }
2184
2185                         public override int GetHashCode ()
2186                         {       
2187                                 return ret_type.GetHashCode ();
2188                         }
2189
2190                         public override bool Equals (object o)
2191                         {
2192                                 OperatorEntry other = (OperatorEntry) o;
2193
2194                                 if (other.ret_type != ret_type)
2195                                         return false;
2196                                 if (other.type1 != type1)
2197                                         return false;
2198                                 if (other.type2 != type2)
2199                                         return false;
2200                                 return true;
2201                         }
2202                 }
2203                                 
2204                 //
2205                 // Checks that some operators come in pairs:
2206                 //  == and !=
2207                 // > and <
2208                 // >= and <=
2209                 // true and false
2210                 //
2211                 // They are matched based on the return type and the argument types
2212                 //
2213                 void CheckPairedOperators ()
2214                 {
2215                         Hashtable pairs = new Hashtable (null, null);
2216                         Operator true_op = null;
2217                         Operator false_op = null;
2218                         bool has_equality_or_inequality = false;
2219                         
2220                         // Register all the operators we care about.
2221                         foreach (Operator op in operators){
2222                                 int reg = 0;
2223                                 
2224                                 switch (op.OperatorType){
2225                                 case Operator.OpType.Equality:
2226                                         reg = 1;
2227                                         has_equality_or_inequality = true;
2228                                         break;
2229                                 case Operator.OpType.Inequality:
2230                                         reg = 2;
2231                                         has_equality_or_inequality = true;
2232                                         break;
2233
2234                                 case Operator.OpType.True:
2235                                         true_op = op;
2236                                         break;
2237                                 case Operator.OpType.False:
2238                                         false_op = op;
2239                                         break;
2240                                         
2241                                 case Operator.OpType.GreaterThan:
2242                                         reg = 1; break;
2243                                 case Operator.OpType.LessThan:
2244                                         reg = 2; break;
2245                                         
2246                                 case Operator.OpType.GreaterThanOrEqual:
2247                                         reg = 1; break;
2248                                 case Operator.OpType.LessThanOrEqual:
2249                                         reg = 2; break;
2250                                 }
2251                                 if (reg == 0)
2252                                         continue;
2253
2254                                 OperatorEntry oe = new OperatorEntry (reg, op);
2255
2256                                 object o = pairs [oe];
2257                                 if (o == null)
2258                                         pairs [oe] = oe;
2259                                 else {
2260                                         oe = (OperatorEntry) o;
2261                                         oe.flags |= reg;
2262                                 }
2263                         }
2264
2265                         if (true_op != null){
2266                                 if (false_op == null)
2267                                         Report.Error (216, true_op.Location, "operator true requires a matching operator false");
2268                         } else if (false_op != null)
2269                                 Report.Error (216, false_op.Location, "operator false requires a matching operator true");
2270                         
2271                         //
2272                         // Look for the mistakes.
2273                         //
2274                         foreach (DictionaryEntry de in pairs){
2275                                 OperatorEntry oe = (OperatorEntry) de.Key;
2276
2277                                 if (oe.flags == 3)
2278                                         continue;
2279
2280                                 string s = "";
2281                                 switch (oe.ot){
2282                                 case Operator.OpType.Equality:
2283                                         s = "!=";
2284                                         break;
2285                                 case Operator.OpType.Inequality: 
2286                                         s = "==";
2287                                         break;
2288                                 case Operator.OpType.GreaterThan: 
2289                                         s = "<";
2290                                         break;
2291                                 case Operator.OpType.LessThan:
2292                                         s = ">";
2293                                         break;
2294                                 case Operator.OpType.GreaterThanOrEqual:
2295                                         s = "<=";
2296                                         break;
2297                                 case Operator.OpType.LessThanOrEqual:
2298                                         s = ">=";
2299                                         break;
2300                                 }
2301                                 Report.Error (216, oe.op.Location,
2302                                               "The operator `" + oe.op + "' requires a matching operator `" + s + "' to also be defined");
2303                         }
2304
2305                         if ((has_equality_or_inequality) && (RootContext.WarningLevel >= 2)) {
2306                                 MethodSignature equals_ms = new MethodSignature (
2307                                         "Equals", TypeManager.bool_type, new Type [] { TypeManager.object_type });
2308                                 MethodSignature hash_ms = new MethodSignature (
2309                                         "GetHashCode", TypeManager.int32_type, new Type [0]);
2310
2311                                 MemberList equals_ml = FindMembers (MemberTypes.Method, BindingFlags.Public | BindingFlags.Instance |
2312                                                                     BindingFlags.DeclaredOnly, MethodSignature.method_signature_filter,
2313                                                                     equals_ms);
2314                                 MemberList hash_ml = FindMembers (MemberTypes.Method, BindingFlags.Public | BindingFlags.Instance |
2315                                                                   BindingFlags.DeclaredOnly, MethodSignature.method_signature_filter,
2316                                                                   hash_ms);
2317
2318                                 bool equals_ok = false;
2319                                 if ((equals_ml != null) && (equals_ml.Count == 1))
2320                                         equals_ok = equals_ml [0].DeclaringType == TypeBuilder;
2321                                 bool hash_ok = false;
2322                                 if ((hash_ml != null) && (hash_ml.Count == 1))
2323                                         hash_ok = hash_ml [0].DeclaringType == TypeBuilder;
2324
2325                                 if (!equals_ok)
2326                                         Report.Warning (660, Location, "`" + Name + "' defines operator == or operator != but does " +
2327                                                         "not override Object.Equals (object o)");
2328                                 if (!hash_ok)
2329                                         Report.Warning (661, Location, "`" + Name + "' defines operator == or operator != but does " +
2330                                                         "not override Object.GetHashCode ()");
2331                         }
2332                 }
2333                 
2334                 
2335         }
2336
2337         public class ClassOrStruct : TypeContainer {
2338                 bool hasExplicitLayout = false;
2339                 public ClassOrStruct (NamespaceEntry ns, TypeContainer parent, string name, Attributes attrs, Location l)
2340                         : base (ns, parent, name, attrs, l)
2341                 {
2342                 }
2343
2344                 protected override void VerifyMembers (EmitContext ec) 
2345                 {
2346                         if (Fields != null) {
2347                                 foreach (Field f in Fields) {
2348                                         if ((f.ModFlags & Modifiers.STATIC) != 0)
2349                                                 continue;
2350                                         if (hasExplicitLayout) {
2351                                                 if (f.OptAttributes == null 
2352                                                     || !f.OptAttributes.Contains (TypeManager.field_offset_attribute_type, ec)) {
2353                                                         Report.Error (625, f.Location,
2354                                                                       "Instance field of type marked with" 
2355                                                                       + " StructLayout(LayoutKind.Explicit) must have a"
2356                                                                       + " FieldOffset attribute.");
2357                                                 }
2358                                         }
2359                                         else {
2360                                                 if (f.OptAttributes != null 
2361                                                     && f.OptAttributes.Contains (TypeManager.field_offset_attribute_type, ec)) {
2362                                                         Report.Error (636, f.Location,
2363                                                                       "The FieldOffset attribute can only be placed on members of "
2364                                                                       + "types marked with the StructLayout(LayoutKind.Explicit)");
2365                                                 }
2366                                         }
2367                                 }
2368                         }
2369                         base.VerifyMembers (ec);
2370                 }
2371
2372                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
2373                 {
2374                         if (a.Type == TypeManager.struct_layout_attribute_type
2375                             && (LayoutKind) a.GetPositionalValue (0) == LayoutKind.Explicit)
2376                                 hasExplicitLayout = true;
2377
2378                         base.ApplyAttributeBuilder (a, cb);
2379                 }
2380         }
2381
2382         public class Class : ClassOrStruct {
2383                 // <summary>
2384                 //   Modifiers allowed in a class declaration
2385                 // </summary>
2386                 public const int AllowedModifiers =
2387                         Modifiers.NEW |
2388                         Modifiers.PUBLIC |
2389                         Modifiers.PROTECTED |
2390                         Modifiers.INTERNAL |
2391                         Modifiers.PRIVATE |
2392                         Modifiers.ABSTRACT |
2393                         Modifiers.SEALED |
2394                         Modifiers.UNSAFE;
2395
2396
2397                 // Information in the case we are an attribute type
2398                 AttributeUsageAttribute attribute_usage;
2399
2400                 public Class (NamespaceEntry ns, TypeContainer parent, string name, int mod,
2401                               Attributes attrs, Location l)
2402                         : base (ns, parent, name, attrs, l)
2403                 {
2404                         int accmods;
2405
2406                         if (parent.Parent == null)
2407                                 accmods = Modifiers.INTERNAL;
2408                         else
2409                                 accmods = Modifiers.PRIVATE;
2410
2411                         this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
2412                         attribute_usage = new AttributeUsageAttribute (AttributeTargets.All);
2413                 }
2414
2415                 public override AttributeTargets AttributeTargets {
2416                         get {
2417                                 return AttributeTargets.Class;
2418                         }
2419                 }
2420
2421                 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
2422                 {
2423                         if (a.UsageAttribute != null)
2424                                 attribute_usage = a.UsageAttribute;
2425
2426                         base.ApplyAttributeBuilder (a, cb);
2427                 }
2428
2429                 public AttributeUsageAttribute AttributeUsage {
2430                         get {
2431                                 return attribute_usage;
2432                         }
2433                 }
2434
2435                 //
2436                 // FIXME: How do we deal with the user specifying a different
2437                 // layout?
2438                 //
2439                 public override TypeAttributes TypeAttr {
2440                         get {
2441                                 return base.TypeAttr | TypeAttributes.AutoLayout | TypeAttributes.Class;
2442                         }
2443                 }
2444         }
2445
2446         public class Struct : ClassOrStruct {
2447                 // <summary>
2448                 //   Modifiers allowed in a struct declaration
2449                 // </summary>
2450                 public const int AllowedModifiers =
2451                         Modifiers.NEW       |
2452                         Modifiers.PUBLIC    |
2453                         Modifiers.PROTECTED |
2454                         Modifiers.INTERNAL  |
2455                         Modifiers.UNSAFE    |
2456                         Modifiers.PRIVATE;
2457
2458                 public Struct (NamespaceEntry ns, TypeContainer parent, string name, int mod, Attributes attrs, Location l)
2459                         : base (ns, parent, name, attrs, l)
2460                 {
2461                         int accmods;
2462                         
2463                         if (parent.Parent == null)
2464                                 accmods = Modifiers.INTERNAL;
2465                         else
2466                                 accmods = Modifiers.PRIVATE;
2467                         
2468                         this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
2469
2470                         this.ModFlags |= Modifiers.SEALED;
2471                 }
2472
2473                 public override AttributeTargets AttributeTargets {
2474                         get {
2475                                 return AttributeTargets.Struct;
2476                         }
2477                 }
2478
2479
2480                 //
2481                 // FIXME: Allow the user to specify a different set of attributes
2482                 // in some cases (Sealed for example is mandatory for a class,
2483                 // but what SequentialLayout can be changed
2484                 //
2485                 public override TypeAttributes TypeAttr {
2486                         get {
2487                                 return base.TypeAttr |
2488                                         TypeAttributes.SequentialLayout |
2489                                         TypeAttributes.Sealed |
2490                                         TypeAttributes.BeforeFieldInit;
2491                         }
2492                 }
2493         }
2494
2495         /// <summary>
2496         ///   Interfaces
2497         /// </summary>
2498         public class Interface : TypeContainer, IMemberContainer {
2499                 /// <summary>
2500                 ///   Modifiers allowed in a class declaration
2501                 /// </summary>
2502                 public const int AllowedModifiers =
2503                         Modifiers.NEW       |
2504                         Modifiers.PUBLIC    |
2505                         Modifiers.PROTECTED |
2506                         Modifiers.INTERNAL  |
2507                         Modifiers.UNSAFE    |
2508                         Modifiers.PRIVATE;
2509
2510                 public Interface (NamespaceEntry ns, TypeContainer parent, string name, int mod,
2511                                   Attributes attrs, Location l)
2512                         : base (ns, parent, name, attrs, l)
2513                 {
2514                         int accmods;
2515
2516                         if (parent.Parent == null)
2517                                 accmods = Modifiers.INTERNAL;
2518                         else
2519                                 accmods = Modifiers.PRIVATE;
2520
2521                         this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
2522                 }
2523
2524                 public override AttributeTargets AttributeTargets {
2525                         get {
2526                                 return AttributeTargets.Interface;
2527                         }
2528                 }
2529
2530                 public override TypeAttributes TypeAttr {
2531                         get {
2532                                 return base.TypeAttr |
2533                                         TypeAttributes.AutoLayout |
2534                                         TypeAttributes.Abstract |
2535                                         TypeAttributes.Interface;
2536                         }
2537                 }
2538         }
2539
2540         public abstract class MethodCore : MemberBase {
2541                 public readonly Parameters Parameters;
2542                 protected Block block;
2543                 public DeclSpace ds;
2544                 
2545                 //
2546                 // Parameters, cached for semantic analysis.
2547                 //
2548                 protected InternalParameters parameter_info;
2549                 protected Type [] parameter_types;
2550
2551                 // <summary>
2552                 //   This is set from TypeContainer.DefineMembers if this method overrides something.
2553                 // </summary>
2554                 public bool OverridesSomething;
2555
2556                 // Whether this is an operator method.
2557                 public bool IsOperator;
2558
2559                 static string[] attribute_targets = new string [] { "method", "return" };
2560
2561                 public MethodCore (DeclSpace ds, Expression type, int mod, int allowed_mod,
2562                                    bool is_interface, string name, Attributes attrs,
2563                                    Parameters parameters, Location loc)
2564                         : base (type, mod, allowed_mod, Modifiers.PRIVATE, name, attrs, loc)
2565                 {
2566                         Parameters = parameters;
2567                         IsInterface = is_interface;
2568                         this.ds = ds;
2569                 }
2570                 
2571                 //
2572                 //  Returns the System.Type array for the parameters of this method
2573                 //
2574                 public Type [] ParameterTypes {
2575                         get {
2576                                 return parameter_types;
2577                         }
2578                 }
2579
2580                 public InternalParameters ParameterInfo
2581                 {
2582                         get {
2583                                 return parameter_info;
2584                         }
2585                 }
2586                 
2587                 public Block Block {
2588                         get {
2589                                 return block;
2590                         }
2591
2592                         set {
2593                                 block = value;
2594                         }
2595                 }
2596
2597                 protected virtual bool DoDefineParameters ()
2598                 {
2599                         // Check if arguments were correct
2600                         parameter_types = Parameters.GetParameterInfo (ds);
2601                         if ((parameter_types == null) || !CheckParameters (ds, parameter_types))
2602                                 return false;
2603
2604                         parameter_info = new InternalParameters (ds, Parameters);
2605
2606                         Parameter array_param = Parameters.ArrayParameter;
2607                         if ((array_param != null) &&
2608                             (!array_param.ParameterType.IsArray ||
2609                              (array_param.ParameterType.GetArrayRank () != 1))) {
2610                                 Report.Error (225, Location, "params parameter has to be a single dimensional array");
2611                                 return false;
2612                         }
2613
2614                         return true;
2615                 }
2616
2617                 protected override string[] ValidAttributeTargets {
2618                         get {
2619                                 return attribute_targets;
2620                         }
2621                 }
2622
2623                 protected override bool VerifyClsCompliance (DeclSpace ds)
2624                 {
2625                         if (!base.VerifyClsCompliance (ds)) {
2626                                 if ((ModFlags & Modifiers.ABSTRACT) != 0 && IsExposedFromAssembly (ds) && ds.IsClsCompliaceRequired (ds)) {
2627                                         Report.Error_T (3011, Location, GetSignatureForError ());
2628                                 }
2629                                 return false;
2630                         }
2631
2632                         if (Parameters.HasArglist) {
2633                                 // "Methods with variable arguments are not CLS-compliant"
2634                                 Report.Error_T (3000, Location);
2635                         }
2636
2637                         AttributeTester.AreParametersCompliant (Parameters.FixedParameters, Location);
2638
2639                         if (!AttributeTester.IsClsCompliant (MemberType)) {
2640                                 Report.Error_T (3002, Location, GetSignatureForError ());
2641                         }
2642
2643                         return true;
2644                 }
2645
2646                 protected bool IsDuplicateImplementation (TypeContainer tc, MethodCore method)
2647                 {
2648                         if ((method == this) || (method.Name != Name))
2649                                 return false;
2650
2651                         Type[] param_types = method.ParameterTypes;
2652                         if (param_types == null)
2653                                 return false;
2654
2655                         if (param_types.Length != ParameterTypes.Length)
2656                                 return false;
2657
2658                         for (int i = 0; i < param_types.Length; i++)
2659                                 if (param_types [i] != ParameterTypes [i])
2660                                         return false;
2661
2662                         //
2663                         // Try to report 663: method only differs on out/ref
2664                         //
2665                         ParameterData info = ParameterInfo;
2666                         ParameterData other_info = method.ParameterInfo;
2667                         for (int i = 0; i < info.Count; i++){
2668                                 if (info.ParameterModifier (i) != other_info.ParameterModifier (i)){
2669                                         Report.Error (663, Location, "Overload method only differs in parameter modifier");
2670                                         return false;
2671                                 }
2672                         }
2673
2674                         Report.Error (111, Location, "Class `{0}' already defines a " +
2675                                       "member called `{1}' with the same parameter types",
2676                                       tc.Name, Name);
2677                         return true;
2678                 }
2679
2680                 public CallingConventions GetCallingConvention (bool is_class)
2681                 {
2682                         CallingConventions cc = 0;
2683                         
2684                         cc = Parameters.GetCallingConvention ();
2685
2686                         if (is_class)
2687                                 if ((ModFlags & Modifiers.STATIC) == 0)
2688                                         cc |= CallingConventions.HasThis;
2689
2690                         // FIXME: How is `ExplicitThis' used in C#?
2691                         
2692                         return cc;
2693                 }
2694
2695                 protected override void VerifyObsoleteAttribute()
2696                 {
2697                         base.VerifyObsoleteAttribute ();
2698
2699                         if (parameter_types == null)
2700                                 return;
2701
2702                         foreach (Type type in parameter_types) {
2703                                 CheckUsageOfObsoleteAttribute (type);
2704                         }
2705                 }
2706         }
2707
2708         public class Method : MethodCore, IIteratorContainer, IMethodData {
2709                 public MethodBuilder MethodBuilder;
2710                 public MethodData MethodData;
2711                 ReturnParameter return_attributes;
2712
2713                 /// <summary>
2714                 ///   Modifiers allowed in a class declaration
2715                 /// </summary>
2716                 const int AllowedModifiers =
2717                         Modifiers.NEW |
2718                         Modifiers.PUBLIC |
2719                         Modifiers.PROTECTED |
2720                         Modifiers.INTERNAL |
2721                         Modifiers.PRIVATE |
2722                         Modifiers.STATIC |
2723                         Modifiers.VIRTUAL |
2724                         Modifiers.SEALED |
2725                         Modifiers.OVERRIDE |
2726                         Modifiers.ABSTRACT |
2727                         Modifiers.UNSAFE |
2728                         Modifiers.METHOD_YIELDS | 
2729                         Modifiers.EXTERN;
2730
2731                 const int AllowedInterfaceModifiers =
2732                         Modifiers.NEW | Modifiers.UNSAFE;
2733
2734                 //
2735                 // return_type can be "null" for VOID values.
2736                 //
2737                 public Method (DeclSpace ds, Expression return_type, int mod, bool is_iface,
2738                                string name, Parameters parameters, Attributes attrs, Location l)
2739                         : base (ds, return_type, mod,
2740                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
2741                                 is_iface, name, attrs, parameters, l)
2742                 {
2743                 }
2744
2745                 public override AttributeTargets AttributeTargets {
2746                         get {
2747                                 return AttributeTargets.Method | AttributeTargets.ReturnValue;
2748                         }
2749                 }
2750                 
2751                 //
2752                 // Returns the `System.Type' for the ReturnType of this
2753                 // function.  Provides a nice cache.  (used between semantic analysis
2754                 // and actual code generation
2755                 //
2756                 public Type GetReturnType ()
2757                 {
2758                         return MemberType;
2759                 }
2760
2761                 public override string GetSignatureForError()
2762                 {
2763                         return TypeManager.CSharpSignature (MethodBuilder);
2764                 }
2765
2766                 /// <summary>
2767                 /// Use this method when MethodBuilder is null
2768                 /// </summary>
2769                 public override string GetSignatureForError (TypeContainer tc)
2770                 {
2771                         // TODO: move to parameters
2772                         System.Text.StringBuilder args = new System.Text.StringBuilder ();
2773                         if (parameter_info.Parameters.FixedParameters != null) {
2774                                 for (int i = 0; i < parameter_info.Parameters.FixedParameters.Length; ++i) {
2775                                         Parameter p = parameter_info.Parameters.FixedParameters [i];
2776                                         args.Append (p.GetSignatureForError ());
2777
2778                                         if (i < parameter_info.Parameters.FixedParameters.Length - 1)
2779                                                 args.Append (',');
2780                                 }
2781                         }
2782
2783                         return String.Concat (base.GetSignatureForError (tc), "(", args.ToString (), ")");
2784                 }
2785
2786                 void DuplicateEntryPoint (MethodInfo b, Location location)
2787                 {
2788                         Report.Error (
2789                                 17, location,
2790                                 "Program `" + CodeGen.FileName +
2791                                 "'  has more than one entry point defined: `" +
2792                                 TypeManager.CSharpSignature(b) + "'");
2793                 }
2794
2795                 void Report28 (MethodInfo b)
2796                 {
2797                         Report.Warning (
2798                                 28, Location,
2799                                 "`" + TypeManager.CSharpSignature(b) +
2800                                 "' has the wrong signature to be an entry point");
2801                 }
2802
2803                 public bool IsEntryPoint (MethodBuilder b, InternalParameters pinfo)
2804                 {
2805                         if (b.ReturnType != TypeManager.void_type &&
2806                             b.ReturnType != TypeManager.int32_type)
2807                                 return false;
2808
2809                         if (pinfo.Count == 0)
2810                                 return true;
2811
2812                         if (pinfo.Count > 1)
2813                                 return false;
2814
2815                         Type t = pinfo.ParameterType(0);
2816                         if (t.IsArray &&
2817                             (t.GetArrayRank() == 1) &&
2818                             (TypeManager.GetElementType(t) == TypeManager.string_type) &&
2819                             (pinfo.ParameterModifier(0) == Parameter.Modifier.NONE))
2820                                 return true;
2821                         else
2822                                 return false;
2823                 }
2824
2825                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
2826                 {
2827                         if (a.Target == "return") {
2828                                 if (return_attributes == null)
2829                                         return_attributes = new ReturnParameter (MethodBuilder, Location);
2830
2831                                 return_attributes.ApplyAttributeBuilder (a, cb);
2832                                 return;
2833                         }
2834
2835                         if (a.Type == TypeManager.methodimpl_attr_type && a.IsInternalCall) {
2836                                 MethodBuilder.SetImplementationFlags (MethodImplAttributes.InternalCall | MethodImplAttributes.Runtime);
2837                         }
2838
2839                         if (a.Type == TypeManager.dllimport_type) {
2840                                 const int extern_static = Modifiers.EXTERN | Modifiers.STATIC;
2841                                 if ((ModFlags & extern_static) != extern_static) {
2842                                         //"The DllImport attribute must be specified on a method marked `static' and `extern'"
2843                                         Report.Error_T (601, a.Location);
2844                                 }
2845
2846                                 return;
2847                         }
2848
2849                         if (a.Type == TypeManager.conditional_attribute_type) {
2850                                 if (IsOperator || IsExplicitImpl) {
2851                                         // Conditional not valid on '{0}' because it is a destructor, operator, or explicit interface implementation
2852                                         Report.Error_T (577, Location, GetSignatureForError ());
2853                                         return;
2854                                 }
2855
2856                                 if (ReturnType != TypeManager.void_type) {
2857                                         // Conditional not valid on '{0}' because its return type is not void
2858                                         Report.Error_T (578, Location, GetSignatureForError ());
2859                                         return;
2860                                 }
2861
2862                                 if ((ModFlags & Modifiers.OVERRIDE) != 0) {
2863                                         // Conditional not valid on '{0}' because it is an override method
2864                                         Report.Error_T (243, Location, GetSignatureForError ());
2865                                         return;
2866                                 }
2867
2868                                 if (IsInterface) {
2869                                         // Conditional not valid on interface members
2870                                         Report.Error_T (582, Location);
2871                                         return;
2872                                 }
2873
2874                                 if (MethodData.IsImplementing) {
2875                                         // Conditional member '{0}' cannot implement interface member
2876                                         Report.Error_T (629, Location, GetSignatureForError ());
2877                                         return;
2878                                 }
2879                         }
2880
2881                         MethodBuilder.SetCustomAttribute (cb);
2882                 }
2883
2884                 //
2885                 // Checks our base implementation if any
2886                 //
2887                 protected override bool CheckBase (TypeContainer container)
2888                 {
2889                         base.CheckBase (container);
2890                         
2891                         // Check whether arguments were correct.
2892                         if (!DoDefineParameters ())
2893                                 return false;
2894
2895                         MethodSignature ms = new MethodSignature (Name, null, ParameterTypes);
2896                         if (IsOperator) {
2897                                 flags |= MethodAttributes.SpecialName | MethodAttributes.HideBySig;
2898                         } else {
2899                                 //
2900                                 // Check in our class for dups
2901                                 //
2902                                 ArrayList ar = container.Methods;
2903                                 if (ar != null) {
2904                                         int arLen = ar.Count;
2905                                         
2906                                         for (int i = 0; i < arLen; i++) {
2907                                                 Method m = (Method) ar [i];
2908                                                 if (IsDuplicateImplementation (container, m))
2909                                                         return false;
2910                                         }
2911                                 }
2912                         }
2913                         
2914
2915                         //
2916                         // Verify if the parent has a type with the same name, and then
2917                         // check whether we have to create a new slot for it or not.
2918                         //
2919                         Type ptype = container.TypeBuilder.BaseType;
2920
2921                         // ptype is only null for System.Object while compiling corlib.
2922                         if (ptype != null) {
2923                                 
2924                                 //
2925                                 // Explicit implementations do not have `parent' methods, however,
2926                                 // the member cache stores them there. Without this check, we get
2927                                 // an incorrect warning in corlib.
2928                                 //
2929                                 if (! IsExplicitImpl) {
2930                                         parent_method = (MethodInfo)((IMemberContainer)container).Parent.MemberCache.FindMemberToOverride (
2931                                                 container.TypeBuilder, Name, ParameterTypes, false);
2932                                 }
2933                                 
2934                                 if (parent_method != null) {
2935                                         string name = parent_method.DeclaringType.Name + "." +
2936                                                 parent_method.Name;
2937
2938                                         if (!CheckMethodAgainstBase (container, flags, parent_method, name))
2939                                                 return false;
2940
2941                                         if ((ModFlags & Modifiers.NEW) == 0) {
2942                                                 Type parent_ret = TypeManager.TypeToCoreType (
2943                                                         parent_method.ReturnType);
2944
2945                                                 if (parent_ret != MemberType) {
2946                                                         Report.Error (
2947                                                                 508, Location, container.MakeName (Name) + ": cannot " +
2948                                                                 "change return type when overriding " +
2949                                                                 "inherited member " + name);
2950                                                         return false;
2951                                                 }
2952                                         }
2953
2954                                         ObsoleteAttribute oa = AttributeTester.GetMethodObsoleteAttribute (parent_method);
2955                                         if (oa != null) {
2956                                                 Report.SymbolRelatedToPreviousError (parent_method);
2957                                                 Report.Warning_T (672, Location, GetSignatureForError (container));
2958                                         }
2959                                 } else {
2960                                         if (!OverridesSomething && ((ModFlags & Modifiers.NEW) != 0))
2961                                                 WarningNotHiding (container);
2962
2963                                         if ((ModFlags & Modifiers.OVERRIDE) != 0){
2964                                                 Report.Error (115, Location,
2965                                                               container.MakeName (Name) +
2966                                                               " no suitable methods found to override");
2967                                         }
2968                                 }
2969                         } else if ((ModFlags & Modifiers.NEW) != 0)
2970                                 WarningNotHiding (container);
2971
2972                         return true;
2973                 }
2974
2975                 //
2976                 // Creates the type
2977                 //
2978                 public override bool Define (TypeContainer container)
2979                 {
2980                         if (!DoDefine (container))
2981                                 return false;
2982
2983                         if (!CheckBase (container))
2984                                 return false;
2985
2986                         MethodData = new MethodData (this, ParameterInfo, ModFlags, flags, this);
2987
2988                         if (!MethodData.Define (container))
2989                                 return false;
2990
2991                         //
2992                         // Setup iterator if we are one
2993                         //
2994                         if ((ModFlags & Modifiers.METHOD_YIELDS) != 0){
2995                                 IteratorHandler ih = new  IteratorHandler (
2996                                             Name, container, MemberType,
2997                                             ParameterTypes, ParameterInfo,
2998                                             ModFlags, Location);
2999
3000                                 Block new_block = ih.Setup (block);
3001                                 if (new_block == null)
3002                                         return false;
3003                                 block = new_block;
3004                         }
3005
3006                         MethodBuilder = MethodData.MethodBuilder;
3007                         
3008                         //
3009                         // This is used to track the Entry Point,
3010                         //
3011                         if (Name == "Main" &&
3012                             ((ModFlags & Modifiers.STATIC) != 0) && RootContext.NeedsEntryPoint && 
3013                             (RootContext.MainClass == null ||
3014                              RootContext.MainClass == container.TypeBuilder.FullName)){
3015                                 if (IsEntryPoint (MethodBuilder, ParameterInfo)) {
3016                                         if (RootContext.EntryPoint == null) {
3017                                                 RootContext.EntryPoint = MethodBuilder;
3018                                                 RootContext.EntryPointLocation = Location;
3019                                         } else {
3020                                                 DuplicateEntryPoint (RootContext.EntryPoint, RootContext.EntryPointLocation);
3021                                                 DuplicateEntryPoint (MethodBuilder, Location);
3022                                         }
3023                                 } else                                  
3024                                         Report28(MethodBuilder);
3025                         }
3026
3027                         return true;
3028                 }
3029
3030                 //
3031                 // Emits the code
3032                 // 
3033                 public override void Emit (TypeContainer container)
3034                 {
3035                         MethodData.Emit (container, this);
3036                         base.Emit (container);
3037                         Block = null;
3038                         MethodData = null;
3039                 }
3040
3041                 void IIteratorContainer.SetYields ()
3042                 {
3043                         ModFlags |= Modifiers.METHOD_YIELDS;
3044                 }
3045         
3046                 protected override bool IsIdentifierClsCompliant (DeclSpace ds)
3047                 {
3048                         return IsIdentifierAndParamClsCompliant (ds, Name, MethodBuilder, parameter_types);
3049                 }
3050
3051                 #region IMethodData Members
3052
3053                 public CallingConventions CallingConventions {
3054                         get {
3055                                 CallingConventions cc = Parameters.GetCallingConvention ();
3056                                 if (Parameters.HasArglist)
3057                                         block.HasVarargs = true;
3058
3059                                 if (!IsInterface)
3060                                         if ((ModFlags & Modifiers.STATIC) == 0)
3061                                                 cc |= CallingConventions.HasThis;
3062
3063                                 // FIXME: How is `ExplicitThis' used in C#?
3064                         
3065                                 return cc;
3066                         }
3067                 }
3068
3069                 public Type ReturnType {
3070                         get {
3071                                 return MemberType;
3072                         }
3073                 }
3074
3075                 public string MethodName {
3076                         get {
3077                                 return ShortName;
3078                         }
3079                 }
3080
3081                 public new Location Location {
3082                         get {
3083                                 return base.Location;
3084                         }
3085                 }
3086
3087                 public EmitContext CreateEmitContext (TypeContainer tc, ILGenerator ig)
3088                 {
3089                         return new EmitContext (tc, ds, Location, ig, ReturnType, ModFlags, false);
3090                 }
3091
3092                 public ObsoleteAttribute GetObsoleteAttribute ()
3093                 {
3094                         return GetObsoleteAttribute (ds);
3095                 }
3096
3097                 /// <summary>
3098                 /// Returns true if method has conditional attribute and the conditions is not defined (method is excluded).
3099                 /// </summary>
3100                 public bool IsExcluded (EmitContext ec)
3101                 {
3102                         if ((caching_flags & Flags.Excluded_Undetected) == 0)
3103                                 return (caching_flags & Flags.Excluded) != 0;
3104
3105                         caching_flags &= ~Flags.Excluded_Undetected;
3106
3107                         if (parent_method == null) {
3108                                 if (OptAttributes == null)
3109                                         return false;
3110
3111                                 Attribute[] attrs = OptAttributes.SearchMulti (TypeManager.conditional_attribute_type, ec);
3112
3113                                 if (attrs == null)
3114                                         return false;
3115
3116                                 foreach (Attribute a in attrs) {
3117                                         string condition = a.GetConditionalAttributeValue (ds);
3118                                         if (RootContext.AllDefines.Contains (condition))
3119                                                 return false;
3120                                 }
3121
3122                                 caching_flags |= Flags.Excluded;
3123                                 return true;
3124                         }
3125
3126                         IMethodData md = TypeManager.GetMethod (parent_method);
3127                         if (md == null) {
3128                                 if (AttributeTester.IsConditionalMethodExcluded (parent_method)) {
3129                                         caching_flags |= Flags.Excluded;
3130                                         return true;
3131                                 }
3132                                 return false;
3133                         }
3134
3135                         if (md.IsExcluded (ec)) {
3136                                 caching_flags |= Flags.Excluded;
3137                                 return true;
3138                         }
3139                         return false;
3140                 }
3141
3142                 #endregion
3143         }
3144
3145         public abstract class ConstructorInitializer {
3146                 ArrayList argument_list;
3147                 protected ConstructorInfo parent_constructor;
3148                 Parameters parameters;
3149                 Location loc;
3150                 
3151                 public ConstructorInitializer (ArrayList argument_list, Parameters parameters,
3152                                                Location loc)
3153                 {
3154                         this.argument_list = argument_list;
3155                         this.parameters = parameters;
3156                         this.loc = loc;
3157                 }
3158
3159                 public ArrayList Arguments {
3160                         get {
3161                                 return argument_list;
3162                         }
3163                 }
3164
3165                 public bool Resolve (ConstructorBuilder caller_builder, EmitContext ec)
3166                 {
3167                         Expression parent_constructor_group;
3168                         Type t;
3169
3170                         ec.CurrentBlock = new ToplevelBlock (Block.Flags.Implicit, parameters, loc);
3171
3172                         if (argument_list != null){
3173                                 foreach (Argument a in argument_list){
3174                                         if (!a.Resolve (ec, loc))
3175                                                 return false;
3176                                 }
3177                         }
3178                         ec.CurrentBlock = null;
3179
3180                         if (this is ConstructorBaseInitializer) {
3181                                 if (ec.ContainerType.BaseType == null)
3182                                         return true;
3183
3184                                 t = ec.ContainerType.BaseType;
3185                                 if (ec.ContainerType.IsValueType) {
3186                                         Report.Error (522, loc,
3187                                                 "structs cannot call base class constructors");
3188                                         return false;
3189                                 }
3190                         } else
3191                                 t = ec.ContainerType;
3192
3193                         parent_constructor_group = Expression.MemberLookup (
3194                                 ec, t, ".ctor", MemberTypes.Constructor,
3195                                 BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
3196                                 loc);
3197                         
3198                         if (parent_constructor_group == null){
3199                                 parent_constructor_group = Expression.MemberLookup (
3200                                         ec, t, ".ctor", MemberTypes.Constructor,
3201                                         BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly,
3202                                         loc);
3203
3204                                 if (parent_constructor_group != null)
3205                                         Report.Error (
3206                                                 112, loc, "`{0}.{1}' is inaccessible due to " +
3207                                                 "its protection level", t.FullName, t.Name);
3208                                 else
3209                                         Report.Error (
3210                                                 1501, loc, "Can not find a constructor for " +
3211                                                 "this argument list");
3212                                 return false;
3213                         }
3214                         
3215                         parent_constructor = (ConstructorInfo) Invocation.OverloadResolve (ec, 
3216                                 (MethodGroupExpr) parent_constructor_group, argument_list, loc);
3217                         
3218                         if (parent_constructor == null){
3219                                 Report.Error (1501, loc,
3220                                        "Can not find a constructor for this argument list");
3221                                 return false;
3222                         }
3223
3224                         if (parent_constructor == caller_builder){
3225                                 Report.Error (515, String.Format ("Constructor `{0}' can not call itself", TypeManager.CSharpSignature (caller_builder)));
3226                                 return false;
3227                         }
3228                         
3229                         return true;
3230                 }
3231
3232                 public void Emit (EmitContext ec)
3233                 {
3234                         if (parent_constructor != null){
3235                                 ec.Mark (loc, false);
3236                                 if (ec.IsStatic)
3237                                         Invocation.EmitCall (ec, true, true, null, parent_constructor, argument_list, loc);
3238                                 else
3239                                         Invocation.EmitCall (ec, true, false, ec.GetThis (loc), parent_constructor, argument_list, loc);
3240                         }
3241                 }
3242
3243                 /// <summary>
3244                 /// Method search for base ctor. (We do not cache it).
3245                 /// </summary>
3246                 Constructor GetOverloadedConstructor (TypeContainer tc)
3247                 {
3248                         if (tc.InstanceConstructors == null)
3249                                 return null;
3250
3251                         foreach (Constructor c in tc.InstanceConstructors) {
3252                                 if (Arguments == null) {
3253                                         if (c.ParameterTypes.Length == 0)
3254                                                 return c;
3255
3256                                         continue;
3257                                 }
3258
3259                                 bool ok = true;
3260
3261                                 int count = c.ParameterInfo.Count;
3262                                 if ((count > 0) &&
3263                                     c.ParameterInfo.ParameterModifier (count - 1) == Parameter.Modifier.PARAMS) {
3264                                         for (int i = 0; i < count-1; i++)
3265                                                 if (c.ParameterTypes [i] != ((Argument)Arguments [i]).Type) {
3266                                                         ok = false;
3267                                                         break;
3268                                                 }
3269                                 } else {
3270                                         if (c.ParameterTypes.Length != Arguments.Count)
3271                                                 continue;
3272
3273                                         for (int i = 0; i < Arguments.Count; ++i)
3274                                                 if (c.ParameterTypes [i] != ((Argument)Arguments [i]).Type) {
3275                                                         ok = false;
3276                                                         break;
3277                                                 }
3278                                 }
3279
3280                                 if (!ok)
3281                                         continue;
3282
3283                                 return c;
3284                         }
3285
3286                         return null;
3287                 }
3288
3289                 //TODO: implement caching when it will be necessary
3290                 public virtual void CheckObsoleteAttribute (TypeContainer tc, Location loc)
3291                 {
3292                         Constructor ctor = GetOverloadedConstructor (tc);
3293                         if (ctor == null)
3294                                 return;
3295
3296                         ObsoleteAttribute oa = ctor.GetObsoleteAttribute (tc);
3297                         if (oa == null)
3298                                 return;
3299
3300                         AttributeTester.Report_ObsoleteMessage (oa, ctor.GetSignatureForError (), loc);
3301                 }
3302         }
3303
3304         public class ConstructorBaseInitializer : ConstructorInitializer {
3305                 public ConstructorBaseInitializer (ArrayList argument_list, Parameters pars, Location l) :
3306                         base (argument_list, pars, l)
3307                 {
3308                 }
3309
3310                 public override void CheckObsoleteAttribute(TypeContainer tc, Location loc) {
3311                         if (parent_constructor == null)
3312                                 return;
3313
3314                         TypeContainer type_ds = TypeManager.LookupTypeContainer (tc.base_classs_type);
3315                         if (type_ds == null) {
3316                                 ObsoleteAttribute oa = AttributeTester.GetMemberObsoleteAttribute (parent_constructor);
3317
3318                                 if (oa != null)
3319                                         AttributeTester.Report_ObsoleteMessage (oa, TypeManager.CSharpSignature (parent_constructor), loc);
3320
3321                                 return;
3322                         }
3323
3324                         base.CheckObsoleteAttribute (type_ds, loc);
3325                 }
3326
3327         }
3328
3329         public class ConstructorThisInitializer : ConstructorInitializer {
3330                 public ConstructorThisInitializer (ArrayList argument_list, Parameters pars, Location l) :
3331                         base (argument_list, pars, l)
3332                 {
3333                 }
3334         }
3335         
3336         public class Constructor : MethodCore {
3337                 public ConstructorBuilder ConstructorBuilder;
3338                 public ConstructorInitializer Initializer;
3339
3340                 // <summary>
3341                 //   Modifiers allowed for a constructor.
3342                 // </summary>
3343                 public const int AllowedModifiers =
3344                         Modifiers.PUBLIC |
3345                         Modifiers.PROTECTED |
3346                         Modifiers.INTERNAL |
3347                         Modifiers.STATIC |
3348                         Modifiers.UNSAFE |
3349                         Modifiers.EXTERN |              
3350                         Modifiers.PRIVATE;
3351
3352                 bool has_compliant_args = false;
3353                 //
3354                 // The spec claims that static is not permitted, but
3355                 // my very own code has static constructors.
3356                 //
3357                 public Constructor (DeclSpace ds, string name, int mod, Parameters args,
3358                                     ConstructorInitializer init, Location l)
3359                         : base (ds, null, mod, AllowedModifiers, false, name, null, args, l)
3360                 {
3361                         Initializer = init;
3362                 }
3363
3364                 public override string GetSignatureForError()
3365                 {
3366                         return TypeManager.CSharpSignature (ConstructorBuilder);
3367                 }
3368
3369                 public bool HasCompliantArgs {
3370                         get {
3371                                 return has_compliant_args;
3372                         }
3373                 }
3374
3375                 public override AttributeTargets AttributeTargets {
3376                         get {
3377                                 return AttributeTargets.Constructor;
3378                         }
3379                 }
3380
3381
3382                 //
3383                 // Returns true if this is a default constructor
3384                 //
3385                 public bool IsDefault ()
3386                 {
3387                         if ((ModFlags & Modifiers.STATIC) != 0)
3388                                 return  (Parameters.FixedParameters == null ? true : Parameters.Empty) &&
3389                                         (Parameters.ArrayParameter == null ? true : Parameters.Empty);
3390                         
3391                         else
3392                                 return  (Parameters.FixedParameters == null ? true : Parameters.Empty) &&
3393                                         (Parameters.ArrayParameter == null ? true : Parameters.Empty) &&
3394                                         (Initializer is ConstructorBaseInitializer) &&
3395                                         (Initializer.Arguments == null);
3396                 }
3397
3398                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
3399                 {
3400                         ConstructorBuilder.SetCustomAttribute (cb);
3401                 }
3402                 
3403                 protected override bool CheckBase (TypeContainer container)
3404                 {
3405                         base.CheckBase (container);
3406                         
3407                         // Check whether arguments were correct.
3408                         if (!DoDefineParameters ())
3409                                 return false;
3410                         
3411                         if ((ModFlags & Modifiers.STATIC) != 0)
3412                                 return true;
3413                         
3414                         if (container is Struct && ParameterTypes.Length == 0) {
3415                                 Report.Error (568, Location, 
3416                                         "Structs can not contain explicit parameterless " +
3417                                         "constructors");
3418                                 return false;
3419                         }
3420                                 
3421                         //
3422                         // Check in our class for dups
3423                         //
3424                         ArrayList ar = container.InstanceConstructors;
3425                         if (ar != null) {
3426                                 int arLen = ar.Count;
3427                                         
3428                                 for (int i = 0; i < arLen; i++) {
3429                                         Constructor m = (Constructor) ar [i];
3430                                         if (IsDuplicateImplementation (container, m))
3431                                                 return false;
3432                                 }
3433                         }
3434                         
3435                         return true;
3436                 }
3437                 
3438                 //
3439                 // Creates the ConstructorBuilder
3440                 //
3441                 public override bool Define (TypeContainer container)
3442                 {
3443                         MethodAttributes ca = (MethodAttributes.RTSpecialName |
3444                                                MethodAttributes.SpecialName);
3445                         
3446                         if ((ModFlags & Modifiers.STATIC) != 0) {
3447                                 ca |= MethodAttributes.Static | MethodAttributes.Private;
3448                         } else {
3449                                 ca |= MethodAttributes.HideBySig;
3450
3451                                 if ((ModFlags & Modifiers.PUBLIC) != 0)
3452                                         ca |= MethodAttributes.Public;
3453                                 else if ((ModFlags & Modifiers.PROTECTED) != 0){
3454                                         if ((ModFlags & Modifiers.INTERNAL) != 0)
3455                                                 ca |= MethodAttributes.FamORAssem;
3456                                         else 
3457                                                 ca |= MethodAttributes.Family;
3458                                 } else if ((ModFlags & Modifiers.INTERNAL) != 0)
3459                                         ca |= MethodAttributes.Assembly;
3460                                 else if (IsDefault ())
3461                                         ca |= MethodAttributes.Public;
3462                                 else
3463                                         ca |= MethodAttributes.Private;
3464                         }
3465                         
3466                         // Check if arguments were correct.
3467                         if (!CheckBase (container))
3468                                 return false;
3469
3470                         ConstructorBuilder = container.TypeBuilder.DefineConstructor (
3471                                 ca, GetCallingConvention (container is Class), ParameterTypes);
3472
3473                         if ((ModFlags & Modifiers.UNSAFE) != 0)
3474                                 ConstructorBuilder.InitLocals = false;
3475                         
3476                         //
3477                         // HACK because System.Reflection.Emit is lame
3478                         //
3479                         TypeManager.RegisterMethod (ConstructorBuilder, ParameterInfo, ParameterTypes);
3480
3481                         return true;
3482                 }
3483
3484                 //
3485                 // Emits the code
3486                 //
3487                 public override void Emit (TypeContainer container)
3488                 {
3489                         ILGenerator ig = ConstructorBuilder.GetILGenerator ();
3490                         EmitContext ec = new EmitContext (container, Location, ig, null, ModFlags, true);
3491
3492                         //
3493                         // extern methods have no bodies
3494                         //
3495                         if ((ModFlags & Modifiers.EXTERN) != 0) {
3496                                 if ((block != null) && ((ModFlags & Modifiers.EXTERN) != 0)) {
3497                                         Report.Error (
3498                                                 179, Location, "External constructor `" +
3499                                                 TypeManager.CSharpSignature (ConstructorBuilder) +
3500                                                 "' can not have a body");
3501                                         return;
3502                                 }
3503                         } else if (block == null) {
3504                                 Report.Error (
3505                                         501, Location, "Constructor `" +
3506                                         TypeManager.CSharpSignature (ConstructorBuilder) +
3507                                         "' must declare a body since it is not marked extern");
3508                                 return;
3509                         }
3510
3511                         if ((ModFlags & Modifiers.STATIC) == 0){
3512                                 if (container is Class && Initializer == null)
3513                                         Initializer = new ConstructorBaseInitializer (
3514                                                 null, Parameters.EmptyReadOnlyParameters, Location);
3515
3516
3517                                 //
3518                                 // Spec mandates that Initializers will not have
3519                                 // `this' access
3520                                 //
3521                                 ec.IsStatic = true;
3522                                 if (Initializer != null && !Initializer.Resolve (ConstructorBuilder, ec))
3523                                         return;
3524                                 ec.IsStatic = false;
3525                         }
3526
3527                         Parameters.LabelParameters (ec, ConstructorBuilder, Location);
3528                         
3529                         SymbolWriter sw = CodeGen.SymbolWriter;
3530                         bool generate_debugging = false;
3531
3532                         if ((sw != null) && (block != null) &&
3533                                 !Location.IsNull (Location) &&
3534                                 !Location.IsNull (block.EndLocation) &&
3535                                 (Location.SymbolDocument != null)) {
3536                                 sw.OpenMethod (container, ConstructorBuilder, Location, block.EndLocation);
3537
3538                                 generate_debugging = true;
3539                         }
3540
3541                         //
3542                         // Classes can have base initializers and instance field initializers.
3543                         //
3544                         if (container is Class){
3545                                 if ((ModFlags & Modifiers.STATIC) == 0){
3546
3547                                         //
3548                                         // If we use a "this (...)" constructor initializer, then
3549                                         // do not emit field initializers, they are initialized in the other constructor
3550                                         //
3551                                         if (!(Initializer != null && Initializer is ConstructorThisInitializer))
3552                                                 container.EmitFieldInitializers (ec);
3553                                 }
3554                         }
3555                         if (Initializer != null) {
3556                                 Initializer.CheckObsoleteAttribute (container, Location);
3557                                 Initializer.Emit (ec);
3558                         }
3559                         
3560                         if ((ModFlags & Modifiers.STATIC) != 0)
3561                                 container.EmitFieldInitializers (ec);
3562
3563                         if (OptAttributes != null) 
3564                                 OptAttributes.Emit (ec, this);
3565
3566                         // If this is a non-static `struct' constructor and doesn't have any
3567                         // initializer, it must initialize all of the struct's fields.
3568                         if ((container is Struct) && ((ModFlags & Modifiers.STATIC) == 0) && (Initializer == null))
3569                                 Block.AddThisVariable (container, Location);
3570
3571                         ec.EmitTopBlock (block, ParameterInfo, Location);
3572
3573                         if (generate_debugging)
3574                                 sw.CloseMethod ();
3575
3576                         base.Emit (container);
3577
3578                         block = null;
3579                 }
3580
3581                 // For constructors is needed to test only parameters
3582                 protected override bool IsIdentifierClsCompliant (DeclSpace ds)
3583                 {
3584                         if (parameter_types == null || parameter_types.Length == 0)
3585                                 return true;
3586
3587                         TypeContainer tc = ds as TypeContainer;
3588
3589                         for (int i = 0; i < tc.InstanceConstructors.Count; i++) {
3590                                 Constructor c = (Constructor) tc.InstanceConstructors [i];
3591                                                 
3592                                 if (c == this || c.ParameterTypes.Length == 0)
3593                                         continue;
3594
3595                                 if (!c.IsClsCompliaceRequired (ds))
3596                                         continue;
3597                                 
3598                                 if (!AttributeTester.AreOverloadedMethodParamsClsCompliant (parameter_types, c.ParameterTypes)) {
3599                                         Report.Error_T (3006, Location, GetSignatureForError ());
3600                                         return false;
3601                                 }
3602                         }
3603
3604                         if (tc.TypeBuilder.BaseType == null)
3605                                 return true;
3606
3607                         DeclSpace temp_ds = TypeManager.LookupDeclSpace (tc.TypeBuilder.BaseType);
3608                         if (temp_ds != null)
3609                                 return IsIdentifierClsCompliant (temp_ds);
3610
3611                         MemberInfo[] ml = tc.TypeBuilder.BaseType.FindMembers (MemberTypes.Constructor, BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance, null, null);
3612                         // Skip parameter-less ctor
3613                         if (ml.Length < 2)
3614                                 return true;
3615
3616                         foreach (ConstructorInfo ci in ml) {
3617                                 object[] cls_attribute = ci.GetCustomAttributes (TypeManager.cls_compliant_attribute_type, false);
3618                                 if (cls_attribute.Length == 1 && (!((CLSCompliantAttribute)cls_attribute[0]).IsCompliant))
3619                                         continue;
3620
3621                                 if (!AttributeTester.AreOverloadedMethodParamsClsCompliant (parameter_types, TypeManager.GetArgumentTypes (ci))) {
3622                                         Report.Error_T (3006, Location, GetSignatureForError ());
3623                                         return false;
3624                                 }
3625                         }
3626                         
3627                         return true;
3628                 }
3629
3630                 protected override bool VerifyClsCompliance (DeclSpace ds)
3631                 {
3632                         if (!base.VerifyClsCompliance (ds) || !IsExposedFromAssembly (ds)) {
3633                                 return false;
3634                         }
3635                         
3636                         if (ds.TypeBuilder.IsSubclassOf (TypeManager.attribute_type)) {
3637                                 foreach (Type param in parameter_types) {
3638                                         if (param.IsArray) {
3639                                                 return false;
3640                                         }
3641                                 }
3642                         }
3643                         has_compliant_args = true;
3644                         return true;
3645                 }
3646
3647         }
3648
3649         /// <summary>
3650         /// Interface for MethodData class. Holds links to parent members to avoid member duplication.
3651         /// </summary>
3652         public interface IMethodData
3653         {
3654                 CallingConventions CallingConventions { get; }
3655                 Location Location { get; }
3656                 string MethodName { get; }
3657                 Type[] ParameterTypes { get; }
3658                 Type ReturnType { get; }
3659
3660                 Attributes OptAttributes { get; }
3661                 Block Block { get; }
3662
3663                 EmitContext CreateEmitContext (TypeContainer tc, ILGenerator ig);
3664                 ObsoleteAttribute GetObsoleteAttribute ();
3665                 string GetSignatureForError (TypeContainer tc);
3666                 bool IsExcluded (EmitContext ec);
3667         }
3668
3669         //
3670         // Encapsulates most of the Method's state
3671         //
3672         public class MethodData {
3673
3674                 readonly IMethodData method;
3675
3676                 //
3677                 // The return type of this method
3678                 //
3679                 public readonly InternalParameters ParameterInfo;
3680
3681                 //
3682                 // Are we implementing an interface ?
3683                 //
3684                 public bool IsImplementing = false;
3685
3686                 //
3687                 // Protected data.
3688                 //
3689                 protected MemberBase member;
3690                 protected int modifiers;
3691                 protected MethodAttributes flags;
3692
3693                 MethodBuilder builder = null;
3694                 public MethodBuilder MethodBuilder {
3695                         get {
3696                                 return builder;
3697                         }
3698                 }
3699
3700                 public MethodData (MemberBase member, InternalParameters parameters,
3701                                    int modifiers, MethodAttributes flags, IMethodData method)
3702                 {
3703                         this.member = member;
3704                         this.ParameterInfo = parameters;
3705                         this.modifiers = modifiers;
3706                         this.flags = flags;
3707
3708                         this.method = method;
3709                 }
3710
3711                 public bool Define (TypeContainer container)
3712                 {
3713                         MethodInfo implementing = null;
3714                         string prefix;
3715
3716                         if (member.IsExplicitImpl)
3717                                 prefix = member.InterfaceType.FullName + ".";
3718                         else
3719                                 prefix = "";
3720
3721                         string name = method.MethodName;
3722                         string method_name = prefix + name;
3723                         Type[] ParameterTypes = method.ParameterTypes;
3724
3725                         if (container.Pending != null){
3726                                 if (member is Indexer)
3727                                         implementing = container.Pending.IsInterfaceIndexer (
3728                                                 member.InterfaceType, method.ReturnType, ParameterTypes);
3729                                 else
3730                                         implementing = container.Pending.IsInterfaceMethod (
3731                                                 member.InterfaceType, name, method.ReturnType, ParameterTypes);
3732
3733                                 if (member.InterfaceType != null && implementing == null){
3734                                         Report.Error (539, method.Location, "'{0}' in explicit interface declaration is not an interface", method_name);
3735                                         return false;
3736                                 }
3737                         }
3738
3739                         //
3740                         // For implicit implementations, make sure we are public, for
3741                         // explicit implementations, make sure we are private.
3742                         //
3743                         if (implementing != null){
3744                                 //
3745                                 // Setting null inside this block will trigger a more
3746                                 // verbose error reporting for missing interface implementations
3747                                 //
3748                                 // The "candidate" function has been flagged already
3749                                 // but it wont get cleared
3750                                 //
3751                                 if (member.IsExplicitImpl){
3752                                         if ((modifiers & (Modifiers.PUBLIC | Modifiers.ABSTRACT | Modifiers.VIRTUAL)) != 0){
3753                                                 Modifiers.Error_InvalidModifier (method.Location, "public, virtual or abstract");
3754                                                 implementing = null;
3755                                         }
3756                                 } else if ((flags & MethodAttributes.MemberAccessMask) != MethodAttributes.Public){
3757                                         if (TypeManager.IsInterfaceType (implementing.DeclaringType)){
3758                                                 //
3759                                                 // If this is an interface method implementation,
3760                                                 // check for public accessibility
3761                                                 //
3762                                                 implementing = null;
3763                                         } else if ((flags & MethodAttributes.MemberAccessMask) == MethodAttributes.Private){
3764                                                 // We may never be private.
3765                                                 implementing = null;
3766                                         } else if ((modifiers & Modifiers.OVERRIDE) == 0){
3767                                                 //
3768                                                 // We may be protected if we're overriding something.
3769                                                 //
3770                                                 implementing = null;
3771                                         }
3772                                 } 
3773                                         
3774                                 //
3775                                 // Static is not allowed
3776                                 //
3777                                 if ((modifiers & Modifiers.STATIC) != 0){
3778                                         implementing = null;
3779                                         Modifiers.Error_InvalidModifier (method.Location, "static");
3780                                 }
3781                         }
3782                         
3783                         //
3784                         // If implementing is still valid, set flags
3785                         //
3786                         if (implementing != null){
3787                                 //
3788                                 // When implementing interface methods, set NewSlot
3789                                 // unless, we are overwriting a method.
3790                                 //
3791                                 if (implementing.DeclaringType.IsInterface){
3792                                         if ((modifiers & Modifiers.OVERRIDE) == 0)
3793                                                 flags |= MethodAttributes.NewSlot;
3794                                 }
3795                                 flags |=
3796                                         MethodAttributes.Virtual |
3797                                         MethodAttributes.HideBySig;
3798
3799                                 // Set Final unless we're virtual, abstract or already overriding a method.
3800                                 if ((modifiers & (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE)) == 0)
3801                                         flags |= MethodAttributes.Final;
3802
3803                                 // Get the method name from the explicit interface.
3804                                 if (member.InterfaceType != null) {
3805                                         name = implementing.Name;
3806                                         method_name = prefix + name;
3807                                 }
3808
3809                                 IsImplementing = true;
3810                         }
3811
3812                         EmitContext ec = method.CreateEmitContext (container, null);
3813
3814                         DefineMethodBuilder (ec, container, method_name, ParameterTypes);
3815
3816                         if (builder == null)
3817                                 return false;
3818
3819                         if ((modifiers & Modifiers.UNSAFE) != 0)
3820                                 builder.InitLocals = false;
3821
3822                         if (IsImplementing){
3823                                 //
3824                                 // clear the pending implemntation flag
3825                                 //
3826                                 if (member is Indexer) {
3827                                         container.Pending.ImplementIndexer (
3828                                                 member.InterfaceType, builder, method.ReturnType,
3829                                                 ParameterTypes, true);
3830                                 } else
3831                                         container.Pending.ImplementMethod (
3832                                                 member.InterfaceType, name, method.ReturnType,
3833                                                 ParameterTypes, member.IsExplicitImpl);
3834
3835                                 if (member.IsExplicitImpl)
3836                                         container.TypeBuilder.DefineMethodOverride (
3837                                                 builder, implementing);
3838
3839                         }
3840
3841                         if (!TypeManager.RegisterMethod (builder, ParameterInfo, ParameterTypes)) {
3842                                 Report.Error (111, method.Location,
3843                                               "Class `" + container.Name +
3844                                               "' already contains a definition with the " +
3845                                               "same return value and parameter types as the " +
3846                                               "'get' method of property `" + member.Name + "'");
3847                                 return false;
3848                         }
3849
3850                         TypeManager.AddMethod (builder, method);
3851
3852                         return true;
3853                 }
3854
3855
3856                 /// <summary>
3857                 /// Create the MethodBuilder for the method 
3858                 /// </summary>
3859                 void DefineMethodBuilder (EmitContext ec, TypeContainer container, string method_name, Type[] ParameterTypes)
3860                 {
3861                         const int extern_static = Modifiers.EXTERN | Modifiers.STATIC;
3862
3863                         if ((modifiers & extern_static) == extern_static) {
3864
3865                                 if (method.OptAttributes != null) {
3866                                         Attribute dllimport_attribute = method.OptAttributes.Search (TypeManager.dllimport_type, ec);
3867                                         if (dllimport_attribute != null) {
3868                                                 flags |= MethodAttributes.PinvokeImpl;
3869                                                 builder = dllimport_attribute.DefinePInvokeMethod (
3870                                                         ec, container.TypeBuilder, method_name, flags,
3871                                                         method.ReturnType, ParameterTypes);
3872
3873                                                 return;
3874                                         }
3875                                 }
3876
3877                                 // for extern static method must be specified either DllImport attribute or MethodImplAttribute.
3878                                 // We are more strict than Microsoft and report CS0626 like error
3879                                 if (method.OptAttributes == null ||
3880                                         !method.OptAttributes.Contains (TypeManager.methodimpl_attr_type, ec)) {
3881                                         //"Method, operator, or accessor '{0}' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation"
3882                                         Report.Error_T (626, method.Location, method.GetSignatureForError (container));
3883                                         return;
3884                                 }
3885                         }
3886
3887                         builder = container.TypeBuilder.DefineMethod (
3888                                 method_name, flags, method.CallingConventions,
3889                                 method.ReturnType, ParameterTypes);
3890                 }
3891
3892                 //
3893                 // Emits the code
3894                 // 
3895                 public void Emit (TypeContainer container, Attributable kind)
3896                 {
3897                         EmitContext ec;
3898
3899                         if ((flags & MethodAttributes.PinvokeImpl) == 0)
3900                                 ec = method.CreateEmitContext (container, builder.GetILGenerator ());
3901                         else
3902                                 ec = method.CreateEmitContext (container, null);
3903
3904                         Location loc = method.Location;
3905                         Attributes OptAttributes = method.OptAttributes;
3906
3907                         if (OptAttributes != null)
3908                                 OptAttributes.Emit (ec, kind);
3909
3910                         if (member is MethodCore)
3911                                 ((MethodCore) member).Parameters.LabelParameters (ec, MethodBuilder, loc);
3912
3913                         SymbolWriter sw = CodeGen.SymbolWriter;
3914                         Block block = method.Block;
3915                         
3916                         //
3917                         // abstract or extern methods have no bodies
3918                         //
3919                         if ((modifiers & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0){
3920                                 if (block == null) {
3921                                         if ((sw != null) && ((modifiers & Modifiers.EXTERN) != 0) &&
3922                                             !Location.IsNull (loc) &&
3923                                             (method.Location.SymbolDocument != null)) {
3924                                                 sw.OpenMethod (container, MethodBuilder, loc, loc);
3925                                                 sw.CloseMethod ();
3926                                         }
3927
3928                                         return;
3929                                 }
3930
3931                                 //
3932                                 // abstract or extern methods have no bodies.
3933                                 //
3934                                 if ((modifiers & Modifiers.ABSTRACT) != 0)
3935                                         Report.Error (
3936                                                 500, method.Location, "Abstract method `" +
3937                                                 TypeManager.CSharpSignature (builder) +
3938                                                 "' can not have a body");
3939
3940                                 if ((modifiers & Modifiers.EXTERN) != 0)
3941                                         Report.Error (
3942                                                 179, method.Location, "External method `" +
3943                                                 TypeManager.CSharpSignature (builder) +
3944                                                 "' can not have a body");
3945
3946                                 return;
3947                         }
3948
3949                         //
3950                         // Methods must have a body unless they're extern or abstract
3951                         //
3952                         if (block == null) {
3953                                 Report.Error (
3954                                         501, method.Location, "Method `" +
3955                                         TypeManager.CSharpSignature (builder) +
3956                                         "' must declare a body since it is not marked " +
3957                                         "abstract or extern");
3958                                 return;
3959                         }
3960
3961                         //
3962                         // Handle destructors specially
3963                         //
3964                         // FIXME: This code generates buggy code
3965                         //
3966                         if ((sw != null) && !Location.IsNull (loc) &&
3967                             !Location.IsNull (block.EndLocation) &&
3968                             (loc.SymbolDocument != null)) {
3969                                 sw.OpenMethod (container, MethodBuilder, loc, block.EndLocation);
3970
3971                                 if (member is Destructor)
3972                                         EmitDestructor (ec, block);
3973                                 else
3974                                         ec.EmitTopBlock (block, ParameterInfo, loc);
3975
3976                                 sw.CloseMethod ();
3977                         } else {
3978                                 if (member is Destructor)
3979                                         EmitDestructor (ec, block);
3980                                 else
3981                                         ec.EmitTopBlock (block, ParameterInfo, loc);
3982                         }
3983                 }
3984
3985                 void EmitDestructor (EmitContext ec, Block block)
3986                 {
3987                         ILGenerator ig = ec.ig;
3988                         
3989                         Label finish = ig.DefineLabel ();
3990
3991                         block.SetDestructor ();
3992                         
3993                         ig.BeginExceptionBlock ();
3994                         ec.ReturnLabel = finish;
3995                         ec.HasReturnLabel = true;
3996                         ec.EmitTopBlock (block, null, method.Location);
3997                         
3998                         // ig.MarkLabel (finish);
3999                         ig.BeginFinallyBlock ();
4000                         
4001                         if (ec.ContainerType.BaseType != null) {
4002                                 Expression member_lookup = Expression.MemberLookup (
4003                                         ec, ec.ContainerType.BaseType, null, ec.ContainerType.BaseType,
4004                                         "Finalize", MemberTypes.Method, Expression.AllBindingFlags, method.Location);
4005
4006                                 if (member_lookup != null){
4007                                         MethodGroupExpr parent_destructor = ((MethodGroupExpr) member_lookup);
4008                                 
4009                                         ig.Emit (OpCodes.Ldarg_0);
4010                                         ig.Emit (OpCodes.Call, (MethodInfo) parent_destructor.Methods [0]);
4011                                 }
4012                         }
4013                         
4014                         ig.EndExceptionBlock ();
4015                         //ig.MarkLabel (ec.ReturnLabel);
4016                         ig.Emit (OpCodes.Ret);
4017                 }
4018         }
4019
4020         public class Destructor : Method {
4021
4022                 public Destructor (DeclSpace ds, Expression return_type, int mod, string name,
4023                                    Parameters parameters, Attributes attrs, Location l)
4024                         : base (ds, return_type, mod, false, name, parameters, attrs, l)
4025                 { }
4026
4027                 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
4028                 {
4029                         if (a.Type == TypeManager.conditional_attribute_type) {
4030                                 // Conditional not valid on '{0}' because it is a destructor, operator, or explicit interface implementation
4031                                 Report.Error_T (577, Location, GetSignatureForError ());
4032                                 return;
4033                         }
4034
4035                         base.ApplyAttributeBuilder (a, cb);
4036                 }
4037         }
4038         
4039         abstract public class MemberBase : MemberCore {
4040                 public Expression Type;
4041
4042                 public MethodAttributes flags;
4043                         
4044                 protected readonly int explicit_mod_flags;
4045
4046                 //
4047                 // The "short" name of this property / indexer / event.  This is the
4048                 // name without the explicit interface.
4049                 //
4050                 public string ShortName;
4051
4052                 //
4053                 // The type of this property / indexer / event
4054                 //
4055                 public Type MemberType;
4056
4057                 //
4058                 // If true, this is an explicit interface implementation
4059                 //
4060                 public bool IsExplicitImpl = false;
4061
4062                 //
4063                 // The name of the interface we are explicitly implementing
4064                 //
4065                 public string ExplicitInterfaceName = null;
4066
4067                 //
4068                 // Whether this is an interface member.
4069                 //
4070                 public bool IsInterface;
4071
4072                 //
4073                 // If true, the interface type we are explicitly implementing
4074                 //
4075                 public Type InterfaceType = null;
4076
4077                 //
4078                 // The method we're overriding if this is an override method.
4079                 //
4080                 protected MethodInfo parent_method = null;
4081                 public MethodInfo ParentMethod {
4082                         get {
4083                                 return parent_method;
4084                         }
4085                 }
4086
4087                 //
4088                 // The constructor is only exposed to our children
4089                 //
4090                 protected MemberBase (Expression type, int mod, int allowed_mod, int def_mod, string name,
4091                                       Attributes attrs, Location loc)
4092                         : base (name, attrs, loc)
4093                 {
4094                         explicit_mod_flags = mod;
4095                         Type = type;
4096                         ModFlags = Modifiers.Check (allowed_mod, mod, def_mod, loc);
4097                 }
4098
4099                 protected virtual bool CheckBase (TypeContainer container)
4100                 {
4101                         if ((container is Struct) || (RootContext.WarningLevel > 3)){
4102                                 if ((ModFlags & Modifiers.PROTECTED) != 0 && (container.ModFlags & Modifiers.SEALED) != 0){
4103                                         if (container is Struct){
4104                                                 Report.Error (666, Location, "Protected member in struct declaration");
4105                                                 return false;
4106                                         } else
4107                                                 Report.Warning (628, Location, "Member " + container.MakeName (Name) + " protected in sealed class");
4108                                 }
4109                         }
4110                         return true;
4111                 }
4112
4113                 protected void WarningNotHiding (TypeContainer parent)
4114                 {
4115                         Report.Warning (
4116                                 109, Location,
4117                                 "The member " + parent.MakeName (Name) + " does not hide an " +
4118                                 "inherited member.  The keyword new is not required");
4119                                                            
4120                 }
4121
4122                 void Error_CannotChangeAccessModifiers (TypeContainer parent, MethodInfo parent_method,
4123                                                         string name)
4124                 {
4125                         //
4126                         // FIXME: report the old/new permissions?
4127                         //
4128                         Report.Error (
4129                                 507, Location, parent.MakeName (Name) +
4130                                 ": can't change the access modifiers when overriding inherited " +
4131                                 "member `" + name + "'");
4132                 }
4133                 
4134                 //
4135                 // Performs various checks on the MethodInfo `mb' regarding the modifier flags
4136                 // that have been defined.
4137                 //
4138                 // `name' is the user visible name for reporting errors (this is used to
4139                 // provide the right name regarding method names and properties)
4140                 //
4141                 protected bool CheckMethodAgainstBase (TypeContainer parent, MethodAttributes my_attrs,
4142                                                        MethodInfo mb, string name)
4143                 {
4144                         bool ok = true;
4145                         
4146                         if ((ModFlags & Modifiers.OVERRIDE) != 0){
4147                                 if (!(mb.IsAbstract || mb.IsVirtual)){
4148                                         Report.Error (
4149                                                 506, Location, parent.MakeName (Name) +
4150                                                 ": cannot override inherited member `" +
4151                                                 name + "' because it is not " +
4152                                                 "virtual, abstract or override");
4153                                         ok = false;
4154                                 }
4155                                 
4156                                 // Now we check that the overriden method is not final
4157                                 
4158                                 if (mb.IsFinal) {
4159                                         // This happens when implementing interface methods.
4160                                         if (mb.IsHideBySig && mb.IsVirtual) {
4161                                                 Report.Error (
4162                                                         506, Location, parent.MakeName (Name) +
4163                                                         ": cannot override inherited member `" +
4164                                                         name + "' because it is not " +
4165                                                         "virtual, abstract or override");
4166                                         } else
4167                                                 Report.Error (239, Location, parent.MakeName (Name) + " : cannot " +
4168                                                               "override inherited member `" + name +
4169                                                               "' because it is sealed.");
4170                                         ok = false;
4171                                 }
4172                                 //
4173                                 // Check that the permissions are not being changed
4174                                 //
4175                                 MethodAttributes thisp = my_attrs & MethodAttributes.MemberAccessMask;
4176                                 MethodAttributes parentp = mb.Attributes & MethodAttributes.MemberAccessMask;
4177
4178                                 //
4179                                 // special case for "protected internal"
4180                                 //
4181
4182                                 if ((parentp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
4183                                         //
4184                                         // when overriding protected internal, the method can be declared
4185                                         // protected internal only within the same assembly
4186                                         //
4187
4188                                         if ((thisp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
4189                                                 if (parent.TypeBuilder.Assembly != mb.DeclaringType.Assembly){
4190                                                         //
4191                                                         // assemblies differ - report an error
4192                                                         //
4193                                                         
4194                                                         Error_CannotChangeAccessModifiers (parent, mb, name);
4195                                                     ok = false;
4196                                                 } else if (thisp != parentp) {
4197                                                         //
4198                                                         // same assembly, but other attributes differ - report an error
4199                                                         //
4200                                                         
4201                                                         Error_CannotChangeAccessModifiers (parent, mb, name);
4202                                                         ok = false;
4203                                                 };
4204                                         } else if ((thisp & MethodAttributes.Family) != MethodAttributes.Family) {
4205                                                 //
4206                                                 // if it's not "protected internal", it must be "protected"
4207                                                 //
4208
4209                                                 Error_CannotChangeAccessModifiers (parent, mb, name);
4210                                                 ok = false;
4211                                         } else if (parent.TypeBuilder.Assembly == mb.DeclaringType.Assembly) {
4212                                                 //
4213                                                 // protected within the same assembly - an error
4214                                                 //
4215                                                 Error_CannotChangeAccessModifiers (parent, mb, name);
4216                                                 ok = false;
4217                                         } else if ((thisp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem)) != 
4218                                                    (parentp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem))) {
4219                                                 //
4220                                                 // protected ok, but other attributes differ - report an error
4221                                                 //
4222                                                 Error_CannotChangeAccessModifiers (parent, mb, name);
4223                                                 ok = false;
4224                                         }
4225                                 } else {
4226                                         if (thisp != parentp){
4227                                                 Error_CannotChangeAccessModifiers (parent, mb, name);
4228                                                 ok = false;
4229                                         }
4230                                 }
4231                         }
4232
4233                         if (mb.IsVirtual || mb.IsAbstract){
4234                                 if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE)) == 0){
4235                                         if (Name != "Finalize"){
4236                                                 Report.Warning (
4237                                                         114, 2, Location, parent.MakeName (Name) + 
4238                                                         " hides inherited member `" + name +
4239                                                         "'.  To make the current member override that " +
4240                                                         "implementation, add the override keyword, " +
4241                                                         "otherwise use the new keyword");
4242                                                 ModFlags |= Modifiers.NEW;
4243                                         }
4244                                 }
4245                         } else {
4246                                 if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE)) == 0){
4247                                         if (Name != "Finalize"){
4248                                                 Report.Warning (
4249                                                         108, 1, Location, "The keyword new is required on " +
4250                                                         parent.MakeName (Name) + " because it hides " +
4251                                                         "inherited member `" + name + "'");
4252                                                 ModFlags |= Modifiers.NEW;
4253                                         }
4254                                 }
4255                         }
4256
4257                         return ok;
4258                 }
4259
4260                 protected virtual bool CheckParameters (DeclSpace ds, Type [] parameters)
4261                 {
4262                         bool error = false;
4263
4264                         foreach (Type partype in parameters){
4265                                 if (partype == TypeManager.void_type) {
4266                                         Report.Error (
4267                                                 1547, Location, "Keyword 'void' cannot " +
4268                                                 "be used in this context");
4269                                         return false;
4270                                 }
4271
4272                                 if (partype.IsPointer){
4273                                         if (!UnsafeOK (ds))
4274                                                 error = true;
4275                                         if (!TypeManager.VerifyUnManaged (TypeManager.GetElementType (partype), Location))
4276                                                 error = true;
4277                                 }
4278
4279                                 if (ds.AsAccessible (partype, ModFlags))
4280                                         continue;
4281
4282                                 if (this is Indexer)
4283                                         Report.Error (55, Location,
4284                                                       "Inconsistent accessibility: parameter type `" +
4285                                                       TypeManager.CSharpName (partype) + "' is less " +
4286                                                       "accessible than indexer `" + Name + "'");
4287                                 else if ((this is Method) && ((Method) this).IsOperator)
4288                                         Report.Error (57, Location,
4289                                                       "Inconsistent accessibility: parameter type `" +
4290                                                       TypeManager.CSharpName (partype) + "' is less " +
4291                                                       "accessible than operator `" + Name + "'");
4292                                 else
4293                                         Report.Error (51, Location,
4294                                                       "Inconsistent accessibility: parameter type `" +
4295                                                       TypeManager.CSharpName (partype) + "' is less " +
4296                                                       "accessible than method `" + Name + "'");
4297                                 error = true;
4298                         }
4299
4300                         return !error;
4301                 }
4302
4303                 protected virtual bool DoDefine (TypeContainer container)
4304                 {
4305                         if (Name == null)
4306                                 Name = "this";
4307
4308                         if (IsInterface) {
4309                                 ModFlags = Modifiers.PUBLIC |
4310                                         Modifiers.ABSTRACT |
4311                                         Modifiers.VIRTUAL | (ModFlags & Modifiers.UNSAFE);
4312
4313                                 flags = MethodAttributes.Public |
4314                                         MethodAttributes.Abstract |
4315                                         MethodAttributes.HideBySig |
4316                                         MethodAttributes.NewSlot |
4317                                         MethodAttributes.Virtual;
4318                         } else {
4319                                 if (!container.MethodModifiersValid (ModFlags, Name, Location))
4320                                         return false;
4321
4322                                 flags = Modifiers.MethodAttr (ModFlags);
4323                         }
4324
4325                         // Lookup Type, verify validity
4326                         MemberType = container.ResolveType (Type, false, Location);
4327                         if (MemberType == null)
4328                                 return false;
4329
4330                         if ((container.ModFlags & Modifiers.SEALED) != 0){
4331                                 if ((ModFlags & (Modifiers.VIRTUAL|Modifiers.ABSTRACT)) != 0){
4332                                         Report.Error (549, Location, "Virtual method can not be contained in sealed class");
4333                                         return false;
4334                                 }
4335                         }
4336                         
4337                         // verify accessibility
4338                         if (!container.AsAccessible (MemberType, ModFlags)) {
4339                                 if (this is Property)
4340                                         Report.Error (53, Location,
4341                                                       "Inconsistent accessibility: property type `" +
4342                                                       TypeManager.CSharpName (MemberType) + "' is less " +
4343                                                       "accessible than property `" + Name + "'");
4344                                 else if (this is Indexer)
4345                                         Report.Error (54, Location,
4346                                                       "Inconsistent accessibility: indexer return type `" +
4347                                                       TypeManager.CSharpName (MemberType) + "' is less " +
4348                                                       "accessible than indexer `" + Name + "'");
4349                                 else if (this is Method) {
4350                                         if (((Method) this).IsOperator)
4351                                                 Report.Error (56, Location,
4352                                                               "Inconsistent accessibility: return type `" +
4353                                                               TypeManager.CSharpName (MemberType) + "' is less " +
4354                                                               "accessible than operator `" + Name + "'");
4355                                         else
4356                                                 Report.Error (50, Location,
4357                                                               "Inconsistent accessibility: return type `" +
4358                                                               TypeManager.CSharpName (MemberType) + "' is less " +
4359                                                               "accessible than method `" + Name + "'");
4360                                 } else
4361                                         Report.Error (52, Location,
4362                                                       "Inconsistent accessibility: field type `" +
4363                                                       TypeManager.CSharpName (MemberType) + "' is less " +
4364                                                       "accessible than field `" + Name + "'");
4365                                 return false;
4366                         }
4367
4368                         if (MemberType.IsPointer && !UnsafeOK (container))
4369                                 return false;
4370                         
4371                         //
4372                         // Check for explicit interface implementation
4373                         //
4374                         if ((ExplicitInterfaceName == null) && (Name.IndexOf ('.') != -1)){
4375                                 int pos = Name.LastIndexOf ('.');
4376
4377                                 ExplicitInterfaceName = Name.Substring (0, pos);
4378                                 ShortName = Name.Substring (pos + 1);
4379                         } else
4380                                 ShortName = Name;
4381
4382                         if (ExplicitInterfaceName != null) {
4383                                 InterfaceType  = container.FindType (
4384                                         Location, ExplicitInterfaceName);
4385                                 if (InterfaceType == null)
4386                                         return false;
4387
4388                                 if (InterfaceType.IsClass) {
4389                                         Report.Error (538, Location, "'{0}' in explicit interface declaration is not an interface", ExplicitInterfaceName);
4390                                         return false;
4391                                 }
4392
4393                                 // Compute the full name that we need to export.
4394                                 Name = InterfaceType.FullName + "." + ShortName;
4395                                 
4396                                 if (!container.VerifyImplements (InterfaceType, ShortName, Name, Location))
4397                                         return false;
4398                                 
4399                                 Modifiers.Check (Modifiers.AllowedExplicitImplFlags, explicit_mod_flags, 0, Location);
4400                                 
4401                                 IsExplicitImpl = true;
4402                         } else
4403                                 IsExplicitImpl = false;
4404
4405                         return true;
4406                 }
4407
4408                 /// <summary>
4409                 /// Use this method when MethodBuilder is null
4410                 /// </summary>
4411                 public virtual string GetSignatureForError (TypeContainer tc)
4412                 {
4413                         return String.Concat (tc.Name, '.', Name);
4414                 }
4415
4416                 protected override bool IsIdentifierClsCompliant (DeclSpace ds)
4417                 {
4418                         return IsIdentifierAndParamClsCompliant (ds, Name, null, null);
4419                 }
4420
4421                 protected override bool VerifyClsCompliance(DeclSpace ds)
4422                 {
4423                         if (base.VerifyClsCompliance (ds)) {
4424                                 return true;
4425                         }
4426
4427                         if (IsInterface && HasClsCompliantAttribute && ds.IsClsCompliaceRequired (ds)) {
4428                                 Report.Error_T (3010, Location, GetSignatureForError ());
4429                         }
4430                         return false;
4431                 }
4432
4433                 protected override void VerifyObsoleteAttribute()
4434                 {
4435                         CheckUsageOfObsoleteAttribute (MemberType);
4436                 }
4437         }
4438
4439         //
4440         // Fields and Events both generate FieldBuilders, we use this to share 
4441         // their common bits.  This is also used to flag usage of the field
4442         //
4443         abstract public class FieldBase : MemberBase {
4444                 public FieldBuilder  FieldBuilder;
4445                 public Status status;
4446
4447                 [Flags]
4448                 public enum Status : byte { ASSIGNED = 1, USED = 2 }
4449
4450                 static string[] attribute_targets = new string [] { "field" };
4451
4452                 //
4453                 // The constructor is only exposed to our children
4454                 //
4455                 protected FieldBase (Expression type, int mod, int allowed_mod, string name,
4456                                      object init, Attributes attrs, Location loc)
4457                         : base (type, mod, allowed_mod, Modifiers.PRIVATE, name, attrs, loc)
4458                 {
4459                         this.init = init;
4460                 }
4461
4462                 public override AttributeTargets AttributeTargets {
4463                         get {
4464                                 return AttributeTargets.Field;
4465                         }
4466                 }
4467
4468                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
4469                 {
4470                         if (a.Type == TypeManager.marshal_as_attr_type) {
4471                                 UnmanagedMarshal marshal = a.GetMarshal ();
4472                                 if (marshal != null) {
4473                                         FieldBuilder.SetMarshal (marshal);
4474                                         return;
4475                                 }
4476                                 Report.Warning_T (-24, a.Location);
4477                                 return;
4478                         }
4479
4480                         
4481                         FieldBuilder.SetCustomAttribute (cb);
4482                 }
4483
4484                 //
4485                 // Whether this field has an initializer.
4486                 //
4487                 public bool HasInitializer {
4488                         get {
4489                                 return init != null;
4490                         }
4491                 }
4492
4493                 protected readonly Object init;
4494                 // Private.
4495                 Expression init_expr;
4496                 bool init_expr_initialized = false;
4497
4498                 //
4499                 // Resolves and returns the field initializer.
4500                 //
4501                 public Expression GetInitializerExpression (EmitContext ec)
4502                 {
4503                         if (init_expr_initialized)
4504                                 return init_expr;
4505
4506                         Expression e;
4507                         if (init is Expression)
4508                                 e = (Expression) init;
4509                         else
4510                                 e = new ArrayCreation (Type, "", (ArrayList)init, Location);
4511
4512                         ec.IsFieldInitializer = true;
4513                         e = e.DoResolve (ec);
4514                         ec.IsFieldInitializer = false;
4515
4516                         init_expr = e;
4517                         init_expr_initialized = true;
4518
4519                         return init_expr;
4520                 }
4521
4522                 protected override bool DoDefine (TypeContainer container)
4523                 {
4524                         if (!base.DoDefine (container))
4525                                 return false;
4526
4527                         if (MemberType == TypeManager.void_type) {
4528                                 Report.Error (1547, Location,
4529                                               "Keyword 'void' cannot be used in this context");
4530                                 return false;
4531                         }
4532
4533                         if (MemberType == TypeManager.arg_iterator_type || MemberType == TypeManager.typed_reference_type) {
4534                                 // "Field or property cannot be of type '{0}'";
4535                                 Report.Error_T (610, Location, TypeManager.CSharpName (MemberType));
4536                                 return false;
4537                         }
4538
4539                         return true;
4540                 }
4541
4542                 public override string GetSignatureForError ()
4543                 {
4544                         return TypeManager.GetFullNameSignature (FieldBuilder);
4545                 }
4546
4547                 protected override string[] ValidAttributeTargets {
4548                         get {
4549                                 return attribute_targets;
4550                         }
4551                 }
4552
4553                 protected override bool VerifyClsCompliance (DeclSpace ds)
4554                 {
4555                         if (!base.VerifyClsCompliance (ds))
4556                                 return false;
4557
4558                         if (FieldBuilder == null) {
4559                                 return true;
4560                         }
4561
4562                         if (!AttributeTester.IsClsCompliant (FieldBuilder.FieldType)) {
4563                                 Report.Error_T (3003, Location, GetSignatureForError ());
4564                         }
4565                         return true;
4566                 }
4567
4568
4569                 public void SetAssigned ()
4570                 {
4571                         status |= Status.ASSIGNED;
4572                 }
4573         }
4574
4575         //
4576         // The Field class is used to represents class/struct fields during parsing.
4577         //
4578         public class Field : FieldBase {
4579                 // <summary>
4580                 //   Modifiers allowed in a class declaration
4581                 // </summary>
4582                 const int AllowedModifiers =
4583                         Modifiers.NEW |
4584                         Modifiers.PUBLIC |
4585                         Modifiers.PROTECTED |
4586                         Modifiers.INTERNAL |
4587                         Modifiers.PRIVATE |
4588                         Modifiers.STATIC |
4589                         Modifiers.VOLATILE |
4590                         Modifiers.UNSAFE |
4591                         Modifiers.READONLY;
4592
4593                 public Field (Expression type, int mod, string name, Object expr_or_array_init,
4594                               Attributes attrs, Location loc)
4595                         : base (type, mod, AllowedModifiers, name, expr_or_array_init, attrs, loc)
4596                 {
4597                 }
4598
4599                 public override bool Define (TypeContainer container)
4600                 {
4601                         MemberType = container.ResolveType (Type, false, Location);
4602                         
4603                         if (MemberType == null)
4604                                 return false;
4605
4606                         CheckBase (container);
4607                         
4608                         if (!container.AsAccessible (MemberType, ModFlags)) {
4609                                 Report.Error (52, Location,
4610                                               "Inconsistent accessibility: field type `" +
4611                                               TypeManager.CSharpName (MemberType) + "' is less " +
4612                                               "accessible than field `" + Name + "'");
4613                                 return false;
4614                         }
4615
4616                         if (MemberType.IsPointer && !UnsafeOK (container))
4617                                 return false;
4618                         
4619                         if (RootContext.WarningLevel > 1){
4620                                 Type ptype = container.TypeBuilder.BaseType;
4621
4622                                 // ptype is only null for System.Object while compiling corlib.
4623                                 if (ptype != null){
4624                                         TypeContainer.FindMembers (
4625                                                 ptype, MemberTypes.Method,
4626                                                 BindingFlags.Public |
4627                                                 BindingFlags.Static | BindingFlags.Instance,
4628                                                 System.Type.FilterName, Name);
4629                                 }
4630                         }
4631
4632                         if ((ModFlags & Modifiers.VOLATILE) != 0){
4633                                 if (!MemberType.IsClass){
4634                                         Type vt = MemberType;
4635                                         
4636                                         if (TypeManager.IsEnumType (vt))
4637                                                 vt = TypeManager.EnumToUnderlying (MemberType);
4638
4639                                         if (!((vt == TypeManager.bool_type) ||
4640                                               (vt == TypeManager.sbyte_type) ||
4641                                               (vt == TypeManager.byte_type) ||
4642                                               (vt == TypeManager.short_type) ||
4643                                               (vt == TypeManager.ushort_type) ||
4644                                               (vt == TypeManager.int32_type) ||
4645                                               (vt == TypeManager.uint32_type) ||    
4646                                               (vt == TypeManager.char_type) ||
4647                                               (vt == TypeManager.float_type) ||
4648                                               (!vt.IsValueType))){
4649                                                 Report.Error (
4650                                                         677, Location, container.MakeName (Name) +
4651                                                         " A volatile field can not be of type `" +
4652                                                         TypeManager.CSharpName (vt) + "'");
4653                                                 return false;
4654                                         }
4655                                 }
4656
4657                                 if ((ModFlags & Modifiers.READONLY) != 0){
4658                                         Report.Error (
4659                                                       678, Location,
4660                                                       "A field can not be both volatile and readonly");
4661                                         return false;
4662                                 }
4663                         }
4664
4665                         FieldAttributes fa = Modifiers.FieldAttr (ModFlags);
4666
4667                         if (container is Struct && 
4668                             ((fa & FieldAttributes.Static) == 0) &&
4669                             MemberType == container.TypeBuilder &&
4670                             !TypeManager.IsBuiltinType (MemberType)){
4671                                 Report.Error (523, Location, "Struct member `" + container.Name + "." + Name + 
4672                                               "' causes a cycle in the structure layout");
4673                                 return false;
4674                         }
4675
4676                         try {
4677                                 FieldBuilder = container.TypeBuilder.DefineField (
4678                                         Name, MemberType, Modifiers.FieldAttr (ModFlags));
4679
4680                                 TypeManager.RegisterFieldBase (FieldBuilder, this);
4681                         }
4682                         catch (ArgumentException) {
4683                                 Report.Warning (-24, Location, "The Microsoft runtime is unable to use [void|void*] as a field type, try using the Mono runtime.");
4684                                 return false;
4685                         }
4686
4687                         return true;
4688                 }
4689
4690                 public override void Emit (TypeContainer tc)
4691                 {
4692                         if (OptAttributes != null) {
4693                                 EmitContext ec = new EmitContext (tc, Location, null, FieldBuilder.FieldType, ModFlags);
4694                                 OptAttributes.Emit (ec, this);
4695                         }
4696
4697                         base.Emit (tc);
4698                 }
4699         }
4700
4701         //
4702         // `set' and `get' accessors are represented with an Accessor.
4703         // 
4704         public class Accessor {
4705                 //
4706                 // Null if the accessor is empty, or a Block if not
4707                 //
4708                 public Block Block;
4709                 public Attributes Attributes;
4710                 
4711                 public Accessor (Block b, Attributes attrs)
4712                 {
4713                         Block = b;
4714                         Attributes = attrs;
4715                 }
4716         }
4717
4718
4719         // Ooouh Martin, templates are missing here.
4720         // When it will be possible move here a lot of child code and template method type.
4721         public abstract class AbstractPropertyEventMethod: Attributable, IMethodData
4722         {
4723                 protected MethodData method_data;
4724                 protected Block block;
4725
4726                 ReturnParameter return_attributes;
4727
4728                 public AbstractPropertyEventMethod ():
4729                         base (null)
4730                 {
4731                 }
4732
4733                 public AbstractPropertyEventMethod (Accessor accessor):
4734                         base (accessor.Attributes)
4735                 {
4736                         this.block = accessor.Block;
4737                 }
4738
4739                 #region IMethodData Members
4740
4741                 public Block Block {
4742                         get {
4743                                 return block;
4744                         }
4745                 }
4746
4747                 public CallingConventions CallingConventions {
4748                         get {
4749                                 return CallingConventions.Standard;
4750                         }
4751                 }
4752
4753                 public bool IsExcluded (EmitContext ec)
4754                 {
4755                         return false;
4756                 }
4757
4758                 public abstract ObsoleteAttribute GetObsoleteAttribute ();
4759                 public abstract string GetSignatureForError (TypeContainer tc);
4760                 public abstract Location Location { get; }
4761                 public abstract string MethodName { get; }
4762                 public abstract Type[] ParameterTypes { get; }
4763                 public abstract Type ReturnType { get; }
4764                 public abstract EmitContext CreateEmitContext(TypeContainer tc, ILGenerator ig);
4765
4766                 #endregion
4767
4768                 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
4769                 {
4770                         if (a.Type == TypeManager.cls_compliant_attribute_type || a.Type == TypeManager.obsolete_attribute_type ||
4771                                         a.Type == TypeManager.conditional_attribute_type) {
4772                                 //"'{0}' is not valid on property or event accessors. It is valid on '{1}' declarations only"
4773                                 Report.Error_T (1667, a.Location, TypeManager.CSharpName (a.Type), a.GetValidTargets ());
4774                                 return;
4775                         }
4776
4777                         if (a.Target == "method") {
4778                                 method_data.MethodBuilder.SetCustomAttribute (cb);
4779                                 return;
4780                         }
4781
4782                         if (a.Target == "return") {
4783                                 if (return_attributes == null)
4784                                         return_attributes = new ReturnParameter (method_data.MethodBuilder, Location);
4785
4786                                 return_attributes.ApplyAttributeBuilder (a, cb);
4787                                 return;
4788                         }
4789
4790                         ApplyToExtraTarget (a, cb);
4791                 }
4792
4793                 virtual protected void ApplyToExtraTarget (Attribute a, CustomAttributeBuilder cb)
4794                 {
4795                         System.Diagnostics.Debug.Fail ("You forgot to define special attribute target handling");
4796                 }
4797
4798                 public virtual void Emit (TypeContainer container)
4799                 {
4800                         method_data.Emit (container, this);
4801                         block = null;
4802                 }
4803         }
4804
4805         //
4806         // Properties and Indexers both generate PropertyBuilders, we use this to share 
4807         // their common bits.
4808         //
4809         abstract public class PropertyBase : MethodCore {
4810
4811                 public class GetMethod: PropertyMethod
4812                 {
4813                         static string[] attribute_targets = new string [] { "method", "return" };
4814
4815                         public GetMethod (MethodCore method, Accessor accessor):
4816                                 base (method, accessor)
4817                         {
4818                         }
4819
4820                         public override MethodBuilder Define(TypeContainer container)
4821                         {
4822                                 method_data = new MethodData (method, method.ParameterInfo, method.ModFlags, method.flags, this);
4823
4824                                 if (!method_data.Define (container))
4825                                         return null;
4826
4827                                 return method_data.MethodBuilder;
4828                         }
4829
4830                         public override string GetSignatureForError (TypeContainer tc)
4831                         {
4832                                 return String.Concat (base.GetSignatureForError (tc), ".get");
4833                         }
4834
4835                         public override string MethodName 
4836                         {
4837                                 get {
4838                                         return "get_" + method.ShortName;
4839                                 }
4840                         }
4841
4842                         public override Type ReturnType {
4843                                 get {
4844                                         return method.MemberType;
4845                                 }
4846                         }
4847
4848                         protected override string[] ValidAttributeTargets {
4849                                 get {
4850                                         return attribute_targets;
4851                                 }
4852                         }
4853                 }
4854
4855                 public class SetMethod: PropertyMethod {
4856
4857                         static string[] attribute_targets = new string [] { "method", "param", "return" };
4858                         ImplicitParameter param_attr;
4859
4860                         public SetMethod (MethodCore method, Accessor accessor):
4861                                 base (method, accessor)
4862                         {
4863                         }
4864
4865                         protected override void ApplyToExtraTarget(Attribute a, CustomAttributeBuilder cb)
4866                         {
4867                                 if (a.Target == "param") {
4868                                         if (param_attr == null)
4869                                                 param_attr = new ImplicitParameter (method_data.MethodBuilder);
4870
4871                                         param_attr.ApplyAttributeBuilder (a, cb);
4872                                         return;
4873                                 }
4874
4875                                 base.ApplyAttributeBuilder (a, cb);
4876                         }
4877
4878                         protected virtual InternalParameters GetParameterInfo (TypeContainer container)
4879                         {
4880                                 Parameter [] parms = new Parameter [1];
4881                                 parms [0] = new Parameter (method.Type, "value", Parameter.Modifier.NONE, null);
4882                                 return new InternalParameters (
4883                                         container, new Parameters (parms, null, method.Location));
4884                         }
4885
4886                         public override MethodBuilder Define(TypeContainer container)
4887                         {
4888                                 method_data = new MethodData (method, GetParameterInfo (container), method.ModFlags, method.flags, this);
4889
4890                                 if (!method_data.Define (container))
4891                                         return null;
4892
4893                                 return method_data.MethodBuilder;
4894                         }
4895
4896                         public override string GetSignatureForError (TypeContainer tc)
4897                         {
4898                                 return String.Concat (base.GetSignatureForError (tc), ".set");
4899                         }
4900
4901                         public override string MethodName {
4902                                 get {
4903                                         return "set_" + method.ShortName;
4904                                 }
4905                         }
4906
4907                         public override Type[] ParameterTypes {
4908                                 get {
4909                                         return new Type[] { method.MemberType };
4910                                 }
4911                         }
4912
4913                         public override Type ReturnType {
4914                                 get {
4915                                         return TypeManager.void_type;
4916                                 }
4917                         }
4918
4919                         protected override string[] ValidAttributeTargets {
4920                                 get {
4921                                         return attribute_targets;
4922                                 }
4923                         }
4924                 }
4925
4926                 static string[] attribute_targets = new string [] { "property" };
4927
4928                 public abstract class PropertyMethod: AbstractPropertyEventMethod
4929                 {
4930                         protected readonly MethodCore method;
4931
4932                         public PropertyMethod (MethodCore method, Accessor accessor):
4933                                 base (accessor)
4934                         {
4935                                 this.method = method;
4936                         }
4937
4938                         public override AttributeTargets AttributeTargets {
4939                                 get {
4940                                         return AttributeTargets.Method | AttributeTargets.ReturnValue;
4941                                 }
4942                         }
4943
4944                         public override bool IsClsCompliaceRequired(DeclSpace ds)
4945                         {
4946                                 return method.IsClsCompliaceRequired (ds);
4947                         }
4948
4949                         public InternalParameters ParameterInfo 
4950                         {
4951                                 get {
4952                                         return method_data.ParameterInfo;
4953                                 }
4954                         }
4955
4956                         public abstract MethodBuilder Define (TypeContainer container);
4957
4958                         public override Type[] ParameterTypes {
4959                                 get {
4960                                         return TypeManager.NoTypes;
4961                                 }
4962                         }
4963
4964                         public override Location Location {
4965                                 get {
4966                                         return method.Location;
4967                                 }
4968                         }
4969
4970                         public override EmitContext CreateEmitContext (TypeContainer tc, ILGenerator ig)
4971                         {
4972                                 return new EmitContext (tc, method.ds, method.Location, ig, ReturnType, method.ModFlags, false);
4973                         }
4974
4975                         public override ObsoleteAttribute GetObsoleteAttribute ()
4976                         {
4977                                 return method.GetObsoleteAttribute (method.ds);
4978                         }
4979
4980                         public override string GetSignatureForError (TypeContainer tc)
4981                         {
4982                                 return String.Concat (tc.Name, '.', method.Name);
4983                         }
4984                 }
4985
4986
4987                 public PropertyMethod Get, Set;
4988                 public PropertyBuilder PropertyBuilder;
4989                 public MethodBuilder GetBuilder, SetBuilder;
4990
4991                 protected EmitContext ec;
4992
4993                 public PropertyBase (DeclSpace ds, Expression type, int mod_flags,
4994                                      int allowed_mod, bool is_iface, string name,
4995                                      Parameters parameters, Attributes attrs,
4996                                      Location loc)
4997                         : base (ds, type, mod_flags, allowed_mod, is_iface, name,
4998                                 attrs, parameters, loc)
4999                 {
5000                 }
5001
5002                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
5003                 {
5004                         PropertyBuilder.SetCustomAttribute (cb);
5005                 }
5006
5007                 public override AttributeTargets AttributeTargets {
5008                         get {
5009                                 return AttributeTargets.Property;
5010                         }
5011                 }
5012
5013                 protected override bool DoDefine (TypeContainer container)
5014                 {
5015                         if (!base.DoDefine (container))
5016                                 return false;
5017
5018                         if (MemberType == TypeManager.arg_iterator_type || MemberType == TypeManager.typed_reference_type) {
5019                                 // "Field or property cannot be of type '{0}'";
5020                                 Report.Error_T (610, Location, TypeManager.CSharpName (MemberType));
5021                                 return false;
5022                         }
5023
5024                         ec = new EmitContext (container, Location, null, MemberType, ModFlags);
5025
5026                         return true;
5027                 }
5028
5029                 public override string GetSignatureForError()
5030                 {
5031                         return TypeManager.CSharpSignature (PropertyBuilder, false);
5032                 }
5033
5034                 protected virtual string RealMethodName {
5035                         get {
5036                                 return Name;
5037                         }
5038                 }
5039
5040                 protected override bool IsIdentifierClsCompliant (DeclSpace ds)
5041                 {
5042                         if (!IsIdentifierAndParamClsCompliant (ds, RealMethodName, null, null))
5043                                 return false;
5044
5045                         if (Get != null && !IsIdentifierAndParamClsCompliant (ds, "get_" + RealMethodName, null, null))
5046                                 return false;
5047
5048                         if (Set != null && !IsIdentifierAndParamClsCompliant (ds, "set_" + RealMethodName, null, null))
5049                                 return false;
5050
5051                         return true;
5052                 }
5053
5054
5055                 //
5056                 // Checks our base implementation if any
5057                 //
5058                 protected override bool CheckBase (TypeContainer container)
5059                 {
5060                         base.CheckBase (container);
5061                         
5062                         // Check whether arguments were correct.
5063                         if (!DoDefineParameters ())
5064                                 return false;
5065
5066                         if (IsExplicitImpl)
5067                                 return true;
5068
5069                         //
5070                         // Check in our class for dups
5071                         //
5072                         ArrayList ar = container.Properties;
5073                         if (ar != null) {
5074                                 int arLen = ar.Count;
5075                                         
5076                                 for (int i = 0; i < arLen; i++) {
5077                                         Property m = (Property) ar [i];
5078                                         if (IsDuplicateImplementation (container, m))
5079                                                 return false;
5080                                 }
5081                         }
5082
5083                         if (IsInterface)
5084                                 return true;
5085
5086                         string report_name;
5087                         MethodSignature ms, base_ms;
5088                         if (this is Indexer) {
5089                                 string name, base_name;
5090
5091                                 report_name = "this";
5092                                 name = TypeManager.IndexerPropertyName (container.TypeBuilder);
5093                                 ms = new MethodSignature (name, null, ParameterTypes);
5094                                 base_name = TypeManager.IndexerPropertyName (container.TypeBuilder.BaseType);
5095                                 base_ms = new MethodSignature (base_name, null, ParameterTypes);
5096                         } else {
5097                                 report_name = Name;
5098                                 ms = base_ms = new MethodSignature (Name, null, ParameterTypes);
5099                         }
5100
5101                         //
5102                         // Verify if the parent has a type with the same name, and then
5103                         // check whether we have to create a new slot for it or not.
5104                         //
5105                         Type ptype = container.TypeBuilder.BaseType;
5106
5107                         // ptype is only null for System.Object while compiling corlib.
5108                         if (ptype == null) {
5109                                 if ((ModFlags & Modifiers.NEW) != 0)
5110                                         WarningNotHiding (container);
5111
5112                                 return true;
5113                         }
5114
5115                         MemberInfo parent_member = null;
5116                         
5117                         //
5118                         // Explicit implementations do not have `parent' methods, however,
5119                         // the member cache stores them there. Without this check, we get
5120                         // an incorrect warning in corlib.
5121                         //
5122                         if (! IsExplicitImpl) {
5123                                 parent_member = ((IMemberContainer)container).Parent.MemberCache.FindMemberToOverride (
5124                                         container.TypeBuilder, Name, ParameterTypes, true);
5125                         }
5126
5127                         if (parent_member is PropertyInfo) {
5128                                 PropertyInfo parent_property = (PropertyInfo)parent_member;
5129
5130                                 string name = parent_property.DeclaringType.Name + "." +
5131                                         parent_property.Name;
5132
5133                                 MethodInfo get, set, parent_method;
5134                                 get = parent_property.GetGetMethod (true);
5135                                 set = parent_property.GetSetMethod (true);
5136
5137                                 if (get != null)
5138                                         parent_method = get;
5139                                 else if (set != null)
5140                                         parent_method = set;
5141                                 else
5142                                         throw new Exception ("Internal error!");
5143
5144                                 if (!CheckMethodAgainstBase (container, flags, parent_method, name))
5145                                         return false;
5146
5147                                 if ((ModFlags & Modifiers.NEW) == 0) {
5148                                         Type parent_type = TypeManager.TypeToCoreType (
5149                                                 parent_property.PropertyType);
5150
5151                                         if (parent_type != MemberType) {
5152                                                 Report.Error (
5153                                                         508, Location, container.MakeName (Name) + ": cannot " +
5154                                                         "change return type when overriding " +
5155                                                         "inherited member " + name);
5156                                                 return false;
5157                                         }
5158                                 }
5159                         } else if (parent_member == null){
5160                                 if ((ModFlags & Modifiers.NEW) != 0)
5161                                         WarningNotHiding (container);
5162
5163                                 if ((ModFlags & Modifiers.OVERRIDE) != 0){
5164                                         if (this is Indexer)
5165                                                 Report.Error (115, Location,
5166                                                               container.MakeName (Name) +
5167                                                               " no suitable indexers found to override");
5168                                         else
5169                                                 Report.Error (115, Location,
5170                                                               container.MakeName (Name) +
5171                                                               " no suitable properties found to override");
5172                                         return false;
5173                                 }
5174                         }
5175                         return true;
5176                 }
5177
5178                 public override void Emit (TypeContainer tc)
5179                 {
5180                         //
5181                         // The PropertyBuilder can be null for explicit implementations, in that
5182                         // case, we do not actually emit the ".property", so there is nowhere to
5183                         // put the attribute
5184                         //
5185                         if (PropertyBuilder != null && OptAttributes != null)
5186                                 OptAttributes.Emit (ec, this);
5187
5188                         if (Get != null)
5189                                 Get.Emit (tc);
5190
5191                         if (Set != null)
5192                                 Set.Emit (tc);
5193
5194                         base.Emit (tc);
5195                 }
5196
5197                 protected override string[] ValidAttributeTargets {
5198                         get {
5199                                 return attribute_targets;
5200                         }
5201                 }
5202         }
5203                         
5204         public class Property : PropertyBase, IIteratorContainer {
5205                 const int AllowedModifiers =
5206                         Modifiers.NEW |
5207                         Modifiers.PUBLIC |
5208                         Modifiers.PROTECTED |
5209                         Modifiers.INTERNAL |
5210                         Modifiers.PRIVATE |
5211                         Modifiers.STATIC |
5212                         Modifiers.SEALED |
5213                         Modifiers.OVERRIDE |
5214                         Modifiers.ABSTRACT |
5215                         Modifiers.UNSAFE |
5216                         Modifiers.EXTERN |
5217                         Modifiers.METHOD_YIELDS |
5218                         Modifiers.VIRTUAL;
5219
5220                 const int AllowedInterfaceModifiers =
5221                         Modifiers.NEW;
5222
5223                 public Property (DeclSpace ds, Expression type, int mod_flags, bool is_iface,
5224                                  string name, Attributes attrs, Accessor get_block,
5225                                  Accessor set_block, Location loc)
5226                         : base (ds, type, mod_flags,
5227                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
5228                                 is_iface, name, Parameters.EmptyReadOnlyParameters, attrs,
5229                                 loc)
5230                 {
5231                         if (get_block != null)
5232                                 Get = new GetMethod (this, get_block);
5233
5234                         if (set_block != null)
5235                                 Set = new SetMethod (this, set_block);
5236                 }
5237
5238                 public override bool Define (TypeContainer container)
5239                 {
5240                         if (!DoDefine (container))
5241                                 return false;
5242
5243                         if (!CheckBase (container))
5244                                 return false;
5245
5246                         flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
5247
5248                         if (Get != null) {
5249
5250                                 GetBuilder = Get.Define (container);
5251                                 if (GetBuilder == null)
5252                                         return false;
5253
5254                                 //
5255                                 // Setup iterator if we are one
5256                                 //
5257                                 if ((ModFlags & Modifiers.METHOD_YIELDS) != 0){
5258                                         IteratorHandler ih = new  IteratorHandler (
5259                                                                                    "get", container, MemberType,
5260                                                                                    TypeManager.NoTypes, Get.ParameterInfo, ModFlags, Location);
5261                                         
5262                                         Block new_block = ih.Setup (block);
5263                                         if (new_block == null)
5264                                                 return false;
5265                                         block = new_block;
5266                                 }
5267                         }
5268
5269                         if (Set != null) {
5270                                 SetBuilder = Set.Define (container);
5271                                 if (SetBuilder == null)
5272                                         return false;
5273
5274                                 SetBuilder.DefineParameter (1, ParameterAttributes.None, "value"); 
5275                         }
5276
5277                         // FIXME - PropertyAttributes.HasDefault ?
5278                         
5279                         PropertyAttributes prop_attr = PropertyAttributes.None;
5280                         if (!IsInterface)
5281                                 prop_attr |= PropertyAttributes.RTSpecialName |
5282                                         PropertyAttributes.SpecialName;
5283
5284                         if (!IsExplicitImpl){
5285                                 PropertyBuilder = container.TypeBuilder.DefineProperty (
5286                                         Name, prop_attr, MemberType, null);
5287                                 
5288                                 if (Get != null)
5289                                         PropertyBuilder.SetGetMethod (GetBuilder);
5290                                 
5291                                 if (Set != null)
5292                                         PropertyBuilder.SetSetMethod (SetBuilder);
5293
5294                                 //
5295                                 // HACK for the reasons exposed above
5296                                 //
5297                                 if (!TypeManager.RegisterProperty (PropertyBuilder, GetBuilder, SetBuilder)) {
5298                                         Report.Error (
5299                                                 111, Location,
5300                                                 "Class `" + container.Name +
5301                                                 "' already contains a definition for the property `" +
5302                                                 Name + "'");
5303                                         return false;
5304                                 }
5305                         }
5306                         return true;
5307                 }
5308
5309                 public void SetYields ()
5310                 {
5311                         ModFlags |= Modifiers.METHOD_YIELDS;
5312                 }
5313         }
5314
5315         /// </summary>
5316         ///  Gigantic workaround  for lameness in SRE follows :
5317         ///  This class derives from EventInfo and attempts to basically
5318         ///  wrap around the EventBuilder so that FindMembers can quickly
5319         ///  return this in it search for members
5320         /// </summary>
5321         public class MyEventBuilder : EventInfo {
5322                 
5323                 //
5324                 // We use this to "point" to our Builder which is
5325                 // not really a MemberInfo
5326                 //
5327                 EventBuilder MyBuilder;
5328                 
5329                 //
5330                 // We "catch" and wrap these methods
5331                 //
5332                 MethodInfo raise, remove, add;
5333
5334                 EventAttributes attributes;
5335                 Type declaring_type, reflected_type, event_type;
5336                 string name;
5337
5338                 Event my_event;
5339
5340                 public MyEventBuilder (Event ev, TypeBuilder type_builder, string name, EventAttributes event_attr, Type event_type)
5341                 {
5342                         MyBuilder = type_builder.DefineEvent (name, event_attr, event_type);
5343
5344                         // And now store the values in our own fields.
5345                         
5346                         declaring_type = type_builder;
5347
5348                         reflected_type = type_builder;
5349                         
5350                         attributes = event_attr;
5351                         this.name = name;
5352                         my_event = ev;
5353                         this.event_type = event_type;
5354                 }
5355                 
5356                 //
5357                 // Methods that you have to override.  Note that you only need 
5358                 // to "implement" the variants that take the argument (those are
5359                 // the "abstract" methods, the others (GetAddMethod()) are 
5360                 // regular.
5361                 //
5362                 public override MethodInfo GetAddMethod (bool nonPublic)
5363                 {
5364                         return add;
5365                 }
5366                 
5367                 public override MethodInfo GetRemoveMethod (bool nonPublic)
5368                 {
5369                         return remove;
5370                 }
5371                 
5372                 public override MethodInfo GetRaiseMethod (bool nonPublic)
5373                 {
5374                         return raise;
5375                 }
5376                 
5377                 //
5378                 // These methods make "MyEventInfo" look like a Builder
5379                 //
5380                 public void SetRaiseMethod (MethodBuilder raiseMethod)
5381                 {
5382                         raise = raiseMethod;
5383                         MyBuilder.SetRaiseMethod (raiseMethod);
5384                 }
5385
5386                 public void SetRemoveOnMethod (MethodBuilder removeMethod)
5387                 {
5388                         remove = removeMethod;
5389                         MyBuilder.SetRemoveOnMethod (removeMethod);
5390                 }
5391
5392                 public void SetAddOnMethod (MethodBuilder addMethod)
5393                 {
5394                         add = addMethod;
5395                         MyBuilder.SetAddOnMethod (addMethod);
5396                 }
5397
5398                 public void SetCustomAttribute (CustomAttributeBuilder cb)
5399                 {
5400                         MyBuilder.SetCustomAttribute (cb);
5401                 }
5402                 
5403                 public override object [] GetCustomAttributes (bool inherit)
5404                 {
5405                         // FIXME : There's nothing which can be seemingly done here because
5406                         // we have no way of getting at the custom attribute objects of the
5407                         // EventBuilder !
5408                         return null;
5409                 }
5410
5411                 public override object [] GetCustomAttributes (Type t, bool inherit)
5412                 {
5413                         // FIXME : Same here !
5414                         return null;
5415                 }
5416
5417                 public override bool IsDefined (Type t, bool b)
5418                 {
5419                         return true;
5420                 }
5421
5422                 public override EventAttributes Attributes {
5423                         get {
5424                                 return attributes;
5425                         }
5426                 }
5427
5428                 public override string Name {
5429                         get {
5430                                 return name;
5431                         }
5432                 }
5433
5434                 public override Type DeclaringType {
5435                         get {
5436                                 return declaring_type;
5437                         }
5438                 }
5439
5440                 public override Type ReflectedType {
5441                         get {
5442                                 return reflected_type;
5443                         }
5444                 }
5445
5446                 public Type EventType {
5447                         get {
5448                                 return event_type;
5449                         }
5450                 }
5451                 
5452                 public void SetUsed ()
5453                 {
5454                         if (my_event != null)
5455                                 my_event.status = (FieldBase.Status.ASSIGNED | FieldBase.Status.USED);
5456                 }
5457         }
5458         
5459         /// <summary>
5460         /// For case when event is declared like property (with add and remove accessors).
5461         /// </summary>
5462         public class EventProperty: Event {
5463
5464                 static string[] attribute_targets = new string [] { "event", "property" };
5465
5466                 public EventProperty (DeclSpace ds, Expression type, int mod_flags, bool is_iface, string name,
5467                         Object init, Attributes attrs, Accessor add, Accessor remove, Location loc)
5468                         : base (ds, type, mod_flags, is_iface, name, init, attrs, loc)
5469                 {
5470                         Add = new AddDelegateMethod (this, add);
5471                         Remove = new RemoveDelegateMethod (this, remove);
5472                 }
5473
5474                 protected override string[] ValidAttributeTargets {
5475                         get {
5476                                 return attribute_targets;
5477                         }
5478                 }
5479         }
5480
5481         /// <summary>
5482         /// Event is declared like field.
5483         /// </summary>
5484         public class EventField: Event {
5485
5486                 static string[] attribute_targets = new string [] { "event", "field", "method" };
5487
5488                 public EventField (DeclSpace ds, Expression type, int mod_flags, bool is_iface, string name,
5489                         Object init, Attributes attrs, Location loc)
5490                         : base (ds, type, mod_flags, is_iface, name, init, attrs, loc)
5491                 {
5492                         Add = new AddDelegateMethod (this);
5493                         Remove = new RemoveDelegateMethod (this);
5494                 }
5495
5496                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
5497                 {
5498                         if (a.Target == "field") {
5499                                 FieldBuilder.SetCustomAttribute (cb);
5500                                 return;
5501                         }
5502
5503                         if (a.Target == "method") {
5504                                 AddBuilder.SetCustomAttribute (cb);
5505                                 RemoveBuilder.SetCustomAttribute (cb);
5506                                 return;
5507                         }
5508
5509                         base.ApplyAttributeBuilder (a, cb);
5510                 }
5511
5512                 protected override string[] ValidAttributeTargets {
5513                         get {
5514                                 return attribute_targets;
5515                         }
5516                 }
5517         }
5518
5519         public abstract class Event : FieldBase {
5520
5521                 protected sealed class AddDelegateMethod: DelegateMethod
5522                 {
5523                         public AddDelegateMethod (Event method):
5524                                 base (method)
5525                         {
5526                         }
5527
5528                         public AddDelegateMethod (Event method, Accessor accessor):
5529                                 base (method, accessor)
5530                         {
5531                         }
5532
5533                         public override string MethodName {
5534                                 get {
5535                                         return "add_" + method.ShortName;
5536                                 }
5537                         }
5538
5539                         protected override MethodInfo DelegateMethodInfo {
5540                                 get {
5541                                         return TypeManager.delegate_combine_delegate_delegate;
5542                                 }
5543                         }
5544
5545                 }
5546
5547                 protected sealed class RemoveDelegateMethod: DelegateMethod
5548                 {
5549                         public RemoveDelegateMethod (Event method):
5550                                 base (method)
5551                         {
5552                         }
5553
5554                         public RemoveDelegateMethod (Event method, Accessor accessor):
5555                                 base (method, accessor)
5556                         {
5557                         }
5558
5559                         public override string MethodName {
5560                                 get {
5561                                         return "remove_" + method.ShortName;
5562                                 }
5563                         }
5564
5565                         protected override MethodInfo DelegateMethodInfo {
5566                                 get {
5567                                         return TypeManager.delegate_remove_delegate_delegate;
5568                                 }
5569                         }
5570
5571                 }
5572
5573                 public abstract class DelegateMethod: AbstractPropertyEventMethod
5574                 {
5575                         protected readonly Event method;
5576                         ImplicitParameter param_attr;
5577
5578                         static string[] attribute_targets = new string [] { "method", "param", "return" };
5579
5580                         public DelegateMethod (Event method)
5581                         {
5582                                 this.method = method;
5583                         }
5584
5585                         public DelegateMethod (Event method, Accessor accessor):
5586                                 base (accessor)
5587                         {
5588                                 this.method = method;
5589                         }
5590
5591                         protected override void ApplyToExtraTarget(Attribute a, CustomAttributeBuilder cb)
5592                         {
5593                                 if (a.Target == "param") {
5594                                         if (param_attr == null)
5595                                                 param_attr = new ImplicitParameter (method_data.MethodBuilder);
5596
5597                                         param_attr.ApplyAttributeBuilder (a, cb);
5598                                         return;
5599                                 }
5600
5601                                 base.ApplyAttributeBuilder (a, cb);
5602                         }
5603
5604                         public override AttributeTargets AttributeTargets {
5605                                 get {
5606                                         return AttributeTargets.Method;
5607                                 }
5608                         }
5609
5610                         public override bool IsClsCompliaceRequired(DeclSpace ds)
5611                         {
5612                                 return method.IsClsCompliaceRequired (ds);
5613                         }
5614
5615                         public MethodBuilder Define (TypeContainer container, InternalParameters ip)
5616                         {
5617                                 method_data = new MethodData (method, ip, method.ModFlags,
5618                                         method.flags | MethodAttributes.HideBySig | MethodAttributes.SpecialName, this);
5619
5620                                 if (!method_data.Define (container))
5621                                         return null;
5622
5623                                 MethodBuilder mb = method_data.MethodBuilder;
5624                                 mb.DefineParameter (1, ParameterAttributes.None, "value");
5625                                 return mb;
5626                         }
5627
5628
5629                         public override void Emit (TypeContainer tc)
5630                         {
5631                                 if (block != null) {
5632                                         base.Emit (tc);
5633                                         return;
5634                                 }
5635
5636                                 ILGenerator ig = method_data.MethodBuilder.GetILGenerator ();
5637                                 EmitContext ec = CreateEmitContext (tc, ig);
5638                                 FieldInfo field_info = (FieldInfo)method.FieldBuilder;
5639
5640                                 method_data.MethodBuilder.SetImplementationFlags (MethodImplAttributes.Synchronized);
5641                                 if ((method.ModFlags & Modifiers.STATIC) != 0) {
5642                                         ig.Emit (OpCodes.Ldsfld, field_info);
5643                                         ig.Emit (OpCodes.Ldarg_0);
5644                                         ig.Emit (OpCodes.Call, DelegateMethodInfo);
5645                                         ig.Emit (OpCodes.Castclass, method.MemberType);
5646                                         ig.Emit (OpCodes.Stsfld, field_info);
5647                                 } else {
5648                                         ig.Emit (OpCodes.Ldarg_0);
5649                                         ig.Emit (OpCodes.Ldarg_0);
5650                                         ig.Emit (OpCodes.Ldfld, field_info);
5651                                         ig.Emit (OpCodes.Ldarg_1);
5652                                         ig.Emit (OpCodes.Call, DelegateMethodInfo);
5653                                         ig.Emit (OpCodes.Castclass, method.MemberType);
5654                                         ig.Emit (OpCodes.Stfld, field_info);
5655                                 }
5656                                 ig.Emit (OpCodes.Ret);
5657                         }
5658
5659                         protected abstract MethodInfo DelegateMethodInfo { get; }
5660
5661                         public override Type[] ParameterTypes {
5662                                 get {
5663                                         return new Type[] { method.MemberType };
5664                                 }
5665                         }
5666
5667                         public override Type ReturnType {
5668                                 get {
5669                                         return TypeManager.void_type;
5670                                 }
5671                         }
5672
5673                         public override Location Location {
5674                                 get {
5675                                         return method.Location;
5676                                 }
5677                         }
5678
5679                         public override EmitContext CreateEmitContext (TypeContainer tc, ILGenerator ig)
5680                         {
5681                                 return new EmitContext (tc, method.ds, Location, ig, ReturnType, method.ModFlags, false);
5682                         }
5683
5684                         public override string GetSignatureForError (TypeContainer tc)
5685                         {
5686                                 return String.Concat (tc.Name, '.', method.Name);
5687                         }
5688
5689                         public override ObsoleteAttribute GetObsoleteAttribute ()
5690                         {
5691                                 return method.GetObsoleteAttribute (method.ds);
5692                         }
5693
5694                         protected override string[] ValidAttributeTargets {
5695                                 get {
5696                                         return attribute_targets;
5697                                 }
5698                         }
5699                 }
5700
5701
5702                 const int AllowedModifiers =
5703                         Modifiers.NEW |
5704                         Modifiers.PUBLIC |
5705                         Modifiers.PROTECTED |
5706                         Modifiers.INTERNAL |
5707                         Modifiers.PRIVATE |
5708                         Modifiers.STATIC |
5709                         Modifiers.VIRTUAL |
5710                         Modifiers.SEALED |
5711                         Modifiers.OVERRIDE |
5712                         Modifiers.UNSAFE |
5713                         Modifiers.ABSTRACT;
5714
5715                 const int AllowedInterfaceModifiers =
5716                         Modifiers.NEW;
5717
5718                 protected DelegateMethod Add, Remove;
5719                 public MyEventBuilder     EventBuilder;
5720                 public MethodBuilder AddBuilder, RemoveBuilder;
5721                 public DeclSpace ds;
5722
5723                 public Event (DeclSpace ds, Expression type, int mod_flags, bool is_iface, string name,
5724                                 Object init, Attributes attrs, Location loc)
5725                         : base (type, mod_flags, is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
5726                                 name, init, attrs, loc)
5727                 {
5728                         IsInterface = is_iface;
5729                         this.ds = ds;
5730                 }
5731
5732                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
5733                 {
5734                         EventBuilder.SetCustomAttribute (cb);
5735                 }
5736
5737                 public override AttributeTargets AttributeTargets {
5738                         get {
5739                                 return AttributeTargets.Event;
5740                         }
5741                 }
5742
5743                 public override bool Define (TypeContainer container)
5744                 {
5745                         EventAttributes e_attr;
5746                         e_attr = EventAttributes.None;
5747
5748                         if (!DoDefine (container))
5749                                 return false;
5750
5751                         if (init != null && ((ModFlags & Modifiers.ABSTRACT) != 0)){
5752                                 Report.Error (74, Location, "'" + container.Name + "." + Name +
5753                                               "': abstract event can not have an initializer");
5754                                 return false;
5755                         }
5756                         
5757                         if (!MemberType.IsSubclassOf (TypeManager.delegate_type)) {
5758                                 Report.Error (66, Location, "'" + container.Name + "." + Name +
5759                                               "' : event must be of a delegate type");
5760                                 return false;
5761                         }
5762
5763                         Parameter [] parms = new Parameter [1];
5764                         parms [0] = new Parameter (Type, "value", Parameter.Modifier.NONE, null);
5765                         InternalParameters ip = new InternalParameters (
5766                                 container, new Parameters (parms, null, Location)); 
5767
5768                         if (!CheckBase (container))
5769                                 return false;
5770
5771                         //
5772                         // Now define the accessors
5773                         //
5774
5775                         AddBuilder = Add.Define (container, ip);
5776                         if (AddBuilder == null)
5777                                 return false;
5778
5779                         RemoveBuilder = Remove.Define (container, ip);
5780                         if (RemoveBuilder == null)
5781                                 return false;
5782
5783                         if (!IsExplicitImpl){
5784                                 EventBuilder = new MyEventBuilder (this,
5785                                         container.TypeBuilder, Name, e_attr, MemberType);
5786                                         
5787                                 if (Add.Block == null && Remove.Block == null &&
5788                                     !IsInterface) {
5789                                         FieldBuilder = container.TypeBuilder.DefineField (
5790                                                 Name, MemberType,
5791                                                 FieldAttributes.Private | ((ModFlags & Modifiers.STATIC) != 0 ? FieldAttributes.Static : 0));
5792                                         TypeManager.RegisterPrivateFieldOfEvent (
5793                                                 (EventInfo) EventBuilder, FieldBuilder);
5794                                         TypeManager.RegisterFieldBase (FieldBuilder, this);
5795                                 }
5796                         
5797                                 EventBuilder.SetAddOnMethod (AddBuilder);
5798                                 EventBuilder.SetRemoveOnMethod (RemoveBuilder);
5799
5800                                 if (!TypeManager.RegisterEvent (EventBuilder, AddBuilder, RemoveBuilder)) {
5801                                         Report.Error (111, Location,
5802                                                       "Class `" + container.Name +
5803                                                       "' already contains a definition for the event `" +
5804                                                       Name + "'");
5805                                         return false;
5806                                 }
5807                         }
5808                         
5809                         return true;
5810                 }
5811
5812                 public override void Emit (TypeContainer tc)
5813                 {
5814                         if (OptAttributes != null) {
5815                                 EmitContext ec = new EmitContext (tc, Location, null, MemberType, ModFlags);
5816                                 OptAttributes.Emit (ec, this);
5817                         }
5818
5819                         if (!IsInterface) {
5820                                 Add.Emit (tc);
5821                                 Remove.Emit (tc);
5822                         }
5823
5824                         base.Emit (tc);
5825                 }
5826
5827                 public override string GetSignatureForError ()
5828                 {
5829                         return TypeManager.GetFullNameSignature (EventBuilder);
5830                 }
5831         }
5832
5833         //
5834         // FIXME: This does not handle:
5835         //
5836         //   int INTERFACENAME [ args ]
5837         //   Does not 
5838         //
5839         // Only:
5840         // 
5841         // int this [ args ]
5842  
5843         public class Indexer : PropertyBase {
5844
5845                 class GetIndexerMethod: GetMethod
5846                 {
5847                         public GetIndexerMethod (MethodCore method, Accessor accessor):
5848                                 base (method, accessor)
5849                         {
5850                         }
5851
5852                         public override Type[] ParameterTypes {
5853                                 get {
5854                                         return method.ParameterTypes;
5855                                 }
5856                         }
5857                 }
5858
5859                 class SetIndexerMethod: SetMethod
5860                 {
5861                         readonly Parameters parameters;
5862
5863                         public SetIndexerMethod (MethodCore method, Parameters parameters, Accessor accessor):
5864                                 base (method, accessor)
5865                         {
5866                                 this.parameters = parameters;
5867                         }
5868
5869                         public override Type[] ParameterTypes {
5870                                 get {
5871                                         int top = method.ParameterTypes.Length;
5872                                         Type [] set_pars = new Type [top + 1];
5873                                         method.ParameterTypes.CopyTo (set_pars, 0);
5874                                         set_pars [top] = method.MemberType;
5875                                         return set_pars;
5876                                 }
5877                         }
5878
5879                         protected override InternalParameters GetParameterInfo (TypeContainer container)
5880                         {
5881                                 Parameter [] fixed_parms = parameters.FixedParameters;
5882
5883                                 if (fixed_parms == null){
5884                                         throw new Exception ("We currently do not support only array arguments in an indexer at: " + method.Location);
5885                                         // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
5886                                         // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
5887                                         //
5888                                         // Here is the problem: the `value' parameter has
5889                                         // to come *after* the array parameter in the declaration
5890                                         // like this:
5891                                         // X (object [] x, Type value)
5892                                         // .param [0]
5893                                         //
5894                                         // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
5895                                         // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
5896                                         
5897                                 }
5898                                 
5899                                 Parameter [] tmp = new Parameter [fixed_parms.Length + 1];
5900
5901                                 fixed_parms.CopyTo (tmp, 0);
5902                                 tmp [fixed_parms.Length] = new Parameter (
5903                                         method.Type, "value", Parameter.Modifier.NONE, null);
5904
5905                                 Parameters set_formal_params = new Parameters (tmp, null, method.Location);
5906                                 
5907                                 return new InternalParameters (container, set_formal_params);
5908                         }
5909
5910                 }
5911
5912
5913                 const int AllowedModifiers =
5914                         Modifiers.NEW |
5915                         Modifiers.PUBLIC |
5916                         Modifiers.PROTECTED |
5917                         Modifiers.INTERNAL |
5918                         Modifiers.PRIVATE |
5919                         Modifiers.VIRTUAL |
5920                         Modifiers.SEALED |
5921                         Modifiers.OVERRIDE |
5922                         Modifiers.UNSAFE |
5923                         Modifiers.EXTERN |
5924                         Modifiers.ABSTRACT;
5925
5926                 const int AllowedInterfaceModifiers =
5927                         Modifiers.NEW;
5928
5929                 public string IndexerName = "Item";
5930                 public string InterfaceIndexerName;
5931
5932                 //
5933                 // Are we implementing an interface ?
5934                 //
5935                 public Indexer (DeclSpace ds, Expression type, string int_type, int mod_flags,
5936                                 bool is_iface, Parameters parameters, Attributes attrs,
5937                                 Accessor get_block, Accessor set_block, Location loc)
5938                         : base (ds, type, mod_flags,
5939                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
5940                                 is_iface, "", parameters, attrs, loc)
5941                 {
5942                         ExplicitInterfaceName = int_type;
5943
5944                         if (get_block != null)
5945                                 Get = new GetIndexerMethod (this, get_block);
5946
5947                         if (set_block != null)
5948                                 Set = new SetIndexerMethod (this, parameters, set_block);
5949                 }
5950                        
5951                 public override bool Define (TypeContainer container)
5952                 {
5953                         PropertyAttributes prop_attr =
5954                                 PropertyAttributes.RTSpecialName |
5955                                 PropertyAttributes.SpecialName;
5956                         
5957                         if (!DoDefine (container))
5958                                 return false;
5959
5960                         if (OptAttributes != null) {
5961                                 Attribute indexer_attr = OptAttributes.GetIndexerNameAttribute (ec);
5962                                 if (indexer_attr != null) {
5963                                         IndexerName = indexer_attr.GetIndexerAttributeValue (ec);
5964
5965                                         if (IsExplicitImpl) {
5966                                                 // The 'IndexerName' attribute is valid only on an indexer that is not an explicit interface member declaration
5967                                                 Report.Error_T (415, indexer_attr.Location);
5968                                                 return false;
5969                                         }
5970
5971                                         if ((ModFlags & Modifiers.OVERRIDE) != 0) {
5972                                                 // Cannot set the 'IndexerName' attribute on an indexer marked override
5973                                                 Report.Error_T (609, indexer_attr.Location);
5974                                                 return false;
5975                                         }
5976
5977                                         if (!Tokenizer.IsValidIdentifier (IndexerName)) {
5978                                                 // The argument to the 'IndexerName' attribute must be a valid identifier
5979                                                 Report.Error_T (633, indexer_attr.Location);
5980                                                 return false;
5981                                         }
5982                                 }
5983                         }
5984
5985                         ShortName = IndexerName;
5986                         if (IsExplicitImpl) {
5987                                 InterfaceIndexerName = TypeManager.IndexerPropertyName (InterfaceType);
5988                                 Name = InterfaceType.FullName + "." + IndexerName;
5989                         } else {
5990                                 InterfaceIndexerName = IndexerName;
5991                                 Name = ShortName;
5992                         }
5993
5994                         if (!CheckNameCollision (container))
5995                                 return false;
5996
5997                         if (!CheckBase (container))
5998                                 return false;
5999
6000                         flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
6001                         if (Get != null){
6002                                 GetBuilder = Get.Define (container);
6003                                 if (GetBuilder == null)
6004                                         return false;
6005                         }
6006                         
6007                         if (Set != null){
6008                                 SetBuilder = Set.Define (container);
6009                                 if (SetBuilder == null)
6010                                         return false;
6011                         }
6012
6013                         //
6014                         // Now name the parameters
6015                         //
6016                         Parameter [] p = Parameters.FixedParameters;
6017                         if (p != null) {
6018                                 int i;
6019                                 
6020                                 for (i = 0; i < p.Length; ++i) {
6021                                         if (Get != null)
6022                                                 GetBuilder.DefineParameter (
6023                                                         i + 1, p [i].Attributes, p [i].Name);
6024
6025                                         if (Set != null)
6026                                                 SetBuilder.DefineParameter (
6027                                                         i + 1, p [i].Attributes, p [i].Name);
6028                                 }
6029
6030                                 if (Set != null)
6031                                         SetBuilder.DefineParameter (
6032                                                 i + 1, ParameterAttributes.None, "value");
6033                                         
6034                                 if (i != ParameterTypes.Length) {
6035                                         Parameter array_param = Parameters.ArrayParameter;
6036
6037                                         SetBuilder.DefineParameter (
6038                                                 i + 1, array_param.Attributes, array_param.Name);
6039                                 }
6040                         }
6041
6042                         //
6043                         // Define the PropertyBuilder if one of the following conditions are met:
6044                         // a) we're not implementing an interface indexer.
6045                         // b) the indexer has a different IndexerName and this is no
6046                         //    explicit interface implementation.
6047                         //
6048                         if (!IsExplicitImpl) {
6049                                 PropertyBuilder = container.TypeBuilder.DefineProperty (
6050                                         IndexerName, prop_attr, MemberType, ParameterTypes);
6051
6052                                 if (Get != null)
6053                                         PropertyBuilder.SetGetMethod (GetBuilder);
6054
6055                                 if (Set != null)
6056                                         PropertyBuilder.SetSetMethod (SetBuilder);
6057                                 
6058                                 TypeManager.RegisterIndexer (PropertyBuilder, GetBuilder, SetBuilder,
6059                                                              ParameterTypes);
6060                         }
6061
6062                         return true;
6063                 }
6064
6065                 bool CheckNameCollision (TypeContainer container) {
6066                         switch (VerifyName (container)){
6067                                 case DeclSpace.AdditionResult.NameExists:
6068                                         Report.Error (102, Location, "The container '{0}' already contains a definition for '{1}'", container.GetSignatureForError (), Name);
6069                                         return false;
6070
6071                                 case DeclSpace.AdditionResult.Success:
6072                                         return true;
6073                         }
6074                         throw new NotImplementedException ();
6075                 }
6076
6077                 DeclSpace.AdditionResult VerifyName (TypeContainer container) {
6078                         if (!AddIndexer (container, container.Name + "." + Name))
6079                                 return DeclSpace.AdditionResult.NameExists;
6080
6081                         if (Get != null) {
6082                                 if (!AddIndexer (container, container.Name + ".get_" + Name))
6083                                         return DeclSpace.AdditionResult.NameExists;
6084                         }
6085
6086                         if (Set != null) {
6087                                 if (!AddIndexer (container, container.Name + ".set_" + Name))
6088                                         return DeclSpace.AdditionResult.NameExists;
6089                         }
6090                         return DeclSpace.AdditionResult.Success;
6091                 }
6092
6093                 bool AddIndexer (TypeContainer container, string fullname)
6094                 {
6095                         object value = container.GetDefinition (fullname);
6096
6097                         if (value != null) {
6098                                 return value.GetType () != GetType () ? false : true;
6099                         }
6100
6101                         container.DefineName (fullname, this);
6102                         return true;
6103                 }
6104
6105                 public override string GetSignatureForError ()
6106                 {
6107                         return TypeManager.CSharpSignature (PropertyBuilder, true);
6108                 }
6109
6110                 protected override string RealMethodName {
6111                         get {
6112                                 return IndexerName;
6113                         }
6114                 }
6115         }
6116
6117         public class Operator : MemberBase, IIteratorContainer {
6118
6119                 const int AllowedModifiers =
6120                         Modifiers.PUBLIC |
6121                         Modifiers.UNSAFE |
6122                         Modifiers.EXTERN |
6123                         Modifiers.STATIC;
6124
6125                 const int RequiredModifiers =
6126                         Modifiers.PUBLIC |
6127                         Modifiers.STATIC;
6128
6129                 public enum OpType : byte {
6130
6131                         // Unary operators
6132                         LogicalNot,
6133                         OnesComplement,
6134                         Increment,
6135                         Decrement,
6136                         True,
6137                         False,
6138
6139                         // Unary and Binary operators
6140                         Addition,
6141                         Subtraction,
6142
6143                         UnaryPlus,
6144                         UnaryNegation,
6145                         
6146                         // Binary operators
6147                         Multiply,
6148                         Division,
6149                         Modulus,
6150                         BitwiseAnd,
6151                         BitwiseOr,
6152                         ExclusiveOr,
6153                         LeftShift,
6154                         RightShift,
6155                         Equality,
6156                         Inequality,
6157                         GreaterThan,
6158                         LessThan,
6159                         GreaterThanOrEqual,
6160                         LessThanOrEqual,
6161
6162                         // Implicit and Explicit
6163                         Implicit,
6164                         Explicit
6165                 };
6166
6167                 public readonly OpType OperatorType;
6168                 public readonly Expression ReturnType;
6169                 public readonly Expression FirstArgType, SecondArgType;
6170                 public readonly string FirstArgName, SecondArgName;
6171                 public Block           Block;
6172                 public MethodBuilder   OperatorMethodBuilder;
6173                 
6174                 public string MethodName;
6175                 public Method OperatorMethod;
6176
6177                 static string[] attribute_targets = new string [] { "method", "return" };
6178
6179                 public Operator (OpType type, Expression ret_type, int mod_flags,
6180                                  Expression arg1type, string arg1name,
6181                                  Expression arg2type, string arg2name,
6182                                  Block block, Attributes attrs, Location loc)
6183                         : base (ret_type, mod_flags, AllowedModifiers, Modifiers.PUBLIC, "", attrs, loc)
6184                 {
6185                         OperatorType = type;
6186                         Name = "op_" + OperatorType;
6187                         ReturnType = ret_type;
6188                         FirstArgType = arg1type;
6189                         FirstArgName = arg1name;
6190                         SecondArgType = arg2type;
6191                         SecondArgName = arg2name;
6192                         Block = block;
6193                 }
6194
6195                 string Prototype (TypeContainer container)
6196                 {
6197                         return container.Name + ".operator " + OperatorType + " (" + FirstArgType + "," +
6198                                 SecondArgType + ")";
6199                 }
6200
6201                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb) 
6202                 {
6203                         OperatorMethod.ApplyAttributeBuilder (a, cb);
6204                 }
6205
6206                 public override AttributeTargets AttributeTargets {
6207                         get {
6208                                 return AttributeTargets.Method; 
6209                         }
6210                 }
6211                 
6212                 public override bool Define (TypeContainer container)
6213                 {
6214                         int length = 1;
6215                         MethodName = "op_" + OperatorType;
6216                         
6217                         if (SecondArgType != null)
6218                                 length = 2;
6219                         
6220                         Parameter [] param_list = new Parameter [length];
6221
6222                         if ((ModFlags & RequiredModifiers) != RequiredModifiers){
6223                                 Report.Error (
6224                                         558, Location, 
6225                                         "User defined operators `" +
6226                                         Prototype (container) +
6227                                         "' must be declared static and public");
6228                                 return false;
6229                         }
6230
6231                         param_list[0] = new Parameter (FirstArgType, FirstArgName,
6232                                                        Parameter.Modifier.NONE, null);
6233                         if (SecondArgType != null)
6234                                 param_list[1] = new Parameter (SecondArgType, SecondArgName,
6235                                                                Parameter.Modifier.NONE, null);
6236                         
6237                         OperatorMethod = new Method (
6238                                 container, ReturnType, ModFlags, false, MethodName,
6239                                 new Parameters (param_list, null, Location),
6240                                 OptAttributes, Location);
6241
6242                         OperatorMethod.Block = Block;
6243                         OperatorMethod.IsOperator = true;                       
6244                         OperatorMethod.Define (container);
6245
6246                         if (OperatorMethod.MethodBuilder == null)
6247                                 return false;
6248                         
6249                         OperatorMethodBuilder = OperatorMethod.MethodBuilder;
6250
6251                         Type [] param_types = OperatorMethod.ParameterTypes;
6252                         Type declaring_type = OperatorMethodBuilder.DeclaringType;
6253                         Type return_type = OperatorMethod.GetReturnType ();
6254                         Type first_arg_type = param_types [0];
6255
6256                         // Rules for conversion operators
6257                         
6258                         if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
6259                                 if (first_arg_type == return_type && first_arg_type == declaring_type){
6260                                         Report.Error (
6261                                                 555, Location,
6262                                                 "User-defined conversion cannot take an object of the " +
6263                                                 "enclosing type and convert to an object of the enclosing" +
6264                                                 " type");
6265                                         return false;
6266                                 }
6267                                 
6268                                 if (first_arg_type != declaring_type && return_type != declaring_type){
6269                                         Report.Error (
6270                                                 556, Location, 
6271                                                 "User-defined conversion must convert to or from the " +
6272                                                 "enclosing type");
6273                                         return false;
6274                                 }
6275                                 
6276                                 if (first_arg_type == TypeManager.object_type ||
6277                                     return_type == TypeManager.object_type){
6278                                         Report.Error (
6279                                                 -8, Location,
6280                                                 "User-defined conversion cannot convert to or from " +
6281                                                 "object type");
6282                                         return false;
6283                                 }
6284
6285                                 if (first_arg_type.IsInterface || return_type.IsInterface){
6286                                         Report.Error (
6287                                                 552, Location,
6288                                                 "User-defined conversion cannot convert to or from an " +
6289                                                 "interface type");
6290                                         return false;
6291                                 }
6292                                 
6293                                 if (first_arg_type.IsSubclassOf (return_type)
6294                                         || return_type.IsSubclassOf (first_arg_type)){
6295                                         if (declaring_type.IsSubclassOf (return_type)) {
6296                                                 // '{0}' : user defined conversion to/from base class
6297                                                 Report.Error_T (553, Location, GetSignatureForError ());
6298                                                 return false;
6299                                         }
6300                                         // '{0}' : user defined conversion to/from derived class
6301                                         Report.Error_T (554, Location, GetSignatureForError ());
6302                                         return false;
6303                                 }
6304                         } else if (SecondArgType == null) {
6305                                 // Checks for Unary operators
6306                                 
6307                                 if (first_arg_type != declaring_type){
6308                                         Report.Error (
6309                                                 562, Location,
6310                                                 "The parameter of a unary operator must be the " +
6311                                                 "containing type");
6312                                         return false;
6313                                 }
6314                                 
6315                                 if (OperatorType == OpType.Increment || OperatorType == OpType.Decrement) {
6316                                         if (return_type != declaring_type){
6317                                                 Report.Error (
6318                                                         559, Location,
6319                                                         "The parameter and return type for ++ and -- " +
6320                                                         "must be the containing type");
6321                                                 return false;
6322                                         }
6323                                         
6324                                 }
6325                                 
6326                                 if (OperatorType == OpType.True || OperatorType == OpType.False) {
6327                                         if (return_type != TypeManager.bool_type){
6328                                                 Report.Error (
6329                                                         215, Location,
6330                                                         "The return type of operator True or False " +
6331                                                         "must be bool");
6332                                                 return false;
6333                                         }
6334                                 }
6335                                 
6336                         } else {
6337                                 // Checks for Binary operators
6338                                 
6339                                 if (first_arg_type != declaring_type &&
6340                                     param_types [1] != declaring_type){
6341                                         Report.Error (
6342                                                 563, Location,
6343                                                 "One of the parameters of a binary operator must " +
6344                                                 "be the containing type");
6345                                         return false;
6346                                 }
6347                         }
6348
6349                         return true;
6350                 }
6351                 
6352                 public override void Emit (TypeContainer container)
6353                 {
6354                         //
6355                         // abstract or extern methods have no bodies
6356                         //
6357                         if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
6358                                 return;
6359                         
6360                         OperatorMethod.Emit (container);
6361                         Block = null;
6362                 }
6363
6364                 public static string GetName (OpType ot)
6365                 {
6366                         switch (ot){
6367                         case OpType.LogicalNot:
6368                                 return "!";
6369                         case OpType.OnesComplement:
6370                                 return "~";
6371                         case OpType.Increment:
6372                                 return "++";
6373                         case OpType.Decrement:
6374                                 return "--";
6375                         case OpType.True:
6376                                 return "true";
6377                         case OpType.False:
6378                                 return "false";
6379                         case OpType.Addition:
6380                                 return "+";
6381                         case OpType.Subtraction:
6382                                 return "-";
6383                         case OpType.UnaryPlus:
6384                                 return "+";
6385                         case OpType.UnaryNegation:
6386                                 return "-";
6387                         case OpType.Multiply:
6388                                 return "*";
6389                         case OpType.Division:
6390                                 return "/";
6391                         case OpType.Modulus:
6392                                 return "%";
6393                         case OpType.BitwiseAnd:
6394                                 return "&";
6395                         case OpType.BitwiseOr:
6396                                 return "|";
6397                         case OpType.ExclusiveOr:
6398                                 return "^";
6399                         case OpType.LeftShift:
6400                                 return "<<";
6401                         case OpType.RightShift:
6402                                 return ">>";
6403                         case OpType.Equality:
6404                                 return "==";
6405                         case OpType.Inequality:
6406                                 return "!=";
6407                         case OpType.GreaterThan:
6408                                 return ">";
6409                         case OpType.LessThan:
6410                                 return "<";
6411                         case OpType.GreaterThanOrEqual:
6412                                 return ">=";
6413                         case OpType.LessThanOrEqual:
6414                                 return "<=";
6415                         case OpType.Implicit:
6416                                 return "implicit";
6417                         case OpType.Explicit:
6418                                 return "explicit";
6419                         default: return "";
6420                         }
6421                 }
6422
6423                 public override string GetSignatureForError(TypeContainer tc)
6424                 {
6425                         return ToString ();
6426                 }
6427
6428                 public override string GetSignatureForError()
6429                 {
6430                         return ToString ();
6431                 }
6432                 
6433                 public override string ToString ()
6434                 {
6435                         Type return_type = OperatorMethod.GetReturnType();
6436                         Type [] param_types = OperatorMethod.ParameterTypes;
6437                         
6438                         if (SecondArgType == null)
6439                                 return String.Format (
6440                                         "{0} operator {1}({2})",
6441                                         TypeManager.CSharpName (return_type),
6442                                         GetName (OperatorType),
6443                                         param_types [0]);
6444                         else
6445                                 return String.Format (
6446                                         "{0} operator {1}({2}, {3})",
6447                                         TypeManager.CSharpName (return_type),
6448                                         GetName (OperatorType),
6449                                         param_types [0], param_types [1]);
6450                 }
6451
6452                 protected override string[] ValidAttributeTargets {
6453                         get {
6454                                 return attribute_targets;
6455                         }
6456                 }
6457
6458                 public void SetYields ()
6459                 {
6460                         ModFlags |= Modifiers.METHOD_YIELDS;
6461                 }
6462         }
6463
6464         //
6465         // This is used to compare method signatures
6466         //
6467         struct MethodSignature {
6468                 public string Name;
6469                 public Type RetType;
6470                 public Type [] Parameters;
6471                 
6472                 /// <summary>
6473                 ///    This delegate is used to extract methods which have the
6474                 ///    same signature as the argument
6475                 /// </summary>
6476                 public static MemberFilter method_signature_filter = new MemberFilter (MemberSignatureCompare);
6477                 
6478                 public MethodSignature (string name, Type ret_type, Type [] parameters)
6479                 {
6480                         Name = name;
6481                         RetType = ret_type;
6482
6483                         if (parameters == null)
6484                                 Parameters = TypeManager.NoTypes;
6485                         else
6486                                 Parameters = parameters;
6487                 }
6488
6489                 public override string ToString ()
6490                 {
6491                         string pars = "";
6492                         if (Parameters.Length != 0){
6493                                 System.Text.StringBuilder sb = new System.Text.StringBuilder ();
6494                                 for (int i = 0; i < Parameters.Length; i++){
6495                                         sb.Append (Parameters [i]);
6496                                         if (i+1 < Parameters.Length)
6497                                                 sb.Append (", ");
6498                                 }
6499                                 pars = sb.ToString ();
6500                         }
6501
6502                         return String.Format ("{0} {1} ({2})", RetType, Name, pars);
6503                 }
6504                 
6505                 public override int GetHashCode ()
6506                 {
6507                         return Name.GetHashCode ();
6508                 }
6509
6510                 public override bool Equals (Object o)
6511                 {
6512                         MethodSignature other = (MethodSignature) o;
6513
6514                         if (other.Name != Name)
6515                                 return false;
6516
6517                         if (other.RetType != RetType)
6518                                 return false;
6519                         
6520                         if (Parameters == null){
6521                                 if (other.Parameters == null)
6522                                         return true;
6523                                 return false;
6524                         }
6525
6526                         if (other.Parameters == null)
6527                                 return false;
6528                         
6529                         int c = Parameters.Length;
6530                         if (other.Parameters.Length != c)
6531                                 return false;
6532
6533                         for (int i = 0; i < c; i++)
6534                                 if (other.Parameters [i] != Parameters [i])
6535                                         return false;
6536
6537                         return true;
6538                 }
6539
6540                 static bool MemberSignatureCompare (MemberInfo m, object filter_criteria)
6541                 {
6542                         MethodSignature sig = (MethodSignature) filter_criteria;
6543
6544                         if (m.Name != sig.Name)
6545                                 return false;
6546
6547                         Type ReturnType;
6548                         MethodInfo mi = m as MethodInfo;
6549                         PropertyInfo pi = m as PropertyInfo;
6550
6551                         if (mi != null)
6552                                 ReturnType = mi.ReturnType;
6553                         else if (pi != null)
6554                                 ReturnType = pi.PropertyType;
6555                         else
6556                                 return false;
6557                         
6558                         //
6559                         // we use sig.RetType == null to mean `do not check the
6560                         // method return value.  
6561                         //
6562                         if (sig.RetType != null)
6563                                 if (ReturnType != sig.RetType)
6564                                         return false;
6565
6566                         Type [] args;
6567                         if (mi != null)
6568                                 args = TypeManager.GetArgumentTypes (mi);
6569                         else
6570                                 args = TypeManager.GetArgumentTypes (pi);
6571                         Type [] sigp = sig.Parameters;
6572
6573                         if (args.Length != sigp.Length)
6574                                 return false;
6575
6576                         for (int i = args.Length; i > 0; ){
6577                                 i--;
6578                                 if (args [i] != sigp [i])
6579                                         return false;
6580                         }
6581                         return true;
6582                 }
6583         }
6584 }