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