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