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