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