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