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