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