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