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