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