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