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