2007-02-12 Marek Safar <marek.safar@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 (FieldBase 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 (MemberCore field, FieldInitializer expression)
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 (expression);
933                         } else {
934                                 if (initialized_fields == null)
935                                         initialized_fields = new ArrayList (4);
936
937                                 initialized_fields.Add (expression);
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 (FieldInitializer f in fields) {
958                                 f.EmitStatement (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[] inferred = new Type [CountTypeParameters];
1145                                         if (!TypeManager.MayBecomeEqualGenericInstances (iface, t, inferred, 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                                                 FieldBase f = (FieldBase) 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 (FieldBase 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 (FieldBase 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 (InterfaceMemberBase 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                                         FieldInitializer fi = (FieldInitializer)initialized_fields[i];
2789
2790                                         EmitContext ec = new EmitContext (fi.TypeContainer, fi.TypeContainer,
2791                                                 Location, null, null, ModFlags);
2792                                         ec.IsFieldInitializer = true;
2793
2794                                         fi.ResolveStatement (ec);
2795                                         if (fi.IsDefaultInitializer && RootContext.Optimize) {
2796                                                 // Field is re-initialized to its default value => removed
2797                                                 initialized_fields.RemoveAt (i);
2798                                                 --i;
2799                                         }
2800                                 }
2801                         }
2802
2803                         if (initialized_static_fields != null) {
2804                                 bool has_complex_initializer = false;
2805
2806                                 foreach (FieldInitializer fi in initialized_static_fields) {
2807                                         EmitContext ec = new EmitContext (fi.TypeContainer, fi.TypeContainer,
2808                                                 Location, null, null, ModFlags);
2809                                         ec.IsStatic = true;
2810                                         ec.IsFieldInitializer = true;
2811
2812                                         fi.ResolveStatement (ec);
2813                                         if (!fi.IsComplexInitializer)
2814                                                 continue;
2815
2816                                         has_complex_initializer = true;
2817                                 }
2818
2819                                 // Need special check to not optimize code like this
2820                                 // static int a = b = 5;
2821                                 // static int b = 0;
2822                                 if (!has_complex_initializer && RootContext.Optimize) {
2823                                         for (int i = 0; i < initialized_static_fields.Count; ++i) {
2824                                                 FieldInitializer fi = (FieldInitializer)initialized_static_fields[i];
2825                                                 if (fi.IsDefaultInitializer) {
2826                                                         initialized_static_fields.RemoveAt (i);
2827                                                         --i;
2828                                                 }
2829                                         }
2830                                 }
2831
2832                                 if (default_static_constructor == null && initialized_static_fields.Count > 0) {
2833                                         DefineDefaultConstructor (true);
2834                                 }
2835                         }
2836
2837                 }
2838
2839                 public override bool Define ()
2840                 {
2841                         DefineFieldInitializers ();
2842
2843                         if (default_static_constructor != null)
2844                                 default_static_constructor.Define ();
2845
2846                         return base.Define ();
2847                 }
2848
2849                 public override void Emit ()
2850                 {
2851                         base.Emit ();
2852
2853                         if (declarative_security != null) {
2854                                 foreach (DictionaryEntry de in declarative_security) {
2855                                         TypeBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
2856                                 }
2857                         }
2858                 }
2859
2860                 protected override TypeAttributes TypeAttr {
2861                         get {
2862                                 if (default_static_constructor == null)
2863                                         return base.TypeAttr | TypeAttributes.BeforeFieldInit;
2864
2865                                 return base.TypeAttr;
2866                         }
2867                 }
2868         }
2869
2870
2871         // TODO: should be sealed
2872         public class Class : ClassOrStruct {
2873                 const int AllowedModifiers =
2874                         Modifiers.NEW |
2875                         Modifiers.PUBLIC |
2876                         Modifiers.PROTECTED |
2877                         Modifiers.INTERNAL |
2878                         Modifiers.PRIVATE |
2879                         Modifiers.ABSTRACT |
2880                         Modifiers.SEALED |
2881                         Modifiers.STATIC |
2882                         Modifiers.UNSAFE;
2883
2884                 public const TypeAttributes StaticClassAttribute = TypeAttributes.Abstract | TypeAttributes.Sealed;
2885
2886                 public Class (NamespaceEntry ns, DeclSpace parent, MemberName name, int mod,
2887                               Attributes attrs)
2888                         : base (ns, parent, name, attrs, Kind.Class)
2889                 {
2890                         int accmods = Parent.Parent == null ? Modifiers.INTERNAL : Modifiers.PRIVATE;
2891                         this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, Location);
2892
2893                         if (IsStatic && RootContext.Version == LanguageVersion.ISO_1) {
2894                                 Report.FeatureIsNotISO1 (Location, "static classes");
2895                         }
2896                 }
2897
2898                 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
2899                 {
2900                         if (a.Type == TypeManager.attribute_usage_type) {
2901                                 if (BaseType != TypeManager.attribute_type && !BaseType.IsSubclassOf (TypeManager.attribute_type) &&
2902                                         TypeBuilder.FullName != "System.Attribute") {
2903                                         Report.Error (641, a.Location, "Attribute `{0}' is only valid on classes derived from System.Attribute", a.GetSignatureForError ());
2904                                 }
2905                         }
2906
2907                         if (a.Type == TypeManager.conditional_attribute_type &&
2908                                 !(BaseType == TypeManager.attribute_type || BaseType.IsSubclassOf (TypeManager.attribute_type))) {
2909                                 Report.Error (1689, a.Location, "Attribute `System.Diagnostics.ConditionalAttribute' is only valid on methods or attribute classes");
2910                                 return;
2911                         }
2912
2913                         if (a.Type == TypeManager.comimport_attr_type &&
2914                                 !attributes.Contains (TypeManager.guid_attr_type)) {
2915                                         a.Error_MissingGuidAttribute ();
2916                                         return;
2917                         }
2918
2919                         if (AttributeTester.IsAttributeExcluded (a.Type))
2920                                 return;
2921
2922                         base.ApplyAttributeBuilder (a, cb);
2923                 }
2924
2925                 public override AttributeTargets AttributeTargets {
2926                         get {
2927                                 return AttributeTargets.Class;
2928                         }
2929                 }
2930
2931                 protected override void DefineContainerMembers (MemberCoreArrayList list)
2932                 {
2933                         if (list == null)
2934                                 return;
2935
2936                         if (!IsStatic) {
2937                                 base.DefineContainerMembers (list);
2938                                 return;
2939                         }
2940
2941                         foreach (MemberCore m in list) {
2942                                 if (m is Operator) {
2943                                         Report.Error (715, m.Location, "`{0}': Static classes cannot contain user-defined operators", m.GetSignatureForError ());
2944                                         continue;
2945                                 }
2946
2947                                 if (m is Destructor) {
2948                                         Report.Error (711, m.Location, "`{0}': Static classes cannot contain destructor", GetSignatureForError ());
2949                                         continue;
2950                                 }
2951
2952                                 if ((m.ModFlags & Modifiers.PROTECTED) != 0) {
2953                                         Report.Error (1057, m.Location, "`{0}': Static classes cannot contain protected members", m.GetSignatureForError ());
2954                                         continue;
2955                                 }
2956
2957                                 if (m is Indexer) {
2958                                         Report.Error (720, m.Location, "`{0}': cannot declare indexers in a static class", m.GetSignatureForError ());
2959                                         continue;
2960                                 }
2961
2962                                 if ((m.ModFlags & Modifiers.STATIC) != 0 || m is Enum || m is Delegate)
2963                                         continue;
2964
2965                                 if (m is Constructor) {
2966                                         Report.Error (710, m.Location, "`{0}': Static classes cannot have instance constructors", GetSignatureForError ());
2967                                         continue;
2968                                 }
2969
2970                                 Report.Error (708, m.Location, "`{0}': cannot declare instance members in a static class", m.GetSignatureForError ());
2971                         }
2972
2973                         base.DefineContainerMembers (list);
2974                 }
2975
2976                 public override TypeBuilder DefineType ()
2977                 {
2978                         if ((ModFlags & Modifiers.ABSTRACT) == Modifiers.ABSTRACT && (ModFlags & (Modifiers.SEALED | Modifiers.STATIC)) != 0) {
2979                                 Report.Error (418, Location, "`{0}': an abstract class cannot be sealed or static", GetSignatureForError ());
2980                                 return null;
2981                         }
2982
2983                         if ((ModFlags & (Modifiers.SEALED | Modifiers.STATIC)) == (Modifiers.SEALED | Modifiers.STATIC)) {
2984                                 Report.Error (441, Location, "`{0}': a class cannot be both static and sealed", GetSignatureForError ());
2985                                 return null;
2986                         }
2987
2988                         return base.DefineType ();
2989                 }
2990
2991                 protected override bool DoDefineMembers ()
2992                 {
2993                         if (InstanceConstructors == null && !IsStatic)
2994                                 DefineDefaultConstructor (false);
2995
2996                         return base.DoDefineMembers ();
2997                 }
2998
2999                 public override TypeExpr[] GetClassBases (out TypeExpr base_class)
3000                 {
3001                         TypeExpr[] ifaces = base.GetClassBases (out base_class);
3002
3003                         if (base_class == null) {
3004                                 if (RootContext.StdLib)
3005                                         base_class = TypeManager.system_object_expr;
3006                                 else if (Name != "System.Object")
3007                                         base_class = TypeManager.system_object_expr;
3008                         } else {
3009                                 if (Kind == Kind.Class && base_class is TypeParameterExpr){
3010                                         Report.Error (
3011                                                 689, base_class.Location,
3012                                                 "Cannot derive from `{0}' because it is a type parameter",
3013                                                 base_class.GetSignatureForError ());
3014                                         return ifaces;
3015                                 }
3016
3017                                 if (base_class.Type.IsArray || base_class.Type.IsPointer) {
3018                                         Report.Error (1521, base_class.Location, "Invalid base type");
3019                                         return ifaces;
3020                                 }
3021
3022                                 if (base_class.IsSealed){
3023                                         Report.SymbolRelatedToPreviousError (base_class.Type);
3024                                         if (base_class.Type.IsAbstract) {
3025                                                 Report.Error (709, Location, "`{0}': Cannot derive from static class `{1}'",
3026                                                         GetSignatureForError (), TypeManager.CSharpName (base_class.Type));
3027                                         } else {
3028                                                 Report.Error (509, Location, "`{0}': cannot derive from sealed class `{1}'",
3029                                                         GetSignatureForError (), TypeManager.CSharpName (base_class.Type));
3030                                         }
3031                                         return ifaces;
3032                                 }
3033
3034                                 if (!base_class.CanInheritFrom ()){
3035                                         Report.Error (644, Location, "`{0}' cannot derive from special class `{1}'",
3036                                                 GetSignatureForError (), base_class.GetSignatureForError ());
3037                                         return ifaces;
3038                                 }
3039
3040                                 if (!base_class.AsAccessible (this, ModFlags)) {
3041                                         Report.SymbolRelatedToPreviousError (base_class.Type);
3042                                         Report.Error (60, Location, "Inconsistent accessibility: base class `{0}' is less accessible than class `{1}'", 
3043                                                 TypeManager.CSharpName (base_class.Type), GetSignatureForError ());
3044                                 }
3045                         }
3046
3047                         if (IsStatic) {
3048                                 if (base_class != TypeManager.system_object_expr) {
3049                                         Report.Error (713, Location, "Static class `{0}' cannot derive from type `{1}'. Static classes must derive from object",
3050                                                 GetSignatureForError (), base_class.GetSignatureForError ());
3051                                         return ifaces;
3052                                 }
3053
3054                                 if (ifaces != null) {
3055                                         foreach (TypeExpr t in ifaces)
3056                                                 Report.SymbolRelatedToPreviousError (t.Type);
3057                                         Report.Error (714, Location, "`{0}': static classes cannot implement interfaces", GetSignatureForError ());
3058                                 }
3059                         }
3060
3061                         return ifaces;
3062                 }
3063
3064                 /// Search for at least one defined condition in ConditionalAttribute of attribute class
3065                 /// Valid only for attribute classes.
3066                 public bool IsExcluded ()
3067                 {
3068                         if ((caching_flags & Flags.Excluded_Undetected) == 0)
3069                                 return (caching_flags & Flags.Excluded) != 0;
3070
3071                         caching_flags &= ~Flags.Excluded_Undetected;
3072
3073                         if (OptAttributes == null)
3074                                 return false;
3075
3076                         Attribute[] attrs = OptAttributes.SearchMulti (TypeManager.conditional_attribute_type);
3077
3078                         if (attrs == null)
3079                                 return false;
3080
3081                         foreach (Attribute a in attrs) {
3082                                 string condition = a.GetConditionalAttributeValue ();
3083                                 if (RootContext.AllDefines.Contains (condition))
3084                                         return false;
3085                         }
3086
3087                         caching_flags |= Flags.Excluded;
3088                         return true;
3089                 }
3090
3091                 bool IsStatic {
3092                         get {
3093                                 return (ModFlags & Modifiers.STATIC) != 0;
3094                         }
3095                 }
3096
3097                 //
3098                 // FIXME: How do we deal with the user specifying a different
3099                 // layout?
3100                 //
3101                 protected override TypeAttributes TypeAttr {
3102                         get {
3103                                 TypeAttributes ta = base.TypeAttr | TypeAttributes.AutoLayout | TypeAttributes.Class;
3104                                 if (IsStatic)
3105                                         ta |= StaticClassAttribute;
3106                                 return ta;
3107                         }
3108                 }
3109         }
3110
3111         public sealed class Struct : ClassOrStruct {
3112                 // <summary>
3113                 //   Modifiers allowed in a struct declaration
3114                 // </summary>
3115                 const int AllowedModifiers =
3116                         Modifiers.NEW       |
3117                         Modifiers.PUBLIC    |
3118                         Modifiers.PROTECTED |
3119                         Modifiers.INTERNAL  |
3120                         Modifiers.UNSAFE    |
3121                         Modifiers.PRIVATE;
3122
3123                 public Struct (NamespaceEntry ns, DeclSpace parent, MemberName name,
3124                                int mod, Attributes attrs)
3125                         : base (ns, parent, name, attrs, Kind.Struct)
3126                 {
3127                         int accmods;
3128                         
3129                         if (parent.Parent == null)
3130                                 accmods = Modifiers.INTERNAL;
3131                         else
3132                                 accmods = Modifiers.PRIVATE;
3133                         
3134                         this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, Location);
3135
3136                         this.ModFlags |= Modifiers.SEALED;
3137                 }
3138
3139                 public override AttributeTargets AttributeTargets {
3140                         get {
3141                                 return AttributeTargets.Struct;
3142                         }
3143                 }
3144
3145                 const TypeAttributes DefaultTypeAttributes =
3146                         TypeAttributes.SequentialLayout |
3147                         TypeAttributes.Sealed |
3148                         TypeAttributes.BeforeFieldInit;
3149
3150
3151                 public override TypeExpr[] GetClassBases (out TypeExpr base_class)
3152                 {
3153                         TypeExpr[] ifaces = base.GetClassBases (out base_class);
3154                         //
3155                         // If we are compiling our runtime,
3156                         // and we are defining ValueType, then our
3157                         // base is `System.Object'.
3158                         //
3159                         if (base_class == null) {
3160                                 if (!RootContext.StdLib && Name == "System.ValueType")
3161                                         base_class = TypeManager.system_object_expr;
3162                                 else
3163                                         base_class = TypeManager.system_valuetype_expr;
3164                         }
3165
3166                         return ifaces;
3167                 }
3168
3169                 //
3170                 // FIXME: Allow the user to specify a different set of attributes
3171                 // in some cases (Sealed for example is mandatory for a class,
3172                 // but what SequentialLayout can be changed
3173                 //
3174                 protected override TypeAttributes TypeAttr {
3175                         get {
3176                                 return base.TypeAttr | DefaultTypeAttributes;
3177                         }
3178                 }
3179
3180                 public override void RegisterFieldForInitialization (MemberCore field, FieldInitializer expression)
3181                 {
3182                         if ((field.ModFlags & Modifiers.STATIC) == 0) {
3183                                 Report.Error (573, field.Location, "`{0}': Structs cannot have instance field initializers",
3184                                         field.GetSignatureForError ());
3185                                 return;
3186                         }
3187                         base.RegisterFieldForInitialization (field, expression);
3188                 }
3189
3190         }
3191
3192         /// <summary>
3193         ///   Interfaces
3194         /// </summary>
3195         public sealed class Interface : TypeContainer, IMemberContainer {
3196
3197                 /// <summary>
3198                 ///   Modifiers allowed in a class declaration
3199                 /// </summary>
3200                 public const int AllowedModifiers =
3201                         Modifiers.NEW       |
3202                         Modifiers.PUBLIC    |
3203                         Modifiers.PROTECTED |
3204                         Modifiers.INTERNAL  |
3205                         Modifiers.UNSAFE    |
3206                         Modifiers.PRIVATE;
3207
3208                 public Interface (NamespaceEntry ns, DeclSpace parent, MemberName name, int mod,
3209                                   Attributes attrs)
3210                         : base (ns, parent, name, attrs, Kind.Interface)
3211                 {
3212                         int accmods;
3213
3214                         if (parent.Parent == null)
3215                                 accmods = Modifiers.INTERNAL;
3216                         else
3217                                 accmods = Modifiers.PRIVATE;
3218
3219                         this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, name.Location);
3220                 }
3221
3222                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
3223                 {
3224                         if (a.Type == TypeManager.comimport_attr_type &&
3225                                 !attributes.Contains (TypeManager.guid_attr_type)) {
3226                                         a.Error_MissingGuidAttribute ();
3227                                         return;
3228                         }
3229                         base.ApplyAttributeBuilder (a, cb);
3230                 }
3231
3232
3233                 public override AttributeTargets AttributeTargets {
3234                         get {
3235                                 return AttributeTargets.Interface;
3236                         }
3237                 }
3238
3239                 const TypeAttributes DefaultTypeAttributes =
3240                         TypeAttributes.AutoLayout |
3241                         TypeAttributes.Abstract |
3242                         TypeAttributes.Interface;
3243
3244                 protected override TypeAttributes TypeAttr {
3245                         get {
3246                                 return base.TypeAttr | DefaultTypeAttributes;
3247                         }
3248                 }
3249
3250                 protected override bool VerifyClsCompliance ()
3251                 {
3252                         if (!base.VerifyClsCompliance ())
3253                                 return false;
3254
3255                         if (ifaces != null) {
3256                                 foreach (Type t in ifaces) {
3257                                         if (AttributeTester.IsClsCompliant (t))
3258                                                 continue;
3259
3260                                         Report.SymbolRelatedToPreviousError (t);
3261                                         Report.Warning (3027, 1, Location, "`{0}' is not CLS-compliant because base interface `{1}' is not CLS-compliant",
3262                                                 GetSignatureForError (), TypeManager.CSharpName (t));
3263                                 }
3264                         }
3265
3266                         return true;
3267                 }
3268         }
3269
3270         // It is used as a base class for all property based members
3271         // This includes properties, indexers, and events
3272         public abstract class PropertyBasedMember : InterfaceMemberBase
3273         {
3274                 public PropertyBasedMember (DeclSpace parent, GenericMethod generic,
3275                         Expression type, int mod, int allowed_mod, bool is_iface,
3276                         MemberName name, Attributes attrs)
3277                         : base (parent, generic, type, mod, allowed_mod, is_iface, name, attrs)
3278                 {
3279                 }
3280
3281                 protected override bool CheckForDuplications ()
3282                 {
3283                         throw new NotSupportedException ();
3284                 }
3285
3286                 protected override bool VerifyClsCompliance ()
3287                 {
3288                         if (!base.VerifyClsCompliance ())
3289                                 return false;
3290
3291                         if (!AttributeTester.IsClsCompliant (MemberType)) {
3292                                 Report.Error (3003, Location, "Type of `{0}' is not CLS-compliant",
3293                                         GetSignatureForError ());
3294                         }
3295                         return true;
3296                 }
3297
3298         }
3299
3300
3301         public abstract class MethodCore : InterfaceMemberBase
3302         {
3303                 public readonly Parameters Parameters;
3304                 protected ToplevelBlock block;
3305
3306                 public MethodCore (DeclSpace parent, GenericMethod generic,
3307                         Expression type, int mod, int allowed_mod, bool is_iface,
3308                         MemberName name, Attributes attrs, Parameters parameters)
3309                         : base (parent, generic, type, mod, allowed_mod, is_iface, name, attrs)
3310                 {
3311                         Parameters = parameters;
3312                 }
3313
3314                 //
3315                 //  Returns the System.Type array for the parameters of this method
3316                 //
3317                 public Type [] ParameterTypes {
3318                         get {
3319                                 return Parameters.Types;
3320                         }
3321                 }
3322
3323                 public Parameters ParameterInfo
3324                 {
3325                         get {
3326                                 return Parameters;
3327                         }
3328                 }
3329                 
3330                 public ToplevelBlock Block {
3331                         get {
3332                                 return block;
3333                         }
3334
3335                         set {
3336                                 block = value;
3337                         }
3338                 }
3339
3340                 protected bool DoDefineParameters ()
3341                 {
3342                         IResolveContext rc = GenericMethod == null ? this : (IResolveContext)ds;
3343
3344                         // Check if arguments were correct
3345                         if (!Parameters.Resolve (rc))
3346                                 return false;
3347
3348                         return CheckParameters (Parameters);
3349                 }
3350
3351                 protected override bool CheckBase ()
3352                 {
3353                         // Check whether arguments were correct.
3354                         if (!DoDefineParameters ())
3355                                 return false;
3356
3357                         if (!base.CheckBase ())
3358                                 return false;
3359
3360                         return true;
3361                 }
3362
3363                 // TODO: create a special method for operators only to make code better
3364                 protected bool IsDuplicateImplementation (MethodCore method)
3365                 {
3366                         if (method == this)
3367                                 return false;
3368
3369                         Operator op2 = null;
3370                         Operator op1 = null;
3371
3372                         if (!(method.MemberName.Equals (MemberName)))
3373                         {
3374                                 op1 = this as Operator;
3375                                 if (op1 == null || !(op1.OperatorType == Operator.OpType.Explicit || op1.OperatorType == Operator.OpType.Implicit))
3376                                         return false;
3377
3378                                 op2 = method as Operator;
3379                                 if (op2 == null || !(op2.OperatorType == Operator.OpType.Explicit || op2.OperatorType == Operator.OpType.Implicit))
3380                                         return false;
3381                         } else {
3382                                 op1 = this as Operator;
3383                                 op2 = method as Operator;
3384                         }
3385
3386                         Type[] param_types = method.ParameterTypes;
3387                         // This never happen. Rewrite this as Equal
3388                         if (param_types == null && ParameterTypes == null)
3389                                 return true;
3390                         if (param_types == null || ParameterTypes == null)
3391                                 return false;
3392
3393                         if (param_types.Length != ParameterTypes.Length)
3394                                 return false;
3395
3396                         if (method.Parameters.HasArglist != Parameters.HasArglist)
3397                                 return false;
3398                         
3399                         bool equal = true;
3400
3401                         for (int i = 0; i < param_types.Length; i++) {
3402                                 if (param_types [i] != ParameterTypes [i])
3403                                         equal = false;
3404                         }
3405
3406                         if (IsExplicitImpl && (method.InterfaceType != InterfaceType))
3407                                 equal = false;
3408
3409                         // TODO: make operator compatible with MethodCore to avoid this
3410                         if (op1 != null && op2 != null) {
3411                                 if (MemberType != method.MemberType)
3412                                         equal = false;
3413                         }
3414
3415                         if (equal) {
3416                                 //
3417                                 // Try to report 663: method only differs on out/ref
3418                                 //
3419                                 Parameters info = ParameterInfo;
3420                                 Parameters other_info = method.ParameterInfo;
3421                                 for (int i = 0; i < info.Count; i++){
3422                                         if (info.ParameterModifier (i) != other_info.ParameterModifier (i)){
3423                                                 Report.SymbolRelatedToPreviousError (method);
3424                                                 Report.Error (663, Location, "`{0}': Methods cannot differ only on their use of ref and out on a parameters",
3425                                                               GetSignatureForError ());
3426                                                 return false;
3427                                         }
3428                                 }
3429
3430                                 Report.SymbolRelatedToPreviousError (method);
3431                                 if (this is Operator && method is Operator)
3432                                         Report.Error (557, Location, "Duplicate user-defined conversion in type `{0}'", Parent.Name);
3433                                 else
3434                                         Report.Error (111, Location, TypeContainer.Error111, GetSignatureForError ());
3435
3436                                 return true;
3437                         }
3438
3439                         return false;
3440                 }
3441
3442                 //
3443                 // Returns a string that represents the signature for this 
3444                 // member which should be used in XML documentation.
3445                 //
3446                 public override string GetDocCommentName (DeclSpace ds)
3447                 {
3448                         return DocUtil.GetMethodDocCommentName (this, Parameters, ds);
3449                 }
3450
3451                 //
3452                 // Raised (and passed an XmlElement that contains the comment)
3453                 // when GenerateDocComment is writing documentation expectedly.
3454                 //
3455                 // FIXME: with a few effort, it could be done with XmlReader,
3456                 // that means removal of DOM use.
3457                 //
3458                 internal override void OnGenerateDocComment (XmlElement el)
3459                 {
3460                         DocUtil.OnMethodGenerateDocComment (this, el);
3461                 }
3462
3463                 //
3464                 //   Represents header string for documentation comment.
3465                 //
3466                 public override string DocCommentHeader 
3467                 {
3468                         get { return "M:"; }
3469                 }
3470
3471                 public virtual void SetYields ()
3472                 {
3473                         ModFlags |= Modifiers.METHOD_YIELDS;
3474                 }
3475
3476                 protected override bool VerifyClsCompliance ()
3477                 {
3478                         if (!base.VerifyClsCompliance ())
3479                                 return false;
3480
3481                         if (Parameters.HasArglist) {
3482                                 Report.Error (3000, Location, "Methods with variable arguments are not CLS-compliant");
3483                         }
3484
3485                         if (!AttributeTester.IsClsCompliant (MemberType)) {
3486                                 Report.Error (3002, Location, "Return type of `{0}' is not CLS-compliant",
3487                                         GetSignatureForError ());
3488                         }
3489
3490                         Parameters.VerifyClsCompliance ();
3491                         return true;
3492                 }
3493
3494         }
3495
3496         public abstract class InterfaceMemberBase : MemberBase {
3497                 //
3498                 // Whether this is an interface member.
3499                 //
3500                 public bool IsInterface;
3501
3502                 //
3503                 // If true, this is an explicit interface implementation
3504                 //
3505                 public bool IsExplicitImpl;
3506
3507                 //
3508                 // The interface type we are explicitly implementing
3509                 //
3510                 public Type InterfaceType;
3511
3512                 //
3513                 // The method we're overriding if this is an override method.
3514                 //
3515                 protected MethodInfo base_method;
3516
3517                 readonly int explicit_mod_flags;
3518                 public MethodAttributes flags;
3519
3520                 public InterfaceMemberBase (DeclSpace parent, GenericMethod generic,
3521                                    Expression type, int mod, int allowed_mod, bool is_iface,
3522                                    MemberName name, Attributes attrs)
3523                         : base (parent, generic, type, mod, allowed_mod, Modifiers.PRIVATE,
3524                                 name, attrs)
3525                 {
3526                         IsInterface = is_iface;
3527                         IsExplicitImpl = (MemberName.Left != null);
3528                         explicit_mod_flags = mod;
3529                 }
3530                 
3531                 protected override bool CheckBase ()
3532                 {
3533                         if (!base.CheckBase ())
3534                                 return false;
3535                         
3536                         if ((caching_flags & Flags.TestMethodDuplication) != 0 && !CheckForDuplications ())
3537                                 return false;
3538
3539                         if (IsExplicitImpl)
3540                                 return true;
3541
3542                         // Is null for System.Object while compiling corlib and base interfaces
3543                         if (Parent.PartialContainer.BaseCache == null) {
3544                                 if ((ModFlags & Modifiers.NEW) != 0) {
3545                                         Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
3546                                 }
3547                                 return true;
3548                         }
3549
3550                         Type base_ret_type = null;
3551                         base_method = FindOutBaseMethod (ref base_ret_type);
3552
3553                         // method is override
3554                         if (base_method != null) {
3555                                 if (!CheckMethodAgainstBase (base_ret_type))
3556                                         return false;
3557
3558                                 if ((ModFlags & Modifiers.OVERRIDE) != 0) {
3559                                         ObsoleteAttribute oa = AttributeTester.GetMethodObsoleteAttribute (base_method);
3560                                         if (oa != null) {
3561                                                 if (OptAttributes == null || !OptAttributes.Contains (TypeManager.obsolete_attribute_type)) {
3562                                                         Report.SymbolRelatedToPreviousError (base_method);
3563                                                                 Report.Warning (672, 1, Location, "Member `{0}' overrides obsolete member `{1}'. Add the Obsolete attribute to `{0}'",
3564                                                                         GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3565                                                 }
3566                                         } else {
3567                                                 if (OptAttributes != null && OptAttributes.Contains (TypeManager.obsolete_attribute_type)) {
3568                                                         Report.Warning (809, 1, Location, "Obsolete member `{0}' overrides non-obsolete member `{1}'",
3569                                                                 GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3570                                                 }
3571                                         }
3572                                 }
3573                                 return true;
3574                         }
3575
3576                         MemberInfo conflict_symbol = Parent.PartialContainer.FindBaseMemberWithSameName (Name, !((this is Event) || (this is Property)));
3577                         if ((ModFlags & Modifiers.OVERRIDE) != 0) {
3578                                 if (conflict_symbol != null) {
3579                                         Report.SymbolRelatedToPreviousError (conflict_symbol);
3580                                         if (this is Event)
3581                                                 Report.Error (72, Location, "`{0}': cannot override because `{1}' is not an event", GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
3582                                         else if (this is PropertyBase)
3583                                                 Report.Error (544, Location, "`{0}': cannot override because `{1}' is not a property", GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
3584                                         else
3585                                                 Report.Error (505, Location, "`{0}': cannot override because `{1}' is not a method", GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
3586                                 } else {
3587                                         Report.Error (115, Location, "`{0}' is marked as an override but no suitable {1} found to override",
3588                                                 GetSignatureForError (), SimpleName.GetMemberType (this));
3589                                 }
3590                                 return false;
3591                         }
3592
3593                         if (conflict_symbol == null) {
3594                                 if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0)) {
3595                                         Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
3596                                 }
3597                                 return true;
3598                         }
3599
3600                         if ((ModFlags & Modifiers.NEW) == 0) {
3601                                 if (this is Method && conflict_symbol is MethodBase)
3602                                         return true;
3603
3604                                 Report.SymbolRelatedToPreviousError (conflict_symbol);
3605                                 Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
3606                                         GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
3607                         }
3608
3609                         return true;
3610                 }
3611
3612                 //
3613                 // Performs various checks on the MethodInfo `mb' regarding the modifier flags
3614                 // that have been defined.
3615                 //
3616                 // `name' is the user visible name for reporting errors (this is used to
3617                 // provide the right name regarding method names and properties)
3618                 //
3619                 bool CheckMethodAgainstBase (Type baseMethodType)
3620                 {
3621                         bool ok = true;
3622
3623                         if ((ModFlags & Modifiers.OVERRIDE) != 0){
3624                                 if (!(base_method.IsAbstract || base_method.IsVirtual)){
3625                                         Report.Error (506, Location,
3626                                                 "`{0}': cannot override inherited member `{1}' because it is not marked virtual, abstract or override",
3627                                                  GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3628                                         ok = false;
3629                                 }
3630                                 
3631                                 // Now we check that the overriden method is not final
3632                                 
3633                                 if (base_method.IsFinal) {
3634                                         Report.SymbolRelatedToPreviousError (base_method);
3635                                         Report.Error (239, Location, "`{0}': cannot override inherited member `{1}' because it is sealed",
3636                                                               GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3637                                         ok = false;
3638                                 }
3639                                 //
3640                                 // Check that the permissions are not being changed
3641                                 //
3642                                 MethodAttributes thisp = flags & MethodAttributes.MemberAccessMask;
3643                                 MethodAttributes base_classp = base_method.Attributes & MethodAttributes.MemberAccessMask;
3644
3645                                 if (!CheckAccessModifiers (thisp, base_classp, base_method)) {
3646                                         Error_CannotChangeAccessModifiers (base_method, base_classp, null);
3647                                         ok = false;
3648                                 }
3649
3650                                 if (!TypeManager.IsEqual (MemberType, TypeManager.TypeToCoreType (baseMethodType))) {
3651                                         Report.SymbolRelatedToPreviousError (base_method);
3652                                         if (this is PropertyBasedMember) {
3653                                                 Report.Error (1715, Location, "`{0}': type must be `{1}' to match overridden member `{2}'", 
3654                                                         GetSignatureForError (), TypeManager.CSharpName (baseMethodType), TypeManager.CSharpSignature (base_method));
3655                                         }
3656                                         else {
3657                                                 Report.Error (508, Location, "`{0}': return type must be `{1}' to match overridden member `{2}'",
3658                                                         GetSignatureForError (), TypeManager.CSharpName (baseMethodType), TypeManager.CSharpSignature (base_method));
3659                                         }
3660                                         ok = false;
3661                                 }
3662                         }
3663
3664                         if ((ModFlags & Modifiers.NEW) == 0) {
3665                                 if ((ModFlags & Modifiers.OVERRIDE) == 0 && Name != "Finalize") {
3666                                         ModFlags |= Modifiers.NEW;
3667                                         Report.SymbolRelatedToPreviousError (base_method);
3668                                         if (!IsInterface && (base_method.IsVirtual || base_method.IsAbstract)) {
3669                                                 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",
3670                                                         GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3671                                         } else {
3672                                                 Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
3673                                                         GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3674                                         }
3675                                 }
3676                         } else {
3677                                 if (base_method.IsAbstract && !IsInterface) {
3678                                         Report.SymbolRelatedToPreviousError (base_method);
3679                                         Report.Error (533, Location, "`{0}' hides inherited abstract member `{1}'",
3680                                                 GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3681                                         return ok = false;
3682                                 }
3683                         }
3684
3685                         return ok;
3686                 }
3687                 
3688                 protected bool CheckAccessModifiers (MethodAttributes thisp, MethodAttributes base_classp, MethodInfo base_method)
3689                 {
3690                         if ((base_classp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
3691                                 //
3692                                 // when overriding protected internal, the method can be declared
3693                                 // protected internal only within the same assembly
3694                                 //
3695
3696                                 if ((thisp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
3697                                         if (Parent.TypeBuilder.Assembly != base_method.DeclaringType.Assembly){
3698                                                 //
3699                                                 // assemblies differ - report an error
3700                                                 //
3701                                                 
3702                                                 return false;
3703                                         } else if (thisp != base_classp) {
3704                                                 //
3705                                                 // same assembly, but other attributes differ - report an error
3706                                                 //
3707                                                 
3708                                                 return false;
3709                                         };
3710                                 } else if ((thisp & MethodAttributes.Family) != MethodAttributes.Family) {
3711                                         //
3712                                         // if it's not "protected internal", it must be "protected"
3713                                         //
3714
3715                                         return false;
3716                                 } else if (Parent.TypeBuilder.Assembly == base_method.DeclaringType.Assembly) {
3717                                         //
3718                                         // protected within the same assembly - an error
3719                                         //
3720                                         return false;
3721                                 } else if ((thisp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem)) != 
3722                                            (base_classp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem))) {
3723                                         //
3724                                         // protected ok, but other attributes differ - report an error
3725                                         //
3726                                         return false;
3727                                 }
3728                                 return true;
3729                         } else {
3730                                 return (thisp == base_classp);
3731                         }
3732                 }
3733
3734                 public bool CheckAbstractAndExtern (bool has_block)
3735                 {
3736                         if (Parent.PartialContainer.Kind == Kind.Interface)
3737                                 return true;
3738
3739                         if (has_block) {
3740                                 if ((ModFlags & Modifiers.EXTERN) != 0) {
3741                                         Report.Error (179, Location, "`{0}' cannot declare a body because it is marked extern",
3742                                                 GetSignatureForError ());
3743                                         return false;
3744                                 }
3745
3746                                 if ((ModFlags & Modifiers.ABSTRACT) != 0) {
3747                                         Report.Error (500, Location, "`{0}' cannot declare a body because it is marked abstract",
3748                                                 GetSignatureForError ());
3749                                         return false;
3750                                 }
3751                         } else {
3752                                 if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) == 0) {
3753                                         Report.Error (501, Location, "`{0}' must declare a body because it is not marked abstract or extern",
3754                                                 GetSignatureForError ());
3755                                         return false;
3756                                 }
3757                         }
3758
3759                         return true;
3760                 }
3761
3762                 protected bool CheckParameters (Parameters parameters)
3763                 {
3764                         bool error = false;
3765
3766                         foreach (Type partype in parameters.Types){
3767                                 if (partype.IsPointer){
3768                                         if (!TypeManager.VerifyUnManaged (TypeManager.GetElementType (partype), Location))
3769                                                 error = true;
3770                                 }
3771
3772                                 if (ds.AsAccessible (partype, ModFlags))
3773                                         continue;
3774
3775                                 Report.SymbolRelatedToPreviousError (partype);
3776                                 if (this is Indexer)
3777                                         Report.Error (55, Location,
3778                                                 "Inconsistent accessibility: parameter type `" +
3779                                                 TypeManager.CSharpName (partype) + "' is less " +
3780                                                 "accessible than indexer `" + GetSignatureForError () + "'");
3781                                 else if (this is Operator)
3782                                         Report.Error (57, Location,
3783                                                 "Inconsistent accessibility: parameter type `" +
3784                                                 TypeManager.CSharpName (partype) + "' is less " +
3785                                                 "accessible than operator `" + GetSignatureForError () + "'");
3786                                 else
3787                                         Report.Error (51, Location,
3788                                                 "Inconsistent accessibility: parameter type `" +
3789                                                 TypeManager.CSharpName (partype) + "' is less " +
3790                                                 "accessible than method `" + GetSignatureForError () + "'");
3791                                 error = true;
3792                         }
3793
3794                         return !error;
3795                 }
3796
3797                 protected override bool DoDefine()
3798                 {
3799                         if (!base.DoDefine ())
3800                                 return false;
3801
3802                         if (IsExplicitImpl) {
3803                                 Expression expr = MemberName.Left.GetTypeExpression ();
3804                                 TypeExpr texpr = expr.ResolveAsTypeTerminal (this, false);
3805                                 if (texpr == null)
3806                                         return false;
3807
3808                                 InterfaceType = texpr.Type;
3809
3810                                 if (!InterfaceType.IsInterface) {
3811                                         Report.Error (538, Location, "`{0}' in explicit interface declaration is not an interface", TypeManager.CSharpName (InterfaceType));
3812                                         return false;
3813                                 }
3814                                 
3815                                 if (!Parent.PartialContainer.VerifyImplements (this))
3816                                         return false;
3817                                 
3818                         }
3819                         return true;
3820                 }
3821
3822                 protected virtual bool DoDefineBase ()
3823                 {
3824                         if (Name == null)
3825                                 throw new InternalErrorException ();
3826
3827                         if (IsInterface) {
3828                                 ModFlags = Modifiers.PUBLIC |
3829                                         Modifiers.ABSTRACT |
3830                                         Modifiers.VIRTUAL | (ModFlags & Modifiers.UNSAFE) | (ModFlags & Modifiers.NEW);
3831
3832                                 flags = MethodAttributes.Public |
3833                                         MethodAttributes.Abstract |
3834                                         MethodAttributes.HideBySig |
3835                                         MethodAttributes.NewSlot |
3836                                         MethodAttributes.Virtual;
3837                         } else {
3838                                 if (!Parent.PartialContainer.MethodModifiersValid (this))
3839                                         return false;
3840
3841                                 flags = Modifiers.MethodAttr (ModFlags);
3842                         }
3843
3844                         if (IsExplicitImpl) {
3845                                 Expression expr = MemberName.Left.GetTypeExpression ();
3846                                 TypeExpr iface_texpr = expr.ResolveAsTypeTerminal (this, false);
3847                                 if (iface_texpr == null)
3848                                         return false;
3849
3850                                 InterfaceType = iface_texpr.Type;
3851
3852                                 if (!InterfaceType.IsInterface) {
3853                                         Report.Error (538, Location, "'{0}' in explicit interface declaration is not an interface", TypeManager.CSharpName (InterfaceType));
3854                                         return false;
3855                                 }
3856
3857                                 if (!Parent.PartialContainer.VerifyImplements (this))
3858                                         return false;
3859                                 
3860                                 Modifiers.Check (Modifiers.AllowedExplicitImplFlags, explicit_mod_flags, 0, Location);
3861                         }
3862
3863                         return true;
3864                 }
3865
3866                 protected void Error_CannotChangeAccessModifiers (MemberInfo base_method, MethodAttributes ma, string suffix)
3867                 {
3868                         Report.SymbolRelatedToPreviousError (base_method);
3869                         string base_name = TypeManager.GetFullNameSignature (base_method);
3870                         string this_name = GetSignatureForError ();
3871                         if (suffix != null) {
3872                                 base_name += suffix;
3873                                 this_name += suffix;
3874                         }
3875
3876                         Report.Error (507, Location, "`{0}': cannot change access modifiers when overriding `{1}' inherited member `{2}'",
3877                                 this_name, Modifiers.GetDescription (ma), base_name);
3878                 }
3879
3880                 protected static string Error722 {
3881                         get {
3882                                 return "`{0}': static types cannot be used as return types";
3883                         }
3884                 }
3885
3886                 /// <summary>
3887                 /// For custom member duplication search in a container
3888                 /// </summary>
3889                 protected abstract bool CheckForDuplications ();
3890
3891                 /// <summary>
3892                 /// Gets base method and its return type
3893                 /// </summary>
3894                 protected abstract MethodInfo FindOutBaseMethod (ref Type base_ret_type);
3895
3896                 //
3897                 // The "short" name of this property / indexer / event.  This is the
3898                 // name without the explicit interface.
3899                 //
3900                 public string ShortName 
3901                 {
3902                         get { return MemberName.Name; }
3903                         set { SetMemberName (new MemberName (MemberName.Left, value, Location)); }
3904                 }
3905
3906                 protected override bool VerifyClsCompliance ()
3907                 {
3908                         if (!base.VerifyClsCompliance ()) {
3909                                 if (IsInterface && HasClsCompliantAttribute && Parent.IsClsComplianceRequired ()) {
3910                                         Report.Error (3010, Location, "`{0}': CLS-compliant interfaces must have only CLS-compliant members", GetSignatureForError ());
3911                                 }
3912
3913                                 if ((ModFlags & Modifiers.ABSTRACT) != 0 && Parent.TypeBuilder.IsClass && IsExposedFromAssembly () && Parent.IsClsComplianceRequired ()) {
3914                                         Report.Error (3011, Location, "`{0}': only CLS-compliant members can be abstract", GetSignatureForError ());
3915                                 }
3916                                 return false;
3917                         }
3918
3919                         if (GenericMethod != null)
3920                                 GenericMethod.VerifyClsCompliance ();
3921
3922                         return true;
3923                 }
3924
3925                 public override bool IsUsed 
3926                 {
3927                         get { return IsExplicitImpl || base.IsUsed; }
3928                 }
3929
3930         }
3931
3932         public abstract class MethodOrOperator : MethodCore, IMethodData
3933         {
3934                 public MethodBuilder MethodBuilder;
3935                 ReturnParameter return_attributes;
3936                 ListDictionary declarative_security;
3937                 protected MethodData MethodData;
3938
3939                 Iterator iterator;
3940                 ArrayList anonymous_methods;
3941
3942                 static string[] attribute_targets = new string [] { "method", "return" };
3943
3944                 protected MethodOrOperator (DeclSpace parent, GenericMethod generic, Expression type, int mod,
3945                                 int allowed_mod, bool is_interface, MemberName name,
3946                                 Attributes attrs, Parameters parameters)
3947                         : base (parent, generic, type, mod, allowed_mod, is_interface, name,
3948                                         attrs, parameters)
3949                 {
3950                 }
3951
3952                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
3953                 {
3954                         if (a.Target == AttributeTargets.ReturnValue) {
3955                                 if (return_attributes == null)
3956                                         return_attributes = new ReturnParameter (MethodBuilder, Location);
3957
3958                                 return_attributes.ApplyAttributeBuilder (a, cb);
3959                                 return;
3960                         }
3961
3962                         if (a.Type == TypeManager.methodimpl_attr_type &&
3963                                 (a.GetMethodImplOptions () & MethodImplOptions.InternalCall) != 0) {
3964                                 MethodBuilder.SetImplementationFlags (MethodImplAttributes.InternalCall | MethodImplAttributes.Runtime);
3965                         }
3966
3967                         if (a.Type == TypeManager.dllimport_type) {
3968                                 const int extern_static = Modifiers.EXTERN | Modifiers.STATIC;
3969                                 if ((ModFlags & extern_static) != extern_static) {
3970                                         Report.Error (601, a.Location, "The DllImport attribute must be specified on a method marked `static' and `extern'");
3971                                 }
3972
3973                                 return;
3974                         }
3975
3976                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
3977                                 if (declarative_security == null)
3978                                         declarative_security = new ListDictionary ();
3979                                 a.ExtractSecurityPermissionSet (declarative_security);
3980                                 return;
3981                         }
3982
3983                         MethodBuilder.SetCustomAttribute (cb);
3984                 }
3985
3986                 public override AttributeTargets AttributeTargets {
3987                         get {
3988                                 return AttributeTargets.Method; 
3989                         }
3990                 }
3991
3992                 public virtual EmitContext CreateEmitContext (DeclSpace tc, ILGenerator ig)
3993                 {
3994                         return new EmitContext (
3995                                 this, tc, this.ds, Location, ig, MemberType, ModFlags, false);
3996                 }
3997
3998                 public void AddAnonymousMethod (AnonymousMethodExpression anonymous)
3999                 {
4000                         if (anonymous_methods == null)
4001                                 anonymous_methods = new ArrayList ();
4002                         anonymous_methods.Add (anonymous);
4003                 }
4004
4005                 protected bool DefineGenericMethod ()
4006                 {
4007                         if (!DoDefineBase ())
4008                                 return false;
4009
4010 #if GMCS_SOURCE
4011                         if (GenericMethod != null) {
4012                                 string method_name = MemberName.Name;
4013
4014                                 if (IsExplicitImpl) {
4015                                         method_name = TypeManager.CSharpName (InterfaceType) +
4016                                                 '.' + method_name;
4017                                 }
4018
4019                                 MethodBuilder = Parent.TypeBuilder.DefineMethod (method_name, flags);
4020
4021                                 if (!GenericMethod.Define (MethodBuilder, block))
4022                                         return false;
4023                         }
4024 #endif
4025
4026                         return true;
4027                 }
4028
4029                 public bool ResolveMembers ()
4030                 {
4031                         if (!DefineGenericMethod ())
4032                                 return false;
4033
4034                         if ((ModFlags & Modifiers.METHOD_YIELDS) != 0) {
4035                                 iterator = Iterator.CreateIterator (this, Parent, GenericMethod, ModFlags);
4036                                 if (iterator == null)
4037                                         return false;
4038                         }
4039
4040                         if (anonymous_methods != null) {
4041                                 foreach (AnonymousMethodExpression ame in anonymous_methods) {
4042                                         if (!ame.CreateAnonymousHelpers ())
4043                                                 return false;
4044                                 }
4045                         }
4046
4047                         return true;
4048                 }
4049
4050                 public override bool Define ()
4051                 {
4052                         if (!DoDefine ())
4053                                 return false;
4054
4055                         if (!CheckAbstractAndExtern (block != null))
4056                                 return false;
4057
4058                         if (!CheckBase ())
4059                                 return false;
4060
4061                         MethodData = new MethodData (
4062                                 this, ModFlags, flags, this, MethodBuilder, GenericMethod, base_method);
4063
4064                         if (!MethodData.Define (Parent.PartialContainer))
4065                                 return false;
4066
4067                         MethodBuilder = MethodData.MethodBuilder;
4068
4069                         if (MemberType.IsAbstract && MemberType.IsSealed) {
4070                                 Report.Error (722, Location, Error722, TypeManager.CSharpName (MemberType));
4071                                 return false;
4072                         }
4073
4074                         return true;
4075                 }
4076
4077                 public override void Emit ()
4078                 {
4079                         if (OptAttributes != null)
4080                                 OptAttributes.Emit ();
4081
4082                         if (declarative_security != null) {
4083                                 foreach (DictionaryEntry de in declarative_security) {
4084                                         MethodBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
4085                                 }
4086                         }
4087
4088                         base.Emit ();
4089                 }
4090
4091                 protected void Error_ConditionalAttributeIsNotValid ()
4092                 {
4093                         Report.Error (577, Location,
4094                                 "Conditional not valid on `{0}' because it is a constructor, destructor, operator or explicit interface implementation",
4095                                 GetSignatureForError ());
4096                 }
4097
4098                 public override bool MarkForDuplicationCheck ()
4099                 {
4100                         caching_flags |= Flags.TestMethodDuplication;
4101                         return true;
4102                 }
4103
4104                 public override string[] ValidAttributeTargets {
4105                         get {
4106                                 return attribute_targets;
4107                         }
4108                 }
4109
4110                 #region IMethodData Members
4111
4112                 public CallingConventions CallingConventions {
4113                         get {
4114                                 CallingConventions cc = Parameters.CallingConvention;
4115                                 if (Parameters.HasArglist)
4116                                         block.HasVarargs = true;
4117
4118                                 if (!IsInterface)
4119                                         if ((ModFlags & Modifiers.STATIC) == 0)
4120                                                 cc |= CallingConventions.HasThis;
4121
4122                                 // FIXME: How is `ExplicitThis' used in C#?
4123                         
4124                                 return cc;
4125                         }
4126                 }
4127
4128                 public Type ReturnType {
4129                         get {
4130                                 return MemberType;
4131                         }
4132                 }
4133
4134                 public MemberName MethodName {
4135                         get {
4136                                 return MemberName;
4137                         }
4138                 }
4139
4140                 public Iterator Iterator {
4141                         get { return iterator; }
4142                 }
4143
4144                 public new Location Location {
4145                         get {
4146                                 return base.Location;
4147                         }
4148                 }
4149
4150                 protected override bool CheckBase ()
4151                 {
4152                         if (!base.CheckBase ())
4153                                 return false;
4154
4155                         // TODO: Destructor should derive from MethodCore
4156                         if (base_method != null && (ModFlags & Modifiers.OVERRIDE) != 0 && Name == "Finalize" &&
4157                                 base_method.DeclaringType == TypeManager.object_type && !(this is Destructor)) {
4158                                 Report.Error (249, Location, "Do not override object.Finalize. Instead, provide a destructor");
4159                                 return false;
4160                         }
4161
4162                         return true;
4163                 }
4164
4165                 /// <summary>
4166                 /// Returns true if method has conditional attribute and the conditions is not defined (method is excluded).
4167                 /// </summary>
4168                 public bool IsExcluded () {
4169                         if ((caching_flags & Flags.Excluded_Undetected) == 0)
4170                                 return (caching_flags & Flags.Excluded) != 0;
4171
4172                         caching_flags &= ~Flags.Excluded_Undetected;
4173
4174                         if (base_method == null) {
4175                                 if (OptAttributes == null)
4176                                         return false;
4177
4178                                 Attribute[] attrs = OptAttributes.SearchMulti (TypeManager.conditional_attribute_type);
4179
4180                                 if (attrs == null)
4181                                         return false;
4182
4183                                 foreach (Attribute a in attrs) {
4184                                         string condition = a.GetConditionalAttributeValue ();
4185                                         if (condition == null)
4186                                                 return false;
4187
4188                                         if (RootContext.AllDefines.Contains (condition))
4189                                                 return false;
4190                                 }
4191
4192                                 caching_flags |= Flags.Excluded;
4193                                 return true;
4194                         }
4195
4196                         IMethodData md = TypeManager.GetMethod (base_method);
4197                         if (md == null) {
4198                                 if (AttributeTester.IsConditionalMethodExcluded (base_method)) {
4199                                         caching_flags |= Flags.Excluded;
4200                                         return true;
4201                                 }
4202                                 return false;
4203                         }
4204
4205                         if (md.IsExcluded ()) {
4206                                 caching_flags |= Flags.Excluded;
4207                                 return true;
4208                         }
4209                         return false;
4210                 }
4211
4212                 GenericMethod IMethodData.GenericMethod {
4213                         get {
4214                                 return GenericMethod;
4215                         }
4216                 }
4217
4218                 #endregion
4219
4220         }
4221
4222         public class SourceMethod : ISourceMethod
4223         {
4224                 DeclSpace parent;
4225                 MethodBase builder;
4226
4227                 protected SourceMethod (DeclSpace parent, MethodBase builder,
4228                                         ISourceFile file, Location start, Location end)
4229                 {
4230                         this.parent = parent;
4231                         this.builder = builder;
4232                         
4233                         CodeGen.SymbolWriter.OpenMethod (file, this, start.Row, start.Column, end.Row, start.Column);
4234                 }
4235
4236                 public string Name {
4237                         get { return builder.Name; }
4238                 }
4239
4240                 public int NamespaceID {
4241                         get { return parent.NamespaceEntry.SymbolFileID; }
4242                 }
4243
4244                 public int Token {
4245                         get {
4246                                 if (builder is MethodBuilder)
4247                                         return ((MethodBuilder) builder).GetToken ().Token;
4248                                 else if (builder is ConstructorBuilder)
4249                                         return ((ConstructorBuilder) builder).GetToken ().Token;
4250                                 else
4251                                         throw new NotSupportedException ();
4252                         }
4253                 }
4254
4255                 public void CloseMethod ()
4256                 {
4257                         if (CodeGen.SymbolWriter != null)
4258                                 CodeGen.SymbolWriter.CloseMethod ();
4259                 }
4260
4261                 public static SourceMethod Create (DeclSpace parent, MethodBase builder, Block block)
4262                 {
4263                         if (CodeGen.SymbolWriter == null)
4264                                 return null;
4265                         if (block == null)
4266                                 return null;
4267
4268                         Location start_loc = block.StartLocation;
4269                         if (start_loc.IsNull)
4270                                 return null;
4271
4272                         Location end_loc = block.EndLocation;
4273                         if (end_loc.IsNull)
4274                                 return null;
4275
4276                         ISourceFile file = start_loc.SourceFile;
4277                         if (file == null)
4278                                 return null;
4279
4280                         return new SourceMethod (
4281                                 parent, builder, file, start_loc, end_loc);
4282                 }
4283         }
4284
4285         public class Method : MethodOrOperator, IAnonymousHost {
4286
4287                 /// <summary>
4288                 ///   Modifiers allowed in a class declaration
4289                 /// </summary>
4290                 const int AllowedModifiers =
4291                         Modifiers.NEW |
4292                         Modifiers.PUBLIC |
4293                         Modifiers.PROTECTED |
4294                         Modifiers.INTERNAL |
4295                         Modifiers.PRIVATE |
4296                         Modifiers.STATIC |
4297                         Modifiers.VIRTUAL |
4298                         Modifiers.SEALED |
4299                         Modifiers.OVERRIDE |
4300                         Modifiers.ABSTRACT |
4301                         Modifiers.UNSAFE |
4302                         Modifiers.METHOD_YIELDS | 
4303                         Modifiers.EXTERN;
4304
4305                 const int AllowedInterfaceModifiers =
4306                         Modifiers.NEW | Modifiers.UNSAFE;
4307
4308                 //
4309                 // return_type can be "null" for VOID values.
4310                 //
4311                 public Method (DeclSpace parent, GenericMethod generic,
4312                                Expression return_type, int mod, bool is_iface,
4313                                MemberName name, Parameters parameters, Attributes attrs)
4314                         : base (parent, generic, return_type, mod,
4315                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
4316                                 is_iface, name, attrs, parameters)
4317                 {
4318                 }
4319                 
4320                 public override string GetSignatureForError()
4321                 {
4322                         return base.GetSignatureForError () + Parameters.GetSignatureForError ();
4323                 }
4324
4325                 void Error_DuplicateEntryPoint (MethodInfo b, Location location)
4326                 {
4327                         Report.Error (17, location,
4328                                 "Program `{0}' has more than one entry point defined: `{1}'",
4329                                 CodeGen.FileName, TypeManager.CSharpSignature(b));
4330                 }
4331
4332                 bool IsEntryPoint ()
4333                 {
4334                         if (ReturnType != TypeManager.void_type &&
4335                                 ReturnType != TypeManager.int32_type)
4336                                 return false;
4337
4338                         if (Parameters.Count == 0)
4339                                 return true;
4340
4341                         if (Parameters.Count > 1)
4342                                 return false;
4343
4344                         Type t = Parameters.ParameterType (0);
4345                         return t.IsArray && t.GetArrayRank () == 1 &&
4346                                         TypeManager.GetElementType (t) == TypeManager.string_type &&
4347                                         (Parameters[0].ModFlags & ~Parameter.Modifier.PARAMS) == Parameter.Modifier.NONE;
4348                 }
4349
4350                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
4351                 {
4352                         if (a.Type == TypeManager.conditional_attribute_type) {
4353                                 if (IsExplicitImpl) {
4354                                         Error_ConditionalAttributeIsNotValid ();
4355                                         return;
4356                                 }
4357
4358                                 if (ReturnType != TypeManager.void_type) {
4359                                         Report.Error (578, Location, "Conditional not valid on `{0}' because its return type is not void", GetSignatureForError ());
4360                                         return;
4361                                 }
4362
4363                                 if ((ModFlags & Modifiers.OVERRIDE) != 0) {
4364                                         Report.Error (243, Location, "Conditional not valid on `{0}' because it is an override method", GetSignatureForError ());
4365                                         return;
4366                                 }
4367
4368                                 if (IsInterface) {
4369                                         Report.Error (582, Location, "Conditional not valid on interface members");
4370                                         return;
4371                                 }
4372
4373                                 if (MethodData.implementing != null) {
4374                                         Report.Error (629, Location, "Conditional member `{0}' cannot implement interface member `{1}'",
4375                                                 GetSignatureForError (), TypeManager.CSharpSignature (MethodData.implementing));
4376                                         return;
4377                                 }
4378
4379                                 for (int i = 0; i < Parameters.Count; ++i) {
4380                                         if ((Parameters.ParameterModifier (i) & Parameter.Modifier.OUTMASK) != 0) {
4381                                                 Report.Error (685, Location, "Conditional method `{0}' cannot have an out parameter", GetSignatureForError ());
4382                                                 return;
4383                                         }
4384                                 }
4385                         }
4386
4387                         base.ApplyAttributeBuilder (a, cb);
4388                 }
4389
4390                 protected override bool CheckForDuplications ()
4391                 {
4392                         ArrayList ar = Parent.PartialContainer.Methods;
4393                         if (ar != null) {
4394                                 int arLen = ar.Count;
4395                                         
4396                                 for (int i = 0; i < arLen; i++) {
4397                                         Method m = (Method) ar [i];
4398                                         if (IsDuplicateImplementation (m))
4399                                                 return false;
4400                                 }
4401                         }
4402
4403                         ar = Parent.PartialContainer.Properties;
4404                         if (ar != null) {
4405                                 for (int i = 0; i < ar.Count; ++i) {
4406                                         PropertyBase pb = (PropertyBase) ar [i];
4407                                         if (pb.AreAccessorsDuplicateImplementation (this))
4408                                                 return false;
4409                                 }
4410                         }
4411
4412                         ar = Parent.PartialContainer.Indexers;
4413                         if (ar != null) {
4414                                 for (int i = 0; i < ar.Count; ++i) {
4415                                         PropertyBase pb = (PropertyBase) ar [i];
4416                                         if (pb.AreAccessorsDuplicateImplementation (this))
4417                                                 return false;
4418                                 }
4419                         }
4420
4421                         ar = Parent.PartialContainer.Events;
4422                         if (ar != null) {
4423                                 for (int i = 0; i < ar.Count; ++i) {
4424                                         Event ev = (Event) ar [i];
4425                                         if (ev.AreAccessorsDuplicateImplementation (this))
4426                                                 return false;
4427                                 }
4428                         }
4429
4430                         return true;
4431                 }
4432
4433                 //
4434                 // Creates the type
4435                 //
4436                 public override bool Define ()
4437                 {
4438                         if (!base.Define ())
4439                                 return false;
4440
4441                         if (RootContext.StdLib && (ReturnType == TypeManager.arg_iterator_type || ReturnType == TypeManager.typed_reference_type)) {
4442                                 Error1599 (Location, ReturnType);
4443                                 return false;
4444                         }
4445
4446                         if (ReturnType == TypeManager.void_type && ParameterTypes.Length == 0 && 
4447                                 Name == "Finalize" && !(this is Destructor)) {
4448                                 Report.Warning (465, 1, Location, "Introducing a 'Finalize' method can interfere with destructor invocation. Did you intend to declare a destructor?");
4449                         }
4450
4451                         if (base_method != null) {
4452                                 if (Parameters.Count == 1 && ParameterTypes [0] == TypeManager.object_type && Name == "Equals")
4453                                         Parent.PartialContainer.Mark_HasEquals ();
4454                                 else if (Parameters.Empty && Name == "GetHashCode")
4455                                         Parent.PartialContainer.Mark_HasGetHashCode ();
4456                         }
4457
4458                         //
4459                         // This is used to track the Entry Point,
4460                         //
4461                         if (RootContext.NeedsEntryPoint &&  ((ModFlags & Modifiers.STATIC) != 0) &&
4462                                 Name == "Main" &&
4463                                 (RootContext.MainClass == null ||
4464                                 RootContext.MainClass == Parent.TypeBuilder.FullName)){
4465                                 if (IsEntryPoint ()) {
4466
4467                                         if (RootContext.EntryPoint == null) {
4468                                                 if (Parent.IsGeneric || MemberName.IsGeneric) {
4469                                                         Report.Warning (402, 4, Location, "`{0}': an entry point cannot be generic or in a generic type",
4470                                                                 GetSignatureForError ());
4471                                                 } else {
4472                                                         IMethodData md = TypeManager.GetMethod (MethodBuilder);
4473                                                         md.SetMemberIsUsed ();
4474
4475                                                         RootContext.EntryPoint = MethodBuilder;
4476                                                         RootContext.EntryPointLocation = Location;
4477                                                 }
4478                                         } else {
4479                                                 Error_DuplicateEntryPoint (RootContext.EntryPoint, RootContext.EntryPointLocation);
4480                                                 Error_DuplicateEntryPoint (MethodBuilder, Location);
4481                                         }
4482                                 } else {
4483                                         Report.Warning (28, 4, Location, "`{0}' has the wrong signature to be an entry point",
4484                                                 GetSignatureForError ());
4485                                 }
4486                         }
4487
4488                         return true;
4489                 }
4490
4491                 //
4492                 // Emits the code
4493                 // 
4494                 public override void Emit ()
4495                 {
4496                         Report.Debug (64, "METHOD EMIT", this, MethodBuilder, Location, Block, MethodData);
4497                         MethodData.Emit (Parent);
4498                         base.Emit ();
4499
4500                         Block = null;
4501                         MethodData = null;
4502                 }
4503
4504                 public static void Error1599 (Location loc, Type t)
4505                 {
4506                         Report.Error (1599, loc, "Method or delegate cannot return type `{0}'", TypeManager.CSharpName (t));
4507                 }
4508
4509                 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
4510                 {
4511                         MethodInfo mi = (MethodInfo) Parent.PartialContainer.BaseCache.FindMemberToOverride (
4512                                 Parent.TypeBuilder, Name, ParameterTypes, GenericMethod, false);
4513
4514                         if (mi == null)
4515                                 return null;
4516
4517                         if (mi.IsSpecialName)
4518                                 return null;
4519
4520                         base_ret_type = mi.ReturnType;
4521                         return mi;
4522                 }
4523
4524                 protected override bool VerifyClsCompliance ()
4525                 {
4526                         if (!base.VerifyClsCompliance ())
4527                                 return false;
4528
4529                         if (ParameterInfo.Count > 0) {
4530                                 ArrayList al = (ArrayList)Parent.PartialContainer.MemberCache.Members [Name];
4531                                 if (al.Count > 1)
4532                                         MemberCache.VerifyClsParameterConflict (al, this, MethodBuilder);
4533                         }
4534
4535                         return true;
4536                 }
4537         }
4538
4539         public abstract class ConstructorInitializer {
4540                 ArrayList argument_list;
4541                 protected ConstructorInfo base_constructor;
4542                 Location loc;
4543                 
4544                 public ConstructorInitializer (ArrayList argument_list, Location loc)
4545                 {
4546                         this.argument_list = argument_list;
4547                         this.loc = loc;
4548                 }
4549
4550                 public ArrayList Arguments {
4551                         get {
4552                                 return argument_list;
4553                         }
4554                 }
4555
4556                 public bool Resolve (ConstructorBuilder caller_builder, Block block, EmitContext ec)
4557                 {
4558                         Expression base_constructor_group;
4559                         Type t;
4560                         bool error = false;
4561
4562                         ec.CurrentBlock = block;
4563
4564                         if (argument_list != null){
4565                                 foreach (Argument a in argument_list){
4566                                         if (!a.Resolve (ec, loc))
4567                                                 return false;
4568                                 }
4569                         }
4570                         ec.CurrentBlock = null;
4571
4572                         if (this is ConstructorBaseInitializer) {
4573                                 if (ec.ContainerType.BaseType == null)
4574                                         return true;
4575
4576                                 t = ec.ContainerType.BaseType;
4577                                 if (ec.ContainerType.IsValueType) {
4578                                         Report.Error (522, loc,
4579                                                 "`{0}': Struct constructors cannot call base constructors", TypeManager.CSharpSignature (caller_builder));
4580                                         return false;
4581                                 }
4582                         } else {
4583                                 //
4584                                 // It is legal to have "this" initializers that take no arguments
4585                                 // in structs, they are just no-ops.
4586                                 //
4587                                 // struct D { public D (int a) : this () {}
4588                                 //
4589                                 if (ec.ContainerType.IsValueType && argument_list == null)
4590                                         return true;
4591                                 
4592                                 t = ec.ContainerType;
4593                         }
4594
4595                         base_constructor_group = Expression.MemberLookup (
4596                                 ec.ContainerType, t, ".ctor", MemberTypes.Constructor,
4597                                 BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
4598                                 loc);
4599                         
4600                         if (base_constructor_group == null){
4601                                 error = true;
4602                                 base_constructor_group = Expression.MemberLookup (
4603                                         t, null, t, ".ctor", MemberTypes.Constructor,
4604                                         BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly,
4605                                         loc);
4606                         }
4607
4608                         int errors = Report.Errors;
4609                         if (base_constructor_group != null)
4610                                 base_constructor = (ConstructorInfo) Invocation.OverloadResolve (
4611                                         ec, (MethodGroupExpr) base_constructor_group, argument_list,
4612                                         false, loc);
4613                         
4614                         if (base_constructor == null) {
4615                                 if (errors == Report.Errors)
4616                                         Invocation.Error_WrongNumArguments (loc, TypeManager.CSharpSignature (caller_builder),
4617                                                 argument_list == null ? 0 : argument_list.Count);
4618                                 return false;
4619                         }
4620
4621                         if (error) {
4622                                 Report.SymbolRelatedToPreviousError (base_constructor);
4623                                 Expression.ErrorIsInaccesible (loc, TypeManager.CSharpSignature (base_constructor));
4624                                 base_constructor = null;
4625                                 return false;
4626                         }
4627                         
4628                         if (base_constructor == caller_builder){
4629                                 Report.Error (516, loc, "Constructor `{0}' cannot call itself", TypeManager.CSharpSignature (caller_builder));
4630                                 return false;
4631                         }
4632                         
4633                         return true;
4634                 }
4635
4636                 public virtual void Emit (EmitContext ec)
4637                 {
4638                         if (base_constructor != null){
4639                                 ec.Mark (loc, false);
4640                                 if (ec.IsStatic)
4641                                         Invocation.EmitCall (ec, true, true, null, base_constructor, argument_list, loc);
4642                                 else
4643                                         Invocation.EmitCall (ec, true, false, ec.GetThis (loc), base_constructor, argument_list, loc);
4644                         }
4645                 }
4646         }
4647
4648         public class ConstructorBaseInitializer : ConstructorInitializer {
4649                 public ConstructorBaseInitializer (ArrayList argument_list, Location l) :
4650                         base (argument_list, l)
4651                 {
4652                 }
4653         }
4654
4655         class GeneratedBaseInitializer: ConstructorBaseInitializer {
4656                 public GeneratedBaseInitializer (Location loc):
4657                         base (null, loc)
4658                 {
4659                 }
4660         }
4661
4662         public class ConstructorThisInitializer : ConstructorInitializer {
4663                 public ConstructorThisInitializer (ArrayList argument_list, Location l) :
4664                         base (argument_list, l)
4665                 {
4666                 }
4667         }
4668         
4669         public class Constructor : MethodCore, IMethodData, IAnonymousHost {
4670                 public ConstructorBuilder ConstructorBuilder;
4671                 public ConstructorInitializer Initializer;
4672                 ListDictionary declarative_security;
4673                 ArrayList anonymous_methods;
4674
4675                 // <summary>
4676                 //   Modifiers allowed for a constructor.
4677                 // </summary>
4678                 public const int AllowedModifiers =
4679                         Modifiers.PUBLIC |
4680                         Modifiers.PROTECTED |
4681                         Modifiers.INTERNAL |
4682                         Modifiers.STATIC |
4683                         Modifiers.UNSAFE |
4684                         Modifiers.EXTERN |              
4685                         Modifiers.PRIVATE;
4686
4687                 static string[] attribute_targets = new string [] { "method" };
4688
4689                 public Iterator Iterator {
4690                         get { return null; }
4691                 }
4692
4693                 bool has_compliant_args = false;
4694                 //
4695                 // The spec claims that static is not permitted, but
4696                 // my very own code has static constructors.
4697                 //
4698                 public Constructor (DeclSpace parent, string name, int mod, Parameters args,
4699                                     ConstructorInitializer init, Location loc)
4700                         : base (parent, null, null, mod, AllowedModifiers, false,
4701                                 new MemberName (name, loc), null, args)
4702                 {
4703                         Initializer = init;
4704                 }
4705
4706                 public bool HasCompliantArgs {
4707                         get { return has_compliant_args; }
4708                 }
4709
4710                 public override AttributeTargets AttributeTargets {
4711                         get { return AttributeTargets.Constructor; }
4712                 }
4713
4714
4715                 //
4716                 // Returns true if this is a default constructor
4717                 //
4718                 public bool IsDefault ()
4719                 {
4720                         if ((ModFlags & Modifiers.STATIC) != 0)
4721                                 return Parameters.Empty;
4722                         
4723                         return Parameters.Empty &&
4724                                         (Initializer is ConstructorBaseInitializer) &&
4725                                         (Initializer.Arguments == null);
4726                 }
4727
4728                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
4729                 {
4730                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
4731                                 if (declarative_security == null) {
4732                                         declarative_security = new ListDictionary ();
4733                                 }
4734                                 a.ExtractSecurityPermissionSet (declarative_security);
4735                                 return;
4736                         }
4737
4738                         if (a.Type == TypeManager.methodimpl_attr_type &&
4739                                 (a.GetMethodImplOptions () & MethodImplOptions.InternalCall) != 0) {
4740                                 ConstructorBuilder.SetImplementationFlags (MethodImplAttributes.InternalCall | MethodImplAttributes.Runtime);
4741                         }
4742
4743                         ConstructorBuilder.SetCustomAttribute (cb);
4744                 }
4745
4746                 public void AddAnonymousMethod (AnonymousMethodExpression anonymous)
4747                 {
4748                         if (anonymous_methods == null)
4749                                 anonymous_methods = new ArrayList ();
4750                         anonymous_methods.Add (anonymous);
4751                 }
4752
4753                 public bool ResolveMembers ()
4754                 {
4755                         if (anonymous_methods != null) {
4756                                 foreach (AnonymousMethodExpression ame in anonymous_methods) {
4757                                         if (!ame.CreateAnonymousHelpers ())
4758                                                 return false;
4759                                 }
4760                         }
4761
4762                         return true;
4763                 }
4764
4765                 protected override bool CheckForDuplications ()
4766                 {
4767                         ArrayList ar = Parent.PartialContainer.InstanceConstructors;
4768                         if (ar != null) {
4769                                 int arLen = ar.Count;
4770                                         
4771                                 for (int i = 0; i < arLen; i++) {
4772                                         Constructor m = (Constructor) ar [i];
4773                                         if (IsDuplicateImplementation (m))
4774                                                 return false;
4775                                 }
4776                         }
4777                         return true;
4778                 }
4779
4780                 protected override bool CheckBase ()
4781                 {
4782                         if ((ModFlags & Modifiers.STATIC) != 0) {
4783                                 if (!Parameters.Empty) {
4784                                         Report.Error (132, Location, "`{0}': The static constructor must be parameterless",
4785                                                 GetSignatureForError ());
4786                                         return false;
4787                                 }
4788
4789                                 // the rest can be ignored
4790                                 return true;
4791                         }
4792
4793                         // Check whether arguments were correct.
4794                         if (!DoDefineParameters ())
4795                                 return false;
4796
4797                         if (!CheckForDuplications ())
4798                                 return false;
4799
4800                         if (Parent.PartialContainer.Kind == Kind.Struct) {
4801                                 if (ParameterTypes.Length == 0) {
4802                                         Report.Error (568, Location, 
4803                                                 "Structs cannot contain explicit parameterless constructors");
4804                                         return false;
4805                                 }
4806
4807                                 if ((ModFlags & Modifiers.PROTECTED) != 0) {
4808                                         Report.Error (666, Location, "`{0}': new protected member declared in struct", GetSignatureForError ());
4809                                         return false;
4810                                 }
4811                         }
4812
4813                         if ((RootContext.WarningLevel >= 4) && ((Parent.ModFlags & Modifiers.SEALED) != 0 && (ModFlags & Modifiers.PROTECTED) != 0)) {
4814                                 Report.Warning (628, 4, Location, "`{0}': new protected member declared in sealed class", GetSignatureForError ());
4815                         }
4816                         
4817                         return true;
4818                 }
4819                 
4820                 //
4821                 // Creates the ConstructorBuilder
4822                 //
4823                 public override bool Define ()
4824                 {
4825                         if (ConstructorBuilder != null)
4826                                 return true;
4827
4828                         MethodAttributes ca = (MethodAttributes.RTSpecialName |
4829                                                MethodAttributes.SpecialName);
4830                         
4831                         if ((ModFlags & Modifiers.STATIC) != 0) {
4832                                 ca |= MethodAttributes.Static | MethodAttributes.Private;
4833                         } else {
4834                                 ca |= MethodAttributes.HideBySig;
4835
4836                                 if ((ModFlags & Modifiers.PUBLIC) != 0)
4837                                         ca |= MethodAttributes.Public;
4838                                 else if ((ModFlags & Modifiers.PROTECTED) != 0){
4839                                         if ((ModFlags & Modifiers.INTERNAL) != 0)
4840                                                 ca |= MethodAttributes.FamORAssem;
4841                                         else 
4842                                                 ca |= MethodAttributes.Family;
4843                                 } else if ((ModFlags & Modifiers.INTERNAL) != 0)
4844                                         ca |= MethodAttributes.Assembly;
4845                                 else
4846                                         ca |= MethodAttributes.Private;
4847                         }
4848
4849                         if (!CheckAbstractAndExtern (block != null))
4850                                 return false;
4851                         
4852                         // Check if arguments were correct.
4853                         if (!CheckBase ())
4854                                 return false;
4855
4856                         ConstructorBuilder = Parent.TypeBuilder.DefineConstructor (
4857                                 ca, CallingConventions,
4858                                 ParameterTypes);
4859
4860                         if ((ModFlags & Modifiers.UNSAFE) != 0)
4861                                 ConstructorBuilder.InitLocals = false;
4862
4863                         if (Parent.PartialContainer.IsComImport) {
4864                                 if (!IsDefault ()) {
4865                                         Report.Error (669, Location, "`{0}': A class with the ComImport attribute cannot have a user-defined constructor",
4866                                                 Parent.GetSignatureForError ());
4867                                         return false;
4868                                 }
4869                                 ConstructorBuilder.SetImplementationFlags (MethodImplAttributes.InternalCall);
4870                         }
4871                         
4872                         TypeManager.AddMethod (ConstructorBuilder, this);
4873
4874                         return true;
4875                 }
4876
4877                 //
4878                 // Emits the code
4879                 //
4880                 public override void Emit ()
4881                 {
4882                         if (OptAttributes != null)
4883                                 OptAttributes.Emit ();
4884
4885                         EmitContext ec = CreateEmitContext (null, null);
4886
4887                         if (block != null) {
4888                                 // If this is a non-static `struct' constructor and doesn't have any
4889                                 // initializer, it must initialize all of the struct's fields.
4890                                 if ((Parent.PartialContainer.Kind == Kind.Struct) &&
4891                                         ((ModFlags & Modifiers.STATIC) == 0) && (Initializer == null))
4892                                         block.AddThisVariable (Parent, Location);
4893
4894                                 if (!block.ResolveMeta (ec, ParameterInfo))
4895                                         block = null;
4896                         }
4897
4898                         if ((ModFlags & Modifiers.STATIC) == 0){
4899                                 if (Parent.PartialContainer.Kind == Kind.Class && Initializer == null)
4900                                         Initializer = new GeneratedBaseInitializer (Location);
4901
4902
4903                                 //
4904                                 // Spec mandates that Initializers will not have
4905                                 // `this' access
4906                                 //
4907                                 ec.IsStatic = true;
4908                                 if ((Initializer != null) &&
4909                                     !Initializer.Resolve (ConstructorBuilder, block, ec))
4910                                         return;
4911                                 ec.IsStatic = false;
4912                         }
4913
4914                         Parameters.ApplyAttributes (ConstructorBuilder);
4915                         
4916                         SourceMethod source = SourceMethod.Create (
4917                                 Parent, ConstructorBuilder, block);
4918
4919                         //
4920                         // Classes can have base initializers and instance field initializers.
4921                         //
4922                         if (Parent.PartialContainer.Kind == Kind.Class){
4923                                 if ((ModFlags & Modifiers.STATIC) == 0){
4924
4925                                         //
4926                                         // If we use a "this (...)" constructor initializer, then
4927                                         // do not emit field initializers, they are initialized in the other constructor
4928                                         //
4929                                         if (!(Initializer != null && Initializer is ConstructorThisInitializer))
4930                                                 Parent.PartialContainer.EmitFieldInitializers (ec);
4931                                 }
4932                         }
4933
4934                         bool unreachable = false;
4935                         if (block != null) {
4936                                 ec.ResolveTopBlock (null, block, ParameterInfo, this, out unreachable);
4937                                 ec.EmitMeta (block);
4938
4939                                 if (block.ScopeInfo != null) {
4940                                         ExpressionStatement init = block.ScopeInfo.GetScopeInitializer (ec);
4941                                         init.EmitStatement (ec);
4942                                 }
4943                         }
4944
4945                         if (Initializer != null) {
4946                                 Initializer.Emit (ec);
4947                         }
4948                         
4949                         if ((ModFlags & Modifiers.STATIC) != 0)
4950                                 Parent.PartialContainer.EmitFieldInitializers (ec);
4951
4952                         if (block != null)
4953                                 ec.EmitResolvedTopBlock (block, unreachable);
4954
4955                         if (source != null)
4956                                 source.CloseMethod ();
4957
4958                         base.Emit ();
4959
4960                         if (declarative_security != null) {
4961                                 foreach (DictionaryEntry de in declarative_security) {
4962                                         ConstructorBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
4963                                 }
4964                         }
4965
4966                         block = null;
4967                 }
4968
4969                 // Is never override
4970                 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
4971                 {
4972                         return null;
4973                 }
4974
4975                 public override string GetSignatureForError()
4976                 {
4977                         return base.GetSignatureForError () + Parameters.GetSignatureForError ();
4978                 }
4979
4980                 public override string[] ValidAttributeTargets {
4981                         get {
4982                                 return attribute_targets;
4983                         }
4984                 }
4985
4986                 protected override bool VerifyClsCompliance ()
4987                 {
4988                         if (!base.VerifyClsCompliance () || !IsExposedFromAssembly ()) {
4989                                 return false;
4990                         }
4991                         
4992                         if (ParameterInfo.Count > 0) {
4993                                 ArrayList al = (ArrayList)Parent.MemberCache.Members [".ctor"];
4994                                 if (al.Count > 3)
4995                                         MemberCache.VerifyClsParameterConflict (al, this, ConstructorBuilder);
4996  
4997                                 if (Parent.TypeBuilder.IsSubclassOf (TypeManager.attribute_type)) {
4998                                         foreach (Type param in ParameterTypes) {
4999                                                 if (param.IsArray) {
5000                                                         return true;
5001                                                 }
5002                                         }
5003                                 }
5004                         }
5005                         has_compliant_args = true;
5006                         return true;
5007                 }
5008
5009                 #region IMethodData Members
5010
5011                 public System.Reflection.CallingConventions CallingConventions {
5012                         get {
5013                                 CallingConventions cc = Parameters.CallingConvention;
5014
5015                                 if (Parent.PartialContainer.Kind == Kind.Class)
5016                                         if ((ModFlags & Modifiers.STATIC) == 0)
5017                                                 cc |= CallingConventions.HasThis;
5018
5019                                 // FIXME: How is `ExplicitThis' used in C#?
5020                         
5021                                 return cc;
5022                         }
5023                 }
5024
5025                 public new Location Location {
5026                         get {
5027                                 return base.Location;
5028                         }
5029                 }
5030
5031                 public MemberName MethodName {
5032                         get {
5033                                 return MemberName;
5034                         }
5035                 }
5036
5037                 public Type ReturnType {
5038                         get {
5039                                 return MemberType;
5040                         }
5041                 }
5042
5043                 public EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig)
5044                 {
5045                         ILGenerator ig_ = ConstructorBuilder.GetILGenerator ();
5046                         return new EmitContext (this, Parent, Location, ig_, null, ModFlags, true);
5047                 }
5048
5049                 public bool IsExcluded()
5050                 {
5051                         return false;
5052                 }
5053
5054                 GenericMethod IMethodData.GenericMethod {
5055                         get {
5056                                 return null;
5057                         }
5058                 }
5059
5060                 #endregion
5061         }
5062
5063         /// <summary>
5064         /// Interface for MethodData class. Holds links to parent members to avoid member duplication.
5065         /// </summary>
5066         public interface IMethodData
5067         {
5068                 CallingConventions CallingConventions { get; }
5069                 Location Location { get; }
5070                 MemberName MethodName { get; }
5071                 Type ReturnType { get; }
5072                 GenericMethod GenericMethod { get; }
5073                 Parameters ParameterInfo { get; }
5074
5075                 Iterator Iterator { get; }
5076
5077                 Attributes OptAttributes { get; }
5078                 ToplevelBlock Block { get; set; }
5079
5080                 EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig);
5081                 ObsoleteAttribute GetObsoleteAttribute ();
5082                 string GetSignatureForError ();
5083                 bool IsExcluded ();
5084                 bool IsClsComplianceRequired ();
5085                 void SetMemberIsUsed ();
5086         }
5087
5088         //
5089         // Encapsulates most of the Method's state
5090         //
5091         public class MethodData {
5092
5093                 readonly IMethodData method;
5094
5095                 public readonly GenericMethod GenericMethod;
5096
5097                 //
5098                 // Are we implementing an interface ?
5099                 //
5100                 public MethodInfo implementing;
5101
5102                 //
5103                 // Protected data.
5104                 //
5105                 protected InterfaceMemberBase member;
5106                 protected int modifiers;
5107                 protected MethodAttributes flags;
5108                 protected Type declaring_type;
5109                 protected MethodInfo parent_method;
5110
5111                 MethodBuilder builder = null;
5112                 public MethodBuilder MethodBuilder {
5113                         get {
5114                                 return builder;
5115                         }
5116                 }
5117
5118                 public Type DeclaringType {
5119                         get {
5120                                 return declaring_type;
5121                         }
5122                 }
5123
5124                 public MethodData (InterfaceMemberBase member,
5125                                    int modifiers, MethodAttributes flags, IMethodData method)
5126                 {
5127                         this.member = member;
5128                         this.modifiers = modifiers;
5129                         this.flags = flags;
5130
5131                         this.method = method;
5132                 }
5133
5134                 public MethodData (InterfaceMemberBase member, 
5135                                    int modifiers, MethodAttributes flags, 
5136                                    IMethodData method, MethodBuilder builder,
5137                                    GenericMethod generic, MethodInfo parent_method)
5138                         : this (member, modifiers, flags, method)
5139                 {
5140                         this.builder = builder;
5141                         this.GenericMethod = generic;
5142                         this.parent_method = parent_method;
5143                 }
5144
5145                 public bool Define (DeclSpace parent)
5146                 {
5147                         string name = method.MethodName.Basename;
5148                         string method_name = method.MethodName.FullName;
5149
5150                         TypeContainer container = parent.PartialContainer;
5151
5152                         PendingImplementation pending = container.PendingImplementations;
5153                         if (pending != null){
5154                                 if (member is Indexer) // TODO: test it, but it should work without this IF
5155                                         implementing = pending.IsInterfaceIndexer (
5156                                                 member.InterfaceType, method.ReturnType, method.ParameterInfo);
5157                                 else
5158                                         implementing = pending.IsInterfaceMethod (
5159                                                 member.InterfaceType, name, method.ReturnType, method.ParameterInfo);
5160
5161                                 if (member.InterfaceType != null){
5162                                         if (implementing == null){
5163                                                 if (member is PropertyBase) {
5164                                                         Report.Error (550, method.Location, "`{0}' is an accessor not found in interface member `{1}{2}'",
5165                                                                       method.GetSignatureForError (), TypeManager.CSharpName (member.InterfaceType),
5166                                                                       member.GetSignatureForError ().Substring (member.GetSignatureForError ().LastIndexOf ('.')));
5167
5168                                                 } else {
5169                                                         Report.Error (539, method.Location,
5170                                                                       "`{0}.{1}' in explicit interface declaration is not a member of interface",
5171                                                                       TypeManager.CSharpName (member.InterfaceType), member.ShortName);
5172                                                 }
5173                                                 return false;
5174                                         }
5175                                         if (implementing.IsSpecialName && !(method is AbstractPropertyEventMethod)) {
5176                                                 Report.SymbolRelatedToPreviousError (implementing);
5177                                                 Report.Error (683, method.Location, "`{0}' explicit method implementation cannot implement `{1}' because it is an accessor",
5178                                                         member.GetSignatureForError (), TypeManager.CSharpSignature (implementing));
5179                                                 return false;
5180                                         }
5181
5182                                         method_name = TypeManager.GetFullName (member.InterfaceType) +
5183                                                 '.' + method_name;
5184                                 } else {
5185                                         if (implementing != null) {
5186                                                 AbstractPropertyEventMethod prop_method = method as AbstractPropertyEventMethod;
5187                                                 if (prop_method == null) {
5188                                                         if (implementing.IsSpecialName) {
5189                                                                 Report.SymbolRelatedToPreviousError (implementing);
5190                                                                 Report.Error (470, method.Location, "Method `{0}' cannot implement interface accessor `{1}.{2}'",
5191                                                                         method.GetSignatureForError (), TypeManager.CSharpSignature (implementing),
5192                                                                         implementing.Name.StartsWith ("get_") ? "get" : "set");
5193                                                                 return false;
5194                                                         }
5195                                                 } else if (implementing.DeclaringType.IsInterface) {
5196                                                         if (!implementing.IsSpecialName) {
5197                                                                 Report.SymbolRelatedToPreviousError (implementing);
5198                                                                 Report.Error (686, method.Location, "Accessor `{0}' cannot implement interface member `{1}' for type `{2}'. Use an explicit interface implementation",
5199                                                                         method.GetSignatureForError (), TypeManager.CSharpSignature (implementing), container.GetSignatureForError ());
5200                                                                 return false;
5201                                                         }
5202                                                         PropertyBase.PropertyMethod pm = prop_method as PropertyBase.PropertyMethod;
5203                                                         if (pm != null && pm.HasCustomAccessModifier && (pm.ModFlags & Modifiers.PUBLIC) == 0) {
5204                                                                 Report.SymbolRelatedToPreviousError (implementing);
5205                                                                 Report.Error (277, method.Location, "Accessor `{0}' must be declared public to implement interface member `{1}'",
5206                                                                         method.GetSignatureForError (), TypeManager.CSharpSignature (implementing, true));
5207                                                                 return false;
5208                                                         }
5209                                                 }
5210                                         }
5211                                 }
5212                         }
5213
5214                         //
5215                         // For implicit implementations, make sure we are public, for
5216                         // explicit implementations, make sure we are private.
5217                         //
5218                         if (implementing != null){
5219                                 //
5220                                 // Setting null inside this block will trigger a more
5221                                 // verbose error reporting for missing interface implementations
5222                                 //
5223                                 // The "candidate" function has been flagged already
5224                                 // but it wont get cleared
5225                                 //
5226                                 if (member.IsExplicitImpl){
5227                                         if (method.ParameterInfo.HasParams && !TypeManager.GetParameterData (implementing).HasParams) {
5228                                                 Report.SymbolRelatedToPreviousError (implementing);
5229                                                 Report.Error (466, method.Location, "`{0}': the explicit interface implementation cannot introduce the params modifier",
5230                                                         method.GetSignatureForError ());
5231                                                 return false;
5232                                         }
5233                                 } else {
5234                                         if (implementing.DeclaringType.IsInterface) {
5235                                                 //
5236                                                 // If this is an interface method implementation,
5237                                                 // check for public accessibility
5238                                                 //
5239                                                 if ((flags & MethodAttributes.MemberAccessMask) != MethodAttributes.Public)
5240                                                         implementing = null;
5241                                         } else if ((flags & MethodAttributes.MemberAccessMask) == MethodAttributes.Private){
5242                                                 // We may never be private.
5243                                                 implementing = null;
5244                                         } else if ((modifiers & Modifiers.OVERRIDE) == 0){
5245                                                 //
5246                                                 // We may be protected if we're overriding something.
5247                                                 //
5248                                                 implementing = null;
5249                                         }
5250                                 }
5251                                         
5252                                 //
5253                                 // Static is not allowed
5254                                 //
5255                                 if ((modifiers & Modifiers.STATIC) != 0){
5256                                         implementing = null;
5257                                 }
5258                         }
5259                         
5260                         //
5261                         // If implementing is still valid, set flags
5262                         //
5263                         if (implementing != null){
5264                                 //
5265                                 // When implementing interface methods, set NewSlot
5266                                 // unless, we are overwriting a method.
5267                                 //
5268                                 if (implementing.DeclaringType.IsInterface){
5269                                         if ((modifiers & Modifiers.OVERRIDE) == 0)
5270                                                 flags |= MethodAttributes.NewSlot;
5271                                 }
5272                                 flags |=
5273                                         MethodAttributes.Virtual |
5274                                         MethodAttributes.HideBySig;
5275
5276                                 // Set Final unless we're virtual, abstract or already overriding a method.
5277                                 if ((modifiers & (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE)) == 0)
5278                                         flags |= MethodAttributes.Final;
5279                         }
5280
5281                         EmitContext ec = method.CreateEmitContext (container, null);
5282
5283                         DefineMethodBuilder (container, method_name, method.ParameterInfo.Types);
5284
5285                         if (builder == null)
5286                                 return false;
5287
5288                         if (container.CurrentType != null)
5289                                 declaring_type = container.CurrentType;
5290                         else
5291                                 declaring_type = container.TypeBuilder;
5292
5293                         if ((modifiers & Modifiers.UNSAFE) != 0)
5294                                 builder.InitLocals = false;
5295
5296                         if (implementing != null){
5297                                 //
5298                                 // clear the pending implemntation flag
5299                                 //
5300                                 if (member is Indexer) {
5301                                         pending.ImplementIndexer (
5302                                                 member.InterfaceType, builder, method.ReturnType,
5303                                                 method.ParameterInfo, member.IsExplicitImpl);
5304                                 } else
5305                                         pending.ImplementMethod (
5306                                                 member.InterfaceType, name, method.ReturnType,
5307                                                 method.ParameterInfo, member.IsExplicitImpl);
5308
5309                                 if (member.IsExplicitImpl)
5310                                         container.TypeBuilder.DefineMethodOverride (
5311                                                 builder, implementing);
5312
5313                         }
5314
5315                         TypeManager.AddMethod (builder, method);
5316
5317                         if (GenericMethod != null) {
5318                                 bool is_override = member.IsExplicitImpl |
5319                                         ((modifiers & Modifiers.OVERRIDE) != 0);
5320
5321                                 if (implementing != null)
5322                                         parent_method = implementing;
5323
5324                                 if (!GenericMethod.DefineType (ec, builder, parent_method, is_override))
5325                                         return false;
5326                         }
5327
5328                         return true;
5329                 }
5330
5331
5332                 /// <summary>
5333                 /// Create the MethodBuilder for the method 
5334                 /// </summary>
5335                 void DefineMethodBuilder (TypeContainer container, string method_name, Type[] ParameterTypes)
5336                 {
5337                         if ((modifiers & Modifiers.EXTERN) != 0) {
5338
5339                                 if (method.OptAttributes != null) {
5340                                         Attribute dllimport_attribute = method.OptAttributes.Search (TypeManager.dllimport_type);
5341                                         if (dllimport_attribute != null) {
5342                                                 flags |= MethodAttributes.PinvokeImpl;
5343                                                 builder = dllimport_attribute.DefinePInvokeMethod (
5344                                                         container.TypeBuilder, method_name, flags,
5345                                                         method.ReturnType, ParameterTypes);
5346
5347                                                 return;
5348                                         }
5349                                 }
5350
5351                                 // for extern static method must be specified either DllImport attribute or MethodImplAttribute.
5352                                 // We are more strict than Microsoft and report CS0626 like error
5353                                 if (method.OptAttributes == null ||
5354                                         !method.OptAttributes.Contains (TypeManager.methodimpl_attr_type)) {
5355                                         Report.Error (626, method.Location,
5356                                                 "`{0}' is marked as an external but has no DllImport attribute. Consider adding a DllImport attribute to specify the external implementation",
5357                                                 member.GetSignatureForError ());
5358                                         return;
5359                                 }
5360                         }
5361
5362                         if (builder == null) {
5363                                 builder = container.TypeBuilder.DefineMethod (
5364                                         method_name, flags, method.CallingConventions,
5365                                         method.ReturnType, ParameterTypes);
5366                                 return;
5367                         }
5368
5369 #if GMCS_SOURCE && !MS_COMPATIBLE
5370                         builder.SetGenericMethodSignature (
5371                                 flags, method.CallingConventions,
5372                                 method.ReturnType, ParameterTypes);
5373 #endif
5374                 }
5375
5376                 //
5377                 // Emits the code
5378                 // 
5379                 public void Emit (DeclSpace parent)
5380                 {
5381                         EmitContext ec;
5382                         if ((flags & MethodAttributes.PinvokeImpl) == 0)
5383                                 ec = method.CreateEmitContext (parent, builder.GetILGenerator ());
5384                         else
5385                                 ec = method.CreateEmitContext (parent, null);
5386
5387                         method.ParameterInfo.ApplyAttributes (MethodBuilder);
5388
5389                         if (GenericMethod != null)
5390                                 GenericMethod.EmitAttributes ();
5391
5392                         ToplevelBlock block = method.Block;
5393                         
5394                         SourceMethod source = SourceMethod.Create (parent, MethodBuilder, method.Block);
5395
5396                         //
5397                         // Handle destructors specially
5398                         //
5399                         // FIXME: This code generates buggy code
5400                         //
5401                         if (member is Destructor)
5402                                 EmitDestructor (ec, block);
5403                         else
5404                                 ec.EmitTopBlock (method, block);
5405
5406                         if (source != null)
5407                                 source.CloseMethod ();
5408                 }
5409
5410                 void EmitDestructor (EmitContext ec, ToplevelBlock block)
5411                 {
5412                         ILGenerator ig = ec.ig;
5413                         
5414                         Label finish = ig.DefineLabel ();
5415
5416                         block.SetDestructor ();
5417                         
5418                         ig.BeginExceptionBlock ();
5419                         ec.ReturnLabel = finish;
5420                         ec.HasReturnLabel = true;
5421                         ec.EmitTopBlock (method, block);
5422                         
5423                         // ig.MarkLabel (finish);
5424                         ig.BeginFinallyBlock ();
5425                         
5426                         if (ec.ContainerType.BaseType != null) {
5427                                 Expression member_lookup = Expression.MemberLookup (
5428                                         ec.ContainerType.BaseType, null, ec.ContainerType.BaseType,
5429                                         "Finalize", MemberTypes.Method, Expression.AllBindingFlags, method.Location);
5430
5431                                 if (member_lookup != null){
5432                                         MethodGroupExpr base_destructor = ((MethodGroupExpr) member_lookup);
5433                                 
5434                                         ig.Emit (OpCodes.Ldarg_0);
5435                                         ig.Emit (OpCodes.Call, (MethodInfo) base_destructor.Methods [0]);
5436                                 }
5437                         }
5438                         
5439                         ig.EndExceptionBlock ();
5440                         //ig.MarkLabel (ec.ReturnLabel);
5441                         ig.Emit (OpCodes.Ret);
5442                 }
5443         }
5444
5445         // TODO: Should derive from MethodCore
5446         public class Destructor : Method {
5447
5448                 static string[] attribute_targets = new string [] { "method" };
5449
5450                 public Destructor (DeclSpace parent, Expression return_type, int mod,
5451                                    string name, Parameters parameters, Attributes attrs,
5452                                    Location l)
5453                         : base (parent, null, return_type, mod, false, new MemberName (name, l),
5454                                 parameters, attrs)
5455                 { }
5456
5457                 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
5458                 {
5459                         if (a.Type == TypeManager.conditional_attribute_type) {
5460                                 Error_ConditionalAttributeIsNotValid ();
5461                                 return;
5462                         }
5463
5464                         base.ApplyAttributeBuilder (a, cb);
5465                 }
5466
5467                 public override string GetSignatureForError ()
5468                 {
5469                         return Parent.GetSignatureForError () + ".~" + Parent.MemberName.Name + "()";
5470                 }
5471
5472                 public override string[] ValidAttributeTargets {
5473                         get {
5474                                 return attribute_targets;
5475                         }
5476                 }
5477         }
5478         
5479         abstract public class MemberBase : MemberCore {
5480                 public Expression Type;
5481                 public readonly DeclSpace ds;
5482                 public readonly GenericMethod GenericMethod;
5483
5484                 //
5485                 // The type of this property / indexer / event
5486                 //
5487                 protected Type member_type;
5488                 public Type MemberType {
5489                         get {
5490                                 if (member_type == null && Type != null) {
5491                                         IResolveContext rc = GenericMethod == null ? this : (IResolveContext)ds;
5492                                         Type = Type.ResolveAsTypeTerminal (rc, false);
5493                                         if (Type != null) {
5494                                                 member_type = Type.Type;
5495                                         }
5496                                 }
5497                                 return member_type;
5498                         }
5499                 }
5500
5501                 //
5502                 // The constructor is only exposed to our children
5503                 //
5504                 protected MemberBase (DeclSpace parent, GenericMethod generic,
5505                                       Expression type, int mod, int allowed_mod, int def_mod,
5506                                       MemberName name, Attributes attrs)
5507                         : base (parent, name, attrs)
5508                 {
5509                         this.ds = generic != null ? generic : (DeclSpace) parent;
5510                         Type = type;
5511                         ModFlags = Modifiers.Check (allowed_mod, mod, def_mod, Location);
5512                         GenericMethod = generic;
5513                         if (GenericMethod != null)
5514                                 GenericMethod.ModFlags = ModFlags;
5515                 }
5516
5517                 protected virtual bool CheckBase ()
5518                 {
5519                         if ((ModFlags & Modifiers.PROTECTED) != 0 && Parent.PartialContainer.Kind == Kind.Struct) {
5520                                 Report.Error (666, Location, "`{0}': new protected member declared in struct", GetSignatureForError ());
5521                                 return false;
5522                         }
5523    
5524                         if ((RootContext.WarningLevel >= 4) &&
5525                             ((Parent.ModFlags & Modifiers.SEALED) != 0) &&
5526                             ((ModFlags & Modifiers.PROTECTED) != 0) &&
5527                             ((ModFlags & Modifiers.OVERRIDE) == 0) && (Name != "Finalize")) {
5528                                 Report.Warning (628, 4, Location, "`{0}': new protected member declared in sealed class", GetSignatureForError ());
5529                         }
5530                                 return true;
5531                 }
5532
5533                 protected virtual bool DoDefine ()
5534                 {
5535                         if (MemberType == null)
5536                                 return false;
5537
5538                         if ((Parent.ModFlags & Modifiers.SEALED) != 0 && 
5539                                 (ModFlags & (Modifiers.VIRTUAL|Modifiers.ABSTRACT)) != 0) {
5540                                         Report.Error (549, Location, "New virtual member `{0}' is declared in a sealed class `{1}'",
5541                                                 GetSignatureForError (), Parent.GetSignatureForError ());
5542                                         return false;
5543                         }
5544                         
5545                         // verify accessibility
5546                         if (!Parent.AsAccessible (MemberType, ModFlags)) {
5547                                 Report.SymbolRelatedToPreviousError (MemberType);
5548                                 if (this is Property)
5549                                         Report.Error (53, Location,
5550                                                       "Inconsistent accessibility: property type `" +
5551                                                       TypeManager.CSharpName (MemberType) + "' is less " +
5552                                                       "accessible than property `" + GetSignatureForError () + "'");
5553                                 else if (this is Indexer)
5554                                         Report.Error (54, Location,
5555                                                       "Inconsistent accessibility: indexer return type `" +
5556                                                       TypeManager.CSharpName (MemberType) + "' is less " +
5557                                                       "accessible than indexer `" + GetSignatureForError () + "'");
5558                                 else if (this is MethodCore) {
5559                                         if (this is Operator)
5560                                                 Report.Error (56, Location,
5561                                                               "Inconsistent accessibility: return type `" +
5562                                                               TypeManager.CSharpName (MemberType) + "' is less " +
5563                                                               "accessible than operator `" + GetSignatureForError () + "'");
5564                                         else
5565                                                 Report.Error (50, Location,
5566                                                               "Inconsistent accessibility: return type `" +
5567                                                               TypeManager.CSharpName (MemberType) + "' is less " +
5568                                                               "accessible than method `" + GetSignatureForError () + "'");
5569                                 } else {
5570                                         Report.Error (52, Location,
5571                                                       "Inconsistent accessibility: field type `" +
5572                                                       TypeManager.CSharpName (MemberType) + "' is less " +
5573                                                       "accessible than field `" + GetSignatureForError () + "'");
5574                                 }
5575                                 return false;
5576                         }
5577
5578                         return true;
5579                 }
5580
5581                 protected bool IsTypePermitted ()
5582                 {
5583                         if (MemberType == TypeManager.arg_iterator_type || MemberType == TypeManager.typed_reference_type) {
5584                                 Report.Error (610, Location, "Field or property cannot be of type `{0}'", TypeManager.CSharpName (MemberType));
5585                                 return false;
5586                         }
5587                         return true;
5588                 }
5589         }
5590
5591         //
5592         // Abstract class for all fields
5593         //
5594         abstract public class FieldBase : MemberBase {
5595                 public FieldBuilder FieldBuilder;
5596                 public Status status;
5597                 protected Expression initializer;
5598
5599                 [Flags]
5600                 public enum Status : byte {
5601                         HAS_OFFSET = 4          // Used by FieldMember.
5602                 }
5603
5604                 static readonly string[] attribute_targets = new string [] { "field" };
5605
5606                 protected FieldBase (DeclSpace parent, Expression type, int mod,
5607                                      int allowed_mod, MemberName name, Attributes attrs)
5608                         : base (parent, null, type, mod, allowed_mod | Modifiers.ABSTRACT, Modifiers.PRIVATE,
5609                                 name, attrs)
5610                 {
5611                         if ((mod & Modifiers.ABSTRACT) != 0)
5612                                 Report.Error (681, Location, "The modifier 'abstract' is not valid on fields. Try using a property instead");
5613                 }
5614
5615                 public override AttributeTargets AttributeTargets {
5616                         get {
5617                                 return AttributeTargets.Field;
5618                         }
5619                 }
5620
5621                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
5622                 {
5623                         if (a.Type == TypeManager.field_offset_attribute_type) {
5624                                 status |= Status.HAS_OFFSET;
5625
5626                                 if (!Parent.PartialContainer.HasExplicitLayout) {
5627                                         Report.Error (636, Location, "The FieldOffset attribute can only be placed on members of types marked with the StructLayout(LayoutKind.Explicit)");
5628                                         return;
5629                                 }
5630
5631                                 if ((ModFlags & Modifiers.STATIC) != 0 || this is Const) {
5632                                         Report.Error (637, Location, "The FieldOffset attribute is not allowed on static or const fields");
5633                                         return;
5634                                 }
5635                         }
5636
5637 #if NET_2_0
5638                         if (a.Type == TypeManager.fixed_buffer_attr_type) {
5639                                 Report.Error (1716, Location, "Do not use 'System.Runtime.CompilerServices.FixedBuffer' attribute. Use the 'fixed' field modifier instead");
5640                                 return;
5641                         }
5642 #endif
5643
5644                         if (a.Type == TypeManager.marshal_as_attr_type) {
5645                                 UnmanagedMarshal marshal = a.GetMarshal (this);
5646                                 if (marshal != null) {
5647                                         FieldBuilder.SetMarshal (marshal);
5648                                 }
5649                                 return;
5650                         }
5651
5652                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
5653                                 a.Error_InvalidSecurityParent ();
5654                                 return;
5655                         }
5656
5657                         FieldBuilder.SetCustomAttribute (cb);
5658                 }
5659
5660                 protected override bool CheckBase ()
5661                 {
5662                         if (!base.CheckBase ())
5663                                 return false;
5664  
5665                         MemberInfo conflict_symbol = Parent.PartialContainer.FindBaseMemberWithSameName (Name, false);
5666                         if (conflict_symbol == null) {
5667                                 if ((ModFlags & Modifiers.NEW) != 0) {
5668                                         Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
5669                                 }
5670                                 return true;
5671                         }
5672  
5673                         if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE)) == 0) {
5674                                 Report.SymbolRelatedToPreviousError (conflict_symbol);
5675                                 Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
5676                                         GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
5677                         }
5678  
5679                         return true;
5680                 }
5681
5682                 public override bool Define()
5683                 {
5684                         if (MemberType == null || Type == null)
5685                                 return false;
5686
5687                         if (MemberType == TypeManager.void_type) {
5688                                 // TODO: wrong location
5689                                 Expression.Error_VoidInvalidInTheContext (Location);
5690                                 return false;
5691                         }
5692
5693                         if (MemberType.IsSealed && MemberType.IsAbstract) {
5694                                 Error_VariableOfStaticClass (Location, GetSignatureForError (), MemberType);
5695                                 return false;
5696                         }
5697
5698                         if (!CheckBase ())
5699                                 return false;
5700                         
5701                         if (!Parent.AsAccessible (MemberType, ModFlags)) {
5702                                 Report.Error (52, Location,
5703                                         "Inconsistent accessibility: field type `" +
5704                                         TypeManager.CSharpName (MemberType) + "' is less " +
5705                                         "accessible than field `" + GetSignatureForError () + "'");
5706                                 return false;
5707                         }
5708
5709                         if (!IsTypePermitted ())
5710                                 return false;
5711
5712                         return true;
5713                 }
5714
5715                 //
5716                 //   Represents header string for documentation comment.
5717                 //
5718                 public override string DocCommentHeader {
5719                         get { return "F:"; }
5720                 }
5721
5722                 public override void Emit ()
5723                 {
5724                         if (OptAttributes != null) {
5725                                 OptAttributes.Emit ();
5726                         }
5727
5728                         if (((status & Status.HAS_OFFSET) == 0) && (ModFlags & Modifiers.STATIC) == 0 && Parent.PartialContainer.HasExplicitLayout) {
5729                                 Report.Error (625, Location, "`{0}': Instance field types marked with StructLayout(LayoutKind.Explicit) must have a FieldOffset attribute.", GetSignatureForError ());
5730                         }
5731
5732                         base.Emit ();
5733                 }
5734
5735                 public static void Error_VariableOfStaticClass (Location loc, string variableName, Type staticClass)
5736                 {
5737                         Report.SymbolRelatedToPreviousError (staticClass);
5738                         Report.Error (723, loc, "`{0}': cannot declare variables of static types",
5739                                 variableName);
5740                 }
5741
5742                 public Expression Initializer {
5743                         set {
5744                                 if (value != null) {
5745                                         this.initializer = value;
5746                                 }
5747                         }
5748                 }
5749
5750                 protected virtual bool IsFieldClsCompliant {
5751                         get {
5752                                 if (FieldBuilder == null)
5753                                         return true;
5754
5755                                 return AttributeTester.IsClsCompliant (FieldBuilder.FieldType);
5756                         }
5757                 }
5758
5759                 public override string[] ValidAttributeTargets 
5760                 {
5761                         get {
5762                                 return attribute_targets;
5763                         }
5764                 }
5765
5766                 protected override bool VerifyClsCompliance ()
5767                 {
5768                         if (!base.VerifyClsCompliance ())
5769                                 return false;
5770
5771                         if (!IsFieldClsCompliant) {
5772                                 Report.Error (3003, Location, "Type of `{0}' is not CLS-compliant", GetSignatureForError ());
5773                         }
5774                         return true;
5775                 }
5776
5777                 public void SetAssigned ()
5778                 {
5779                         caching_flags |= Flags.IsAssigned;
5780                 }
5781         }
5782
5783         interface IFixedBuffer
5784         {
5785                 FieldInfo Element { get; }
5786                 Type ElementType { get; }
5787         }
5788
5789         public class FixedFieldExternal: IFixedBuffer
5790         {
5791                 FieldInfo element_field;
5792
5793                 public FixedFieldExternal (FieldInfo fi)
5794                 {
5795                         element_field = fi.FieldType.GetField (FixedField.FixedElementName);
5796                 }
5797
5798                 #region IFixedField Members
5799
5800                 public FieldInfo Element {
5801                         get {
5802                                 return element_field;
5803                         }
5804                 }
5805
5806                 public Type ElementType {
5807                         get {
5808                                 return element_field.FieldType;
5809                         }
5810                 }
5811
5812                 #endregion
5813         }
5814
5815         /// <summary>
5816         /// Fixed buffer implementation
5817         /// </summary>
5818         public class FixedField : FieldBase, IFixedBuffer
5819         {
5820                 public const string FixedElementName = "FixedElementField";
5821                 static int GlobalCounter = 0;
5822                 static object[] ctor_args = new object[] { (short)LayoutKind.Sequential };
5823                 static FieldInfo[] fi;
5824
5825                 TypeBuilder fixed_buffer_type;
5826                 FieldBuilder element;
5827                 Expression size_expr;
5828                 int buffer_size;
5829
5830                 const int AllowedModifiers =
5831                         Modifiers.NEW |
5832                         Modifiers.PUBLIC |
5833                         Modifiers.PROTECTED |
5834                         Modifiers.INTERNAL |
5835                         Modifiers.PRIVATE;
5836
5837                 public FixedField (DeclSpace parent, Expression type, int mod, string name,
5838                         Expression size_expr, Attributes attrs, Location loc):
5839                         base (parent, type, mod, AllowedModifiers, new MemberName (name, loc), attrs)
5840                 {
5841                         if (RootContext.Version == LanguageVersion.ISO_1)
5842                                 Report.FeatureIsNotISO1 (loc, "fixed size buffers");
5843
5844                         this.size_expr = size_expr;
5845                 }
5846
5847                 public override bool Define()
5848                 {
5849 #if !NET_2_0
5850                         if ((ModFlags & (Modifiers.PUBLIC | Modifiers.PROTECTED)) != 0)
5851                                 Report.Warning (-23, 1, Location, "Only private or internal fixed sized buffers are supported by .NET 1.x");
5852 #endif
5853
5854                         if (Parent.PartialContainer.Kind != Kind.Struct) {
5855                                 Report.Error (1642, Location, "`{0}': Fixed size buffer fields may only be members of structs",
5856                                         GetSignatureForError ());
5857                                 return false;
5858                         }
5859
5860                         if (!base.Define ())
5861                                 return false;
5862
5863                         if (!TypeManager.IsPrimitiveType (MemberType)) {
5864                                 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",
5865                                         GetSignatureForError ());
5866                                 return false;
5867                         }
5868
5869                         EmitContext ec = new EmitContext (this, Parent, Location, null, null, ModFlags);
5870                         Constant c = size_expr.ResolveAsConstant (ec, this);
5871                         if (c == null)
5872                                 return false;
5873
5874                         IntConstant buffer_size_const = c.ImplicitConversionRequired (TypeManager.int32_type, Location) as IntConstant;
5875                         if (buffer_size_const == null)
5876                                 return false;
5877
5878                         buffer_size = buffer_size_const.Value;
5879
5880                         if (buffer_size <= 0) {
5881                                 Report.Error (1665, Location, "`{0}': Fixed size buffers must have a length greater than zero", GetSignatureForError ());
5882                                 return false;
5883                         }
5884
5885                         int type_size = Expression.GetTypeSize (MemberType);
5886
5887                         if (buffer_size > int.MaxValue / type_size) {
5888                                 Report.Error (1664, Location, "Fixed size buffer `{0}' of length `{1}' and type `{2}' exceeded 2^31 limit",
5889                                         GetSignatureForError (), buffer_size.ToString (), TypeManager.CSharpName (MemberType));
5890                                 return false;
5891                         }
5892
5893                         buffer_size *= type_size;
5894
5895                         // Define nested
5896                         string name = String.Format ("<{0}>__FixedBuffer{1}", Name, GlobalCounter++);
5897
5898                         fixed_buffer_type = Parent.TypeBuilder.DefineNestedType (name,
5899                                 TypeAttributes.NestedPublic | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit, TypeManager.value_type);
5900                         element = fixed_buffer_type.DefineField (FixedElementName, MemberType, FieldAttributes.Public);
5901                         RootContext.RegisterCompilerGeneratedType (fixed_buffer_type);
5902
5903                         FieldBuilder = Parent.TypeBuilder.DefineField (Name, fixed_buffer_type, Modifiers.FieldAttr (ModFlags));
5904                         TypeManager.RegisterFieldBase (FieldBuilder, this);
5905
5906                         return true;
5907                 }
5908
5909                 public override void Emit()
5910                 {
5911                         if (fi == null)
5912                                 fi = new FieldInfo [] { TypeManager.struct_layout_attribute_type.GetField ("Size") };
5913
5914                         object[] fi_val = new object[1];
5915                         fi_val [0] = buffer_size;
5916
5917                         CustomAttributeBuilder cab = new CustomAttributeBuilder (TypeManager.struct_layout_attribute_ctor, 
5918                                 ctor_args, fi, fi_val);
5919                         fixed_buffer_type.SetCustomAttribute (cab);
5920
5921 #if NET_2_0
5922                         cab = new CustomAttributeBuilder (TypeManager.fixed_buffer_attr_ctor, new object[] { MemberType, buffer_size } );
5923                         FieldBuilder.SetCustomAttribute (cab);
5924 #endif
5925                         base.Emit ();
5926                 }
5927
5928                 protected override bool IsFieldClsCompliant {
5929                         get {
5930                                 return false;
5931                         }
5932                 }
5933
5934                 #region IFixedField Members
5935
5936                 public FieldInfo Element {
5937                         get {
5938                                 return element;
5939                         }
5940                 }
5941
5942                 public Type ElementType {
5943                         get {
5944                                 return MemberType;
5945                         }
5946                 }
5947
5948                 #endregion
5949         }
5950
5951         //
5952         // The Field class is used to represents class/struct fields during parsing.
5953         //
5954         public class Field : FieldBase {
5955                 // <summary>
5956                 //   Modifiers allowed in a class declaration
5957                 // </summary>
5958                 const int AllowedModifiers =
5959                         Modifiers.NEW |
5960                         Modifiers.PUBLIC |
5961                         Modifiers.PROTECTED |
5962                         Modifiers.INTERNAL |
5963                         Modifiers.PRIVATE |
5964                         Modifiers.STATIC |
5965                         Modifiers.VOLATILE |
5966                         Modifiers.UNSAFE |
5967                         Modifiers.READONLY;
5968
5969                 public Field (DeclSpace parent, Expression type, int mod, string name,
5970                               Attributes attrs, Location loc)
5971                         : base (parent, type, mod, AllowedModifiers, new MemberName (name, loc),
5972                                 attrs)
5973                 {
5974                 }
5975
5976                 public override bool Define ()
5977                 {
5978                         if (!base.Define ())
5979                                 return false;
5980
5981                         if (RootContext.WarningLevel > 1){
5982                                 Type ptype = Parent.TypeBuilder.BaseType;
5983
5984                                 // ptype is only null for System.Object while compiling corlib.
5985                                 if (ptype != null){
5986                                         TypeContainer.FindMembers (
5987                                                 ptype, MemberTypes.Method,
5988                                                 BindingFlags.Public |
5989                                                 BindingFlags.Static | BindingFlags.Instance,
5990                                                 System.Type.FilterName, Name);
5991                                 }
5992                         }
5993
5994                         if ((ModFlags & Modifiers.VOLATILE) != 0){
5995                                 if (!MemberType.IsClass){
5996                                         Type vt = MemberType;
5997                                         
5998                                         if (TypeManager.IsEnumType (vt))
5999                                                 vt = TypeManager.EnumToUnderlying (MemberType);
6000
6001                                         if (!((vt == TypeManager.bool_type) ||
6002                                               (vt == TypeManager.sbyte_type) ||
6003                                               (vt == TypeManager.byte_type) ||
6004                                               (vt == TypeManager.short_type) ||
6005                                               (vt == TypeManager.ushort_type) ||
6006                                               (vt == TypeManager.int32_type) ||
6007                                               (vt == TypeManager.uint32_type) ||    
6008                                               (vt == TypeManager.char_type) ||
6009                                               (vt == TypeManager.float_type) ||
6010                                               (!vt.IsValueType))){
6011                                                 Report.Error (677, Location, "`{0}': A volatile field cannot be of the type `{1}'",
6012                                                         GetSignatureForError (), TypeManager.CSharpName (vt));
6013                                                 return false;
6014                                         }
6015                                 }
6016
6017                                 if ((ModFlags & Modifiers.READONLY) != 0){
6018                                         Report.Error (678, Location, "`{0}': A field cannot be both volatile and readonly",
6019                                                 GetSignatureForError ());
6020                                         return false;
6021                                 }
6022                         }
6023
6024                         FieldAttributes fa = Modifiers.FieldAttr (ModFlags);
6025
6026                         if (Parent.PartialContainer.Kind == Kind.Struct && 
6027                             ((fa & FieldAttributes.Static) == 0) &&
6028                             MemberType == Parent.TypeBuilder &&
6029                             !TypeManager.IsBuiltinType (MemberType)){
6030                                 Report.Error (523, Location, "Struct member `" + Parent.Name + "." + Name + 
6031                                               "' causes a cycle in the structure layout");
6032                                 return false;
6033                         }
6034
6035                         try {
6036                                 FieldBuilder = Parent.TypeBuilder.DefineField (
6037                                         Name, MemberType, Modifiers.FieldAttr (ModFlags));
6038
6039                                 TypeManager.RegisterFieldBase (FieldBuilder, this);
6040                         }
6041                         catch (ArgumentException) {
6042                                 Report.Warning (-24, 1, Location, "The Microsoft runtime is unable to use [void|void*] as a field type, try using the Mono runtime.");
6043                                 return false;
6044                         }
6045
6046                         if (initializer != null)
6047                                 Parent.PartialContainer.RegisterFieldForInitialization (this,
6048                                         new FieldInitializer (FieldBuilder, initializer, Parent));
6049
6050                         return true;
6051                 }
6052
6053                 protected override bool VerifyClsCompliance ()
6054                 {
6055                         if (!base.VerifyClsCompliance ())
6056                                 return false;
6057
6058                         if ((ModFlags & Modifiers.VOLATILE) != 0) {
6059                                 Report.Warning (3026, 1, Location, "CLS-compliant field `{0}' cannot be volatile", GetSignatureForError ());
6060                         }
6061
6062                         return true;
6063                 }
6064         }
6065
6066         //
6067         // `set' and `get' accessors are represented with an Accessor.
6068         // 
6069         public class Accessor : IAnonymousHost {
6070                 //
6071                 // Null if the accessor is empty, or a Block if not
6072                 //
6073                 public const int AllowedModifiers = 
6074                         Modifiers.PUBLIC |
6075                         Modifiers.PROTECTED |
6076                         Modifiers.INTERNAL |
6077                         Modifiers.PRIVATE;
6078                 
6079                 public ToplevelBlock Block;
6080                 public Attributes Attributes;
6081                 public Location Location;
6082                 public int ModFlags;
6083                 public bool Yields;
6084                 public ArrayList AnonymousMethods;
6085                 
6086                 public Accessor (ToplevelBlock b, int mod, Attributes attrs, Location loc)
6087                 {
6088                         Block = b;
6089                         Attributes = attrs;
6090                         Location = loc;
6091                         ModFlags = Modifiers.Check (AllowedModifiers, mod, 0, loc);
6092                 }
6093
6094                 public void SetYields ()
6095                 {
6096                         Yields = true;
6097                 }
6098
6099                 public void AddAnonymousMethod (AnonymousMethodExpression ame)
6100                 {
6101                         if (AnonymousMethods == null)
6102                                 AnonymousMethods = new ArrayList ();
6103                         AnonymousMethods.Add (ame);
6104                 }
6105         }
6106
6107         // Ooouh Martin, templates are missing here.
6108         // When it will be possible move here a lot of child code and template method type.
6109         public abstract class AbstractPropertyEventMethod : MemberCore, IMethodData {
6110                 protected MethodData method_data;
6111                 protected ToplevelBlock block;
6112                 protected ListDictionary declarative_security;
6113
6114                 // The accessor are created event if they are not wanted.
6115                 // But we need them because their names are reserved.
6116                 // Field says whether accessor will be emited or not
6117                 public readonly bool IsDummy;
6118
6119                 protected readonly string prefix;
6120
6121                 ReturnParameter return_attributes;
6122
6123                 public AbstractPropertyEventMethod (PropertyBasedMember member, string prefix)
6124                         : base (member.Parent, SetupName (prefix, member, member.Location), null)
6125                 {
6126                         this.prefix = prefix;
6127                         IsDummy = true;
6128                 }
6129
6130                 public AbstractPropertyEventMethod (InterfaceMemberBase member, Accessor accessor,
6131                                                     string prefix)
6132                         : base (member.Parent, SetupName (prefix, member, accessor.Location),
6133                                 accessor.Attributes)
6134                 {
6135                         this.prefix = prefix;
6136                         this.block = accessor.Block;
6137                 }
6138
6139                 static MemberName SetupName (string prefix, InterfaceMemberBase member, Location loc)
6140                 {
6141                         return new MemberName (member.MemberName.Left, prefix + member.ShortName, loc);
6142                 }
6143
6144                 public void UpdateName (InterfaceMemberBase member)
6145                 {
6146                         SetMemberName (SetupName (prefix, member, Location));
6147                 }
6148
6149                 #region IMethodData Members
6150
6151                 public abstract Iterator Iterator {
6152                         get;
6153                 }
6154
6155                 public ToplevelBlock Block {
6156                         get {
6157                                 return block;
6158                         }
6159
6160                         set {
6161                                 block = value;
6162                         }
6163                 }
6164
6165                 public CallingConventions CallingConventions {
6166                         get {
6167                                 return CallingConventions.Standard;
6168                         }
6169                 }
6170
6171                 public bool IsExcluded ()
6172                 {
6173                         return false;
6174                 }
6175
6176                 GenericMethod IMethodData.GenericMethod {
6177                         get {
6178                                 return null;
6179                         }
6180                 }
6181
6182                 public MemberName MethodName {
6183                         get {
6184                                 return MemberName;
6185                         }
6186                 }
6187
6188                 public Type[] ParameterTypes { 
6189                         get {
6190                                 return ParameterInfo.Types;
6191                         }
6192                 }
6193
6194                 public abstract Parameters ParameterInfo { get ; }
6195                 public abstract Type ReturnType { get; }
6196                 public abstract EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig);
6197
6198                 #endregion
6199
6200                 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
6201                 {
6202                         if (a.Type == TypeManager.cls_compliant_attribute_type || a.Type == TypeManager.obsolete_attribute_type ||
6203                                         a.Type == TypeManager.conditional_attribute_type) {
6204                                 Report.Error (1667, a.Location,
6205                                         "Attribute `{0}' is not valid on property or event accessors. It is valid on `{1}' declarations only",
6206                                         TypeManager.CSharpName (a.Type), a.GetValidTargets ());
6207                                 return;
6208                         }
6209
6210                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
6211                                 if (declarative_security == null)
6212                                         declarative_security = new ListDictionary ();
6213                                 a.ExtractSecurityPermissionSet (declarative_security);
6214                                 return;
6215                         }
6216
6217                         if (a.Target == AttributeTargets.Method) {
6218                                 method_data.MethodBuilder.SetCustomAttribute (cb);
6219                                 return;
6220                         }
6221
6222                         if (a.Target == AttributeTargets.ReturnValue) {
6223                                 if (return_attributes == null)
6224                                         return_attributes = new ReturnParameter (method_data.MethodBuilder, Location);
6225
6226                                 return_attributes.ApplyAttributeBuilder (a, cb);
6227                                 return;
6228                         }
6229
6230                         ApplyToExtraTarget (a, cb);
6231                 }
6232
6233                 virtual protected void ApplyToExtraTarget (Attribute a, CustomAttributeBuilder cb)
6234                 {
6235                         System.Diagnostics.Debug.Fail ("You forgot to define special attribute target handling");
6236                 }
6237
6238                 // It is not supported for the accessors
6239                 public sealed override bool Define()
6240                 {
6241                         throw new NotSupportedException ();
6242                 }
6243
6244                 public void Emit (DeclSpace parent)
6245                 {
6246                         EmitMethod (parent);
6247
6248                         if (OptAttributes != null)
6249                                 OptAttributes.Emit ();
6250
6251                         if (declarative_security != null) {
6252                                 foreach (DictionaryEntry de in declarative_security) {
6253                                         method_data.MethodBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
6254                                 }
6255                         }
6256
6257                         block = null;
6258                 }
6259
6260                 protected virtual void EmitMethod (DeclSpace parent)
6261                 {
6262                         method_data.Emit (parent);
6263                 }
6264
6265                 public override bool IsClsComplianceRequired()
6266                 {
6267                         return false;
6268                 }
6269
6270                 public bool IsDuplicateImplementation (MethodCore method)
6271                 {
6272                         if (!MemberName.Equals (method.MemberName))
6273                                 return false;
6274
6275                         Type[] param_types = method.ParameterTypes;
6276
6277                         if (param_types.Length != ParameterTypes.Length)
6278                                 return false;
6279
6280                         for (int i = 0; i < param_types.Length; i++)
6281                                 if (param_types [i] != ParameterTypes [i])
6282                                         return false;
6283
6284                         Report.SymbolRelatedToPreviousError (method);
6285                         Report.Error (111, Location, TypeContainer.Error111, method.GetSignatureForError ());
6286                         return true;
6287                 }
6288
6289                 public override bool IsUsed
6290                 {
6291                         get {
6292                                 if (IsDummy)
6293                                         return false;
6294
6295                                 return base.IsUsed;
6296                         }
6297                 }
6298
6299                 public new Location Location { 
6300                         get {
6301                                 return base.Location;
6302                         }
6303                 }
6304
6305                 //
6306                 //   Represents header string for documentation comment.
6307                 //
6308                 public override string DocCommentHeader {
6309                         get { throw new InvalidOperationException ("Unexpected attempt to get doc comment from " + this.GetType () + "."); }
6310                 }
6311
6312         }
6313
6314         //
6315         // Properties and Indexers both generate PropertyBuilders, we use this to share 
6316         // their common bits.
6317         //
6318         abstract public class PropertyBase : PropertyBasedMember {
6319
6320                 public class GetMethod : PropertyMethod
6321                 {
6322                         static string[] attribute_targets = new string [] { "method", "return" };
6323
6324                         public GetMethod (PropertyBase method):
6325                                 base (method, "get_")
6326                         {
6327                         }
6328
6329                         public GetMethod (PropertyBase method, Accessor accessor):
6330                                 base (method, accessor, "get_")
6331                         {
6332                         }
6333
6334                         public override MethodBuilder Define (DeclSpace parent)
6335                         {
6336                                 base.Define (parent);
6337                                 
6338                                 method_data = new MethodData (method, ModFlags, flags, this);
6339
6340                                 if (!method_data.Define (parent))
6341                                         return null;
6342
6343                                 return method_data.MethodBuilder;
6344                         }
6345
6346                         public override Type ReturnType {
6347                                 get {
6348                                         return method.MemberType;
6349                                 }
6350                         }
6351
6352                         public override Parameters ParameterInfo {
6353                                 get {
6354                                         return Parameters.EmptyReadOnlyParameters;
6355                                 }
6356                         }
6357
6358                         public override string[] ValidAttributeTargets {
6359                                 get {
6360                                         return attribute_targets;
6361                                 }
6362                         }
6363                 }
6364
6365                 public class SetMethod : PropertyMethod {
6366
6367                         static string[] attribute_targets = new string [] { "method", "param", "return" };
6368                         ImplicitParameter param_attr;
6369                         protected Parameters parameters;
6370
6371                         public SetMethod (PropertyBase method):
6372                                 base (method, "set_")
6373                         {
6374                         }
6375
6376                         public SetMethod (PropertyBase method, Accessor accessor):
6377                                 base (method, accessor, "set_")
6378                         {
6379                         }
6380
6381                         protected override void ApplyToExtraTarget(Attribute a, CustomAttributeBuilder cb)
6382                         {
6383                                 if (a.Target == AttributeTargets.Parameter) {
6384                                         if (param_attr == null)
6385                                                 param_attr = new ImplicitParameter (method_data.MethodBuilder);
6386
6387                                         param_attr.ApplyAttributeBuilder (a, cb);
6388                                         return;
6389                                 }
6390
6391                                 base.ApplyAttributeBuilder (a, cb);
6392                         }
6393
6394                         public override Parameters ParameterInfo {
6395                                 get {
6396                                         if (parameters == null)
6397                                                 DefineParameters ();
6398                                         return parameters;
6399                                 }
6400                         }
6401
6402                         protected virtual void DefineParameters ()
6403                         {
6404                                 parameters = new Parameters (
6405                                         new Parameter[] { new Parameter (method.MemberType, "value", Parameter.Modifier.NONE, null, Location) },
6406                                         new Type[] { method.MemberType });
6407                         }
6408
6409                         public override MethodBuilder Define (DeclSpace parent)
6410                         {
6411                                 if (IsDummy)
6412                                         return null;
6413
6414                                 base.Define (parent);
6415
6416                                 method_data = new MethodData (method, ModFlags, flags, this);
6417
6418                                 if (!method_data.Define (parent))
6419                                         return null;
6420
6421                                 return method_data.MethodBuilder;
6422                         }
6423
6424                         public override Type ReturnType {
6425                                 get {
6426                                         return TypeManager.void_type;
6427                                 }
6428                         }
6429
6430                         public override string[] ValidAttributeTargets {
6431                                 get {
6432                                         return attribute_targets;
6433                                 }
6434                         }
6435                 }
6436
6437                 static string[] attribute_targets = new string [] { "property" };
6438
6439                 public abstract class PropertyMethod : AbstractPropertyEventMethod
6440                 {
6441                         protected readonly PropertyBase method;
6442                         protected MethodAttributes flags;
6443                         Iterator iterator;
6444                         ArrayList anonymous_methods;
6445                         bool yields;
6446
6447                         public PropertyMethod (PropertyBase method, string prefix)
6448                                 : base (method, prefix)
6449                         {
6450                                 this.method = method;
6451                         }
6452
6453                         public PropertyMethod (PropertyBase method, Accessor accessor,
6454                                                string prefix)
6455                                 : base (method, accessor, prefix)
6456                         {
6457                                 this.method = method;
6458                                 this.ModFlags = accessor.ModFlags;
6459                                 yields = accessor.Yields;
6460                                 anonymous_methods = accessor.AnonymousMethods;
6461
6462                                 if (accessor.ModFlags != 0 && RootContext.Version == LanguageVersion.ISO_1) {
6463                                         Report.FeatureIsNotISO1 (Location, "access modifiers on properties");
6464                                 }
6465                         }
6466
6467                         public override Iterator Iterator {
6468                                 get { return iterator; }
6469                         }
6470
6471                         public override AttributeTargets AttributeTargets {
6472                                 get {
6473                                         return AttributeTargets.Method;
6474                                 }
6475                         }
6476
6477                         public override bool IsClsComplianceRequired ()
6478                         {
6479                                 return method.IsClsComplianceRequired ();
6480                         }
6481
6482                         public bool ResolveMembers ()
6483                         {
6484                                 if (yields) {
6485                                         iterator = Iterator.CreateIterator (this, Parent, null, ModFlags);
6486                                         if (iterator == null)
6487                                                 return false;
6488                                 }
6489
6490                                 if (anonymous_methods != null) {
6491                                         foreach (AnonymousMethodExpression ame in anonymous_methods) {
6492                                                 if (!ame.CreateAnonymousHelpers ())
6493                                                         return false;
6494                                         }
6495                                 }
6496
6497                                 return true;
6498                         }
6499
6500                         public virtual MethodBuilder Define (DeclSpace parent)
6501                         {
6502                                 if (!method.CheckAbstractAndExtern (block != null))
6503                                         return null;
6504
6505                                 TypeContainer container = parent.PartialContainer;
6506
6507                                 //
6508                                 // Check for custom access modifier
6509                                 //
6510                                 if (ModFlags == 0) {
6511                                         ModFlags = method.ModFlags;
6512                                         flags = method.flags;
6513                                 } else {
6514                                         if (container.Kind == Kind.Interface)
6515                                                 Report.Error (275, Location, "`{0}': accessibility modifiers may not be used on accessors in an interface",
6516                                                         GetSignatureForError ());
6517
6518                                         if ((method.ModFlags & Modifiers.ABSTRACT) != 0 && (ModFlags & Modifiers.PRIVATE) != 0) {
6519                                                 Report.Error (442, Location, "`{0}': abstract properties cannot have private accessors", GetSignatureForError ());
6520                                         }
6521
6522                                         CheckModifiers (ModFlags);
6523                                         ModFlags |= (method.ModFlags & (~Modifiers.Accessibility));
6524                                         ModFlags |= Modifiers.PROPERTY_CUSTOM;
6525                                         flags = Modifiers.MethodAttr (ModFlags);
6526                                         flags |= (method.flags & (~MethodAttributes.MemberAccessMask));
6527                                 }
6528
6529                                 return null;
6530                         }
6531
6532                         public bool HasCustomAccessModifier
6533                         {
6534                                 get {
6535                                         return (ModFlags & Modifiers.PROPERTY_CUSTOM) != 0;
6536                                 }
6537                         }
6538
6539                         public override EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig)
6540                         {
6541                                 return new EmitContext (method,
6542                                         ds, method.ds, method.Location, ig, ReturnType,
6543                                         method.ModFlags, false);
6544                         }
6545
6546                         public override ObsoleteAttribute GetObsoleteAttribute ()
6547                         {
6548                                 return method.GetObsoleteAttribute ();
6549                         }
6550
6551                         public override string GetSignatureForError()
6552                         {
6553                                 return method.GetSignatureForError () + '.' + prefix.Substring (0, 3);
6554                         }
6555                         
6556                         void CheckModifiers (int modflags)
6557                         {
6558                                 int flags = 0;
6559                                 int mflags = method.ModFlags & Modifiers.Accessibility;
6560
6561                                 if ((mflags & Modifiers.PUBLIC) != 0) {
6562                                         flags |= Modifiers.PROTECTED | Modifiers.INTERNAL | Modifiers.PRIVATE;
6563                                 }
6564                                 else if ((mflags & Modifiers.PROTECTED) != 0) {
6565                                         if ((mflags & Modifiers.INTERNAL) != 0)
6566                                                 flags |= Modifiers.PROTECTED | Modifiers.INTERNAL;
6567
6568                                         flags |= Modifiers.PRIVATE;
6569                                 }
6570                                 else if ((mflags & Modifiers.INTERNAL) != 0)
6571                                         flags |= Modifiers.PRIVATE;
6572
6573                                 if ((mflags == modflags) || (modflags & (~flags)) != 0) {
6574                                         Report.Error (273, Location,
6575                                                 "The accessibility modifier of the `{0}' accessor must be more restrictive than the modifier of the property or indexer `{1}'",
6576                                                 GetSignatureForError (), method.GetSignatureForError ());
6577                                 }
6578                         }
6579
6580                         public override bool MarkForDuplicationCheck ()
6581                         {
6582                                 caching_flags |= Flags.TestMethodDuplication;
6583                                 return true;
6584                         }
6585                 }
6586
6587                 public PropertyMethod Get, Set;
6588                 public PropertyBuilder PropertyBuilder;
6589                 public MethodBuilder GetBuilder, SetBuilder;
6590
6591                 protected bool define_set_first = false;
6592
6593                 public PropertyBase (DeclSpace parent, Expression type, int mod_flags,
6594                                      int allowed_mod, bool is_iface, MemberName name,
6595                                      Attributes attrs, bool define_set_first)
6596                         : base (parent, null, type, mod_flags, allowed_mod, is_iface, name,     attrs)
6597                 {
6598                          this.define_set_first = define_set_first;
6599                 }
6600
6601                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
6602                 {
6603                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
6604                                 a.Error_InvalidSecurityParent ();
6605                                 return;
6606                         }
6607
6608                         PropertyBuilder.SetCustomAttribute (cb);
6609                 }
6610
6611                 public override AttributeTargets AttributeTargets {
6612                         get {
6613                                 return AttributeTargets.Property;
6614                         }
6615                 }
6616
6617                 public override bool Define ()
6618                 {
6619                         if (!DoDefine ())
6620                                 return false;
6621
6622                         if (!IsTypePermitted ())
6623                                 return false;
6624
6625                         return true;
6626                 }
6627
6628                 protected override bool DoDefine ()
6629                 {
6630                         if (!base.DoDefine ())
6631                                 return false;
6632
6633                         //
6634                         // Accessors modifiers check
6635                         //
6636                         if (Get.ModFlags != 0 && Set.ModFlags != 0) {
6637                                 Report.Error (274, Location, "`{0}': Cannot specify accessibility modifiers for both accessors of the property or indexer",
6638                                                 GetSignatureForError ());
6639                                 return false;
6640                         }
6641
6642                         if ((Get.IsDummy || Set.IsDummy)
6643                                         && (Get.ModFlags != 0 || Set.ModFlags != 0) && (ModFlags & Modifiers.OVERRIDE) == 0) {
6644                                 Report.Error (276, Location, 
6645                                         "`{0}': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor",
6646                                         GetSignatureForError ());
6647                                 return false;
6648                         }
6649
6650                         if (MemberType.IsAbstract && MemberType.IsSealed) {
6651                                 Report.Error (722, Location, Error722, TypeManager.CSharpName (MemberType));
6652                                 return false;
6653                         }
6654
6655                         return true;
6656                 }
6657
6658                 bool DefineGet ()
6659                 {
6660                         if (Get.IsDummy)
6661                                 return true;
6662
6663                         GetBuilder = Get.Define (Parent);
6664                         return GetBuilder != null;
6665                 }
6666
6667                 bool DefineSet (bool define)
6668                 {
6669                         if (!define || Set.IsDummy)
6670                                 return true;
6671
6672                         SetBuilder = Set.Define (Parent);
6673                         return SetBuilder != null;
6674                 }
6675
6676                 protected bool DefineAccessors ()
6677                 {
6678                         return DefineSet (define_set_first) &&
6679                                 DefineGet () &&
6680                                 DefineSet (!define_set_first);
6681                 }
6682
6683                 protected abstract PropertyInfo ResolveBaseProperty ();
6684
6685                 // TODO: rename to Resolve......
6686                 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
6687                 {
6688                         PropertyInfo base_property = ResolveBaseProperty ();
6689                         if (base_property == null)
6690                                 return null;
6691   
6692                         base_ret_type = base_property.PropertyType;
6693                         MethodInfo get_accessor = base_property.GetGetMethod (true);
6694                         MethodInfo set_accessor = base_property.GetSetMethod (true);
6695                         MethodAttributes get_accessor_access, set_accessor_access;
6696
6697                         if ((ModFlags & Modifiers.OVERRIDE) != 0) {
6698                                 if (Get != null && !Get.IsDummy && get_accessor == null) {
6699                                         Report.SymbolRelatedToPreviousError (base_property);
6700                                         Report.Error (545, Location, "`{0}.get': cannot override because `{1}' does not have an overridable get accessor", GetSignatureForError (), TypeManager.GetFullNameSignature (base_property));
6701                                 }
6702
6703                                 if (Set != null && !Set.IsDummy && set_accessor == null) {
6704                                         Report.SymbolRelatedToPreviousError (base_property);
6705                                         Report.Error (546, Location, "`{0}.set': cannot override because `{1}' does not have an overridable set accessor", GetSignatureForError (), TypeManager.GetFullNameSignature (base_property));
6706                                 }
6707                         }
6708                         
6709                         //
6710                         // Check base class accessors access
6711                         //
6712
6713                         // TODO: rewrite to reuse Get|Set.CheckAccessModifiers and share code there
6714                         get_accessor_access = set_accessor_access = 0;
6715                         if ((ModFlags & Modifiers.NEW) == 0) {
6716                                 if (get_accessor != null) {
6717                                         MethodAttributes get_flags = Modifiers.MethodAttr (Get.ModFlags != 0 ? Get.ModFlags : ModFlags);
6718                                         get_accessor_access = (get_accessor.Attributes & MethodAttributes.MemberAccessMask);
6719
6720                                         if (!Get.IsDummy && !CheckAccessModifiers (get_flags & MethodAttributes.MemberAccessMask, get_accessor_access, get_accessor))
6721                                                 Error_CannotChangeAccessModifiers (get_accessor, get_accessor_access,  ".get");
6722                                 }
6723
6724                                 if (set_accessor != null)  {
6725                                         MethodAttributes set_flags = Modifiers.MethodAttr (Set.ModFlags != 0 ? Set.ModFlags : ModFlags);
6726                                         set_accessor_access = (set_accessor.Attributes & MethodAttributes.MemberAccessMask);
6727
6728                                         if (!Set.IsDummy && !CheckAccessModifiers (set_flags & MethodAttributes.MemberAccessMask, set_accessor_access, set_accessor))
6729                                                 Error_CannotChangeAccessModifiers (set_accessor, set_accessor_access, ".set");
6730                                 }
6731                         }
6732
6733                         //
6734                         // Get the less restrictive access
6735                         //
6736                         return get_accessor_access > set_accessor_access ? get_accessor : set_accessor;
6737                 }
6738
6739                 public override void Emit ()
6740                 {
6741                         //
6742                         // The PropertyBuilder can be null for explicit implementations, in that
6743                         // case, we do not actually emit the ".property", so there is nowhere to
6744                         // put the attribute
6745                         //
6746                         if (PropertyBuilder != null && OptAttributes != null)
6747                                 OptAttributes.Emit ();
6748
6749                         if (!Get.IsDummy)
6750                                 Get.Emit (Parent);
6751
6752                         if (!Set.IsDummy)
6753                                 Set.Emit (Parent);
6754
6755                         base.Emit ();
6756                 }
6757
6758                 /// <summary>
6759                 /// Tests whether accessors are not in collision with some method (CS0111)
6760                 /// </summary>
6761                 public bool AreAccessorsDuplicateImplementation (MethodCore mc)
6762                 {
6763                         return Get.IsDuplicateImplementation (mc) || Set.IsDuplicateImplementation (mc);
6764                 }
6765
6766                 public override bool IsUsed
6767                 {
6768                         get {
6769                                 if (IsExplicitImpl)
6770                                         return true;
6771
6772                                 return Get.IsUsed | Set.IsUsed;
6773                         }
6774                 }
6775
6776                 protected override void SetMemberName (MemberName new_name)
6777                 {
6778                         base.SetMemberName (new_name);
6779
6780                         Get.UpdateName (this);
6781                         Set.UpdateName (this);
6782                 }
6783
6784                 public override string[] ValidAttributeTargets {
6785                         get {
6786                                 return attribute_targets;
6787                         }
6788                 }
6789
6790                 //
6791                 //   Represents header string for documentation comment.
6792                 //
6793                 public override string DocCommentHeader {
6794                         get { return "P:"; }
6795                 }
6796         }
6797                         
6798         public class Property : PropertyBase {
6799                 const int AllowedModifiers =
6800                         Modifiers.NEW |
6801                         Modifiers.PUBLIC |
6802                         Modifiers.PROTECTED |
6803                         Modifiers.INTERNAL |
6804                         Modifiers.PRIVATE |
6805                         Modifiers.STATIC |
6806                         Modifiers.SEALED |
6807                         Modifiers.OVERRIDE |
6808                         Modifiers.ABSTRACT |
6809                         Modifiers.UNSAFE |
6810                         Modifiers.EXTERN |
6811                         Modifiers.METHOD_YIELDS |
6812                         Modifiers.VIRTUAL;
6813
6814                 const int AllowedInterfaceModifiers =
6815                         Modifiers.NEW;
6816
6817                 public Property (DeclSpace parent, Expression type, int mod, bool is_iface,
6818                                  MemberName name, Attributes attrs, Accessor get_block,
6819                                  Accessor set_block, bool define_set_first)
6820                         : base (parent, type, mod,
6821                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
6822                                 is_iface, name, attrs, define_set_first)
6823                 {
6824                         if (get_block == null)
6825                                 Get = new GetMethod (this);
6826                         else
6827                                 Get = new GetMethod (this, get_block);
6828
6829                         if (set_block == null)
6830                                 Set = new SetMethod (this);
6831                         else
6832                                 Set = new SetMethod (this, set_block);
6833                 }
6834
6835                 public override bool Define ()
6836                 {
6837                         if (!DoDefineBase ())
6838                                 return false;
6839
6840                         if (!base.Define ())
6841                                 return false;
6842
6843                         if (!CheckBase ())
6844                                 return false;
6845
6846                         flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
6847
6848                         if (!DefineAccessors ())
6849                                 return false;
6850
6851                         // FIXME - PropertyAttributes.HasDefault ?
6852
6853                         PropertyBuilder = Parent.TypeBuilder.DefineProperty (
6854                                 MemberName.ToString (), PropertyAttributes.None, MemberType, null);
6855
6856                         if (!Get.IsDummy)
6857                                 PropertyBuilder.SetGetMethod (GetBuilder);
6858                                 
6859                         if (!Set.IsDummy)
6860                                 PropertyBuilder.SetSetMethod (SetBuilder);
6861                         
6862                         TypeManager.RegisterProperty (PropertyBuilder, this);
6863                         return true;
6864                 }
6865
6866                 protected override PropertyInfo ResolveBaseProperty ()
6867                 {
6868                         return Parent.PartialContainer.BaseCache.FindMemberToOverride (
6869                                 Parent.TypeBuilder, Name, Parameters.EmptyReadOnlyParameters.Types, null, true) as PropertyInfo;
6870                 }
6871         }
6872
6873         /// </summary>
6874         ///  Gigantic workaround  for lameness in SRE follows :
6875         ///  This class derives from EventInfo and attempts to basically
6876         ///  wrap around the EventBuilder so that FindMembers can quickly
6877         ///  return this in it search for members
6878         /// </summary>
6879         public class MyEventBuilder : EventInfo {
6880                 
6881                 //
6882                 // We use this to "point" to our Builder which is
6883                 // not really a MemberInfo
6884                 //
6885                 EventBuilder MyBuilder;
6886                 
6887                 //
6888                 // We "catch" and wrap these methods
6889                 //
6890                 MethodInfo raise, remove, add;
6891
6892                 EventAttributes attributes;
6893                 Type declaring_type, reflected_type, event_type;
6894                 string name;
6895
6896                 Event my_event;
6897
6898                 public MyEventBuilder (Event ev, TypeBuilder type_builder, string name, EventAttributes event_attr, Type event_type)
6899                 {
6900                         MyBuilder = type_builder.DefineEvent (name, event_attr, event_type);
6901
6902                         // And now store the values in our own fields.
6903                         
6904                         declaring_type = type_builder;
6905
6906                         reflected_type = type_builder;
6907                         
6908                         attributes = event_attr;
6909                         this.name = name;
6910                         my_event = ev;
6911                         this.event_type = event_type;
6912                 }
6913                 
6914                 //
6915                 // Methods that you have to override.  Note that you only need 
6916                 // to "implement" the variants that take the argument (those are
6917                 // the "abstract" methods, the others (GetAddMethod()) are 
6918                 // regular.
6919                 //
6920                 public override MethodInfo GetAddMethod (bool nonPublic)
6921                 {
6922                         return add;
6923                 }
6924                 
6925                 public override MethodInfo GetRemoveMethod (bool nonPublic)
6926                 {
6927                         return remove;
6928                 }
6929                 
6930                 public override MethodInfo GetRaiseMethod (bool nonPublic)
6931                 {
6932                         return raise;
6933                 }
6934                 
6935                 //
6936                 // These methods make "MyEventInfo" look like a Builder
6937                 //
6938                 public void SetRaiseMethod (MethodBuilder raiseMethod)
6939                 {
6940                         raise = raiseMethod;
6941                         MyBuilder.SetRaiseMethod (raiseMethod);
6942                 }
6943
6944                 public void SetRemoveOnMethod (MethodBuilder removeMethod)
6945                 {
6946                         remove = removeMethod;
6947                         MyBuilder.SetRemoveOnMethod (removeMethod);
6948                 }
6949
6950                 public void SetAddOnMethod (MethodBuilder addMethod)
6951                 {
6952                         add = addMethod;
6953                         MyBuilder.SetAddOnMethod (addMethod);
6954                 }
6955
6956                 public void SetCustomAttribute (CustomAttributeBuilder cb)
6957                 {
6958                         MyBuilder.SetCustomAttribute (cb);
6959                 }
6960                 
6961                 public override object [] GetCustomAttributes (bool inherit)
6962                 {
6963                         // FIXME : There's nothing which can be seemingly done here because
6964                         // we have no way of getting at the custom attribute objects of the
6965                         // EventBuilder !
6966                         return null;
6967                 }
6968
6969                 public override object [] GetCustomAttributes (Type t, bool inherit)
6970                 {
6971                         // FIXME : Same here !
6972                         return null;
6973                 }
6974
6975                 public override bool IsDefined (Type t, bool b)
6976                 {
6977                         return true;
6978                 }
6979
6980                 public override EventAttributes Attributes {
6981                         get {
6982                                 return attributes;
6983                         }
6984                 }
6985
6986                 public override string Name {
6987                         get {
6988                                 return name;
6989                         }
6990                 }
6991
6992                 public override Type DeclaringType {
6993                         get {
6994                                 return declaring_type;
6995                         }
6996                 }
6997
6998                 public override Type ReflectedType {
6999                         get {
7000                                 return reflected_type;
7001                         }
7002                 }
7003
7004                 public Type EventType {
7005                         get {
7006                                 return event_type;
7007                         }
7008                 }
7009                 
7010                 public void SetUsed ()
7011                 {
7012                         if (my_event != null) {
7013 //                              my_event.SetAssigned ();
7014                                 my_event.SetMemberIsUsed ();
7015                         }
7016                 }
7017         }
7018         
7019         /// <summary>
7020         /// For case when event is declared like property (with add and remove accessors).
7021         /// </summary>
7022         public class EventProperty: Event {
7023                 abstract class AEventPropertyAccessor : AEventAccessor
7024                 {
7025                         public AEventPropertyAccessor (Event method, Accessor accessor, string prefix):
7026                                 base (method, accessor, prefix)
7027                         {
7028                         }
7029
7030                         public override MethodBuilder Define (DeclSpace ds)
7031                         {
7032                                 method.CheckAbstractAndExtern (block != null);
7033                                 return base.Define (ds);
7034                         }
7035                 }
7036
7037                 sealed class AddDelegateMethod: AEventPropertyAccessor
7038                 {
7039                         public AddDelegateMethod (Event method, Accessor accessor):
7040                                 base (method, accessor, "add_")
7041                         {
7042                         }
7043
7044                         protected override MethodInfo DelegateMethodInfo {
7045                                 get {
7046                                         return TypeManager.delegate_combine_delegate_delegate;
7047                                 }
7048                         }
7049                 }
7050
7051                 sealed class RemoveDelegateMethod: AEventPropertyAccessor
7052                 {
7053                         public RemoveDelegateMethod (Event method, Accessor accessor):
7054                                 base (method, accessor, "remove_")
7055                         {
7056                         }
7057
7058                         protected override MethodInfo DelegateMethodInfo {
7059                                 get {
7060                                         return TypeManager.delegate_remove_delegate_delegate;
7061                                 }
7062                         }
7063                 }
7064
7065
7066                 static readonly string[] attribute_targets = new string [] { "event" }; // "property" target was disabled for 2.0 version
7067
7068                 public EventProperty (DeclSpace parent, Expression type, int mod_flags,
7069                                       bool is_iface, MemberName name,
7070                                       Attributes attrs, Accessor add, Accessor remove)
7071                         : base (parent, type, mod_flags, is_iface, name, attrs)
7072                 {
7073                         Add = new AddDelegateMethod (this, add);
7074                         Remove = new RemoveDelegateMethod (this, remove);
7075                 }
7076
7077                 public override bool Define()
7078                 {
7079                         if (!base.Define ())
7080                                 return false;
7081
7082                         if (IsExplicitImpl)
7083                                 SetMemberIsUsed ();
7084
7085                         return true;
7086                 }
7087
7088                 public override string[] ValidAttributeTargets {
7089                         get {
7090                                 return attribute_targets;
7091                         }
7092                 }
7093         }
7094
7095         /// <summary>
7096         /// Event is declared like field.
7097         /// </summary>
7098         public class EventField : Event {
7099                 abstract class EventFieldAccessor : AEventAccessor
7100                 {
7101                         protected EventFieldAccessor (Event method, string prefix)
7102                                 : base (method, prefix)
7103                         {
7104                         }
7105
7106                         protected override void EmitMethod(DeclSpace parent)
7107                         {
7108                                 if ((method.ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
7109                                         return;
7110
7111                                 ILGenerator ig = method_data.MethodBuilder.GetILGenerator ();
7112
7113                                 // TODO: because we cannot use generics yet
7114                                 FieldInfo field_info = ((EventField)method).FieldBuilder;
7115
7116                                 method_data.MethodBuilder.SetImplementationFlags (MethodImplAttributes.Synchronized);
7117                                 if ((method.ModFlags & Modifiers.STATIC) != 0) {
7118                                         ig.Emit (OpCodes.Ldsfld, field_info);
7119                                         ig.Emit (OpCodes.Ldarg_0);
7120                                         ig.Emit (OpCodes.Call, DelegateMethodInfo);
7121                                         ig.Emit (OpCodes.Castclass, method.MemberType);
7122                                         ig.Emit (OpCodes.Stsfld, field_info);
7123                                 } else {
7124                                         ig.Emit (OpCodes.Ldarg_0);
7125                                         ig.Emit (OpCodes.Ldarg_0);
7126                                         ig.Emit (OpCodes.Ldfld, field_info);
7127                                         ig.Emit (OpCodes.Ldarg_1);
7128                                         ig.Emit (OpCodes.Call, DelegateMethodInfo);
7129                                         ig.Emit (OpCodes.Castclass, method.MemberType);
7130                                         ig.Emit (OpCodes.Stfld, field_info);
7131                                 }
7132                                 ig.Emit (OpCodes.Ret);
7133                         }
7134                 }
7135
7136                 sealed class AddDelegateMethod: EventFieldAccessor
7137                 {
7138                         public AddDelegateMethod (Event method):
7139                                 base (method, "add_")
7140                         {
7141                         }
7142
7143                         protected override MethodInfo DelegateMethodInfo {
7144                                 get {
7145                                         return TypeManager.delegate_combine_delegate_delegate;
7146                                 }
7147                         }
7148                 }
7149
7150                 sealed class RemoveDelegateMethod: EventFieldAccessor
7151                 {
7152                         public RemoveDelegateMethod (Event method):
7153                                 base (method, "remove_")
7154                         {
7155                         }
7156
7157                         protected override MethodInfo DelegateMethodInfo {
7158                                 get {
7159                                         return TypeManager.delegate_remove_delegate_delegate;
7160                                 }
7161                         }
7162                 }
7163
7164
7165                 static readonly string[] attribute_targets = new string [] { "event", "field", "method" };
7166                 static readonly string[] attribute_targets_interface = new string[] { "event", "method" };
7167
7168                 public FieldBuilder FieldBuilder;
7169                 public Expression Initializer;
7170
7171                 public EventField (DeclSpace parent, Expression type, int mod_flags,
7172                                    bool is_iface, MemberName name,
7173                                    Attributes attrs)
7174                         : base (parent, type, mod_flags, is_iface, name, attrs)
7175                 {
7176                         Add = new AddDelegateMethod (this);
7177                         Remove = new RemoveDelegateMethod (this);
7178                 }
7179
7180                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
7181                 {
7182                         if (a.Target == AttributeTargets.Field) {
7183                                 FieldBuilder.SetCustomAttribute (cb);
7184                                 return;
7185                         }
7186
7187                         if (a.Target == AttributeTargets.Method) {
7188                                 int errors = Report.Errors;
7189                                 Add.ApplyAttributeBuilder (a, cb);
7190                                 if (errors == Report.Errors)
7191                                         Remove.ApplyAttributeBuilder (a, cb);
7192                                 return;
7193                         }
7194
7195                         base.ApplyAttributeBuilder (a, cb);
7196                 }
7197
7198                 public override bool Define()
7199                 {
7200                         if (!base.Define ())
7201                                 return false;
7202
7203                         if (IsInterface)
7204                                 return true;
7205
7206                         // FIXME: We are unable to detect whether generic event is used because
7207                         // we are using FieldExpr instead of EventExpr for event access in that
7208                         // case.  When this issue will be fixed this hack can be removed.
7209                         if (TypeManager.IsGenericType (MemberType))
7210                                 SetMemberIsUsed();
7211
7212                         FieldBuilder = Parent.TypeBuilder.DefineField (
7213                                 Name, MemberType,
7214                                 FieldAttributes.Private | ((ModFlags & Modifiers.STATIC) != 0 ? FieldAttributes.Static : 0));
7215                         TypeManager.RegisterEventField (EventBuilder, this);
7216
7217                         if (Initializer != null) {
7218                                 if (((ModFlags & Modifiers.ABSTRACT) != 0)) {
7219                                         Report.Error (74, Location, "`{0}': abstract event cannot have an initializer",
7220                                                 GetSignatureForError ());
7221                                         return false;
7222                                 }
7223
7224                                 Parent.PartialContainer.RegisterFieldForInitialization (this,
7225                                         new FieldInitializer (FieldBuilder, Initializer, Parent));
7226                         }
7227
7228                         return true;
7229                 }
7230
7231                 public override string[] ValidAttributeTargets 
7232                 {
7233                         get {
7234                                 return IsInterface ? attribute_targets_interface : attribute_targets;
7235                         }
7236                 }
7237         }
7238
7239         public abstract class Event : PropertyBasedMember {
7240                 public abstract class AEventAccessor : AbstractPropertyEventMethod
7241                 {
7242                         protected readonly Event method;
7243                         ImplicitParameter param_attr;
7244
7245                         static readonly string[] attribute_targets = new string [] { "method", "param", "return" };
7246
7247                         protected AEventAccessor (Event method, string prefix)
7248                                 : base (method, prefix)
7249                         {
7250                                 this.method = method;
7251                         }
7252
7253                         protected AEventAccessor (Event method, Accessor accessor, string prefix)
7254                                 : base (method, accessor, prefix)
7255                         {
7256                                 this.method = method;
7257                         }
7258
7259                         public override Iterator Iterator {
7260                                 get { return null; }
7261                         }
7262
7263                         protected override void ApplyToExtraTarget(Attribute a, CustomAttributeBuilder cb)
7264                         {
7265                                 if (a.Target == AttributeTargets.Parameter) {
7266                                         if (param_attr == null)
7267                                                 param_attr = new ImplicitParameter (method_data.MethodBuilder);
7268
7269                                         param_attr.ApplyAttributeBuilder (a, cb);
7270                                         return;
7271                                 }
7272
7273                                 base.ApplyAttributeBuilder (a, cb);
7274                         }
7275
7276                         public override AttributeTargets AttributeTargets {
7277                                 get {
7278                                         return AttributeTargets.Method;
7279                                 }
7280                         }
7281
7282                         public override bool IsClsComplianceRequired ()
7283                         {
7284                                 return method.IsClsComplianceRequired ();
7285                         }
7286
7287                         public virtual MethodBuilder Define (DeclSpace parent)
7288                         {
7289                                 method_data = new MethodData (method, method.ModFlags,
7290                                         method.flags | MethodAttributes.HideBySig | MethodAttributes.SpecialName, this);
7291
7292                                 if (!method_data.Define (parent))
7293                                         return null;
7294
7295                                 MethodBuilder mb = method_data.MethodBuilder;
7296                                 ParameterInfo.ApplyAttributes (mb);
7297                                 return mb;
7298                         }
7299
7300                         protected abstract MethodInfo DelegateMethodInfo { get; }
7301
7302                         public override Type ReturnType {
7303                                 get {
7304                                         return TypeManager.void_type;
7305                                 }
7306                         }
7307
7308                         public override EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig)
7309                         {
7310                                 return new EmitContext (
7311                                         ds, method.Parent, Location, ig, ReturnType,
7312                                         method.ModFlags, false);
7313                         }
7314
7315                         public override ObsoleteAttribute GetObsoleteAttribute ()
7316                         {
7317                                 return method.GetObsoleteAttribute ();
7318                         }
7319
7320                         public override string[] ValidAttributeTargets {
7321                                 get {
7322                                         return attribute_targets;
7323                                 }
7324                         }
7325
7326                         public override Parameters ParameterInfo {
7327                                 get {
7328                                         return method.parameters;
7329                                 }
7330                         }
7331                 }
7332
7333
7334                 const int AllowedModifiers =
7335                         Modifiers.NEW |
7336                         Modifiers.PUBLIC |
7337                         Modifiers.PROTECTED |
7338                         Modifiers.INTERNAL |
7339                         Modifiers.PRIVATE |
7340                         Modifiers.STATIC |
7341                         Modifiers.VIRTUAL |
7342                         Modifiers.SEALED |
7343                         Modifiers.OVERRIDE |
7344                         Modifiers.UNSAFE |
7345                         Modifiers.ABSTRACT |
7346                         Modifiers.EXTERN;
7347
7348                 const int AllowedInterfaceModifiers =
7349                         Modifiers.NEW;
7350
7351                 public AEventAccessor Add, Remove;
7352                 public MyEventBuilder     EventBuilder;
7353                 public MethodBuilder AddBuilder, RemoveBuilder;
7354
7355                 Parameters parameters;
7356
7357                 protected Event (DeclSpace parent, Expression type, int mod_flags,
7358                               bool is_iface, MemberName name, Attributes attrs)
7359                         : base (parent, null, type, mod_flags,
7360                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers, is_iface,
7361                                 name, attrs)
7362                 {
7363                 }
7364
7365                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
7366                 {
7367                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
7368                                 a.Error_InvalidSecurityParent ();
7369                                 return;
7370                         }
7371                         
7372                         EventBuilder.SetCustomAttribute (cb);
7373                 }
7374
7375                 public bool AreAccessorsDuplicateImplementation (MethodCore mc)
7376                 {
7377                         return Add.IsDuplicateImplementation (mc) || Remove.IsDuplicateImplementation (mc);
7378                 }
7379
7380                 public override AttributeTargets AttributeTargets {
7381                         get {
7382                                 return AttributeTargets.Event;
7383                         }
7384                 }
7385
7386                 public override bool Define ()
7387                 {
7388                         if (!DoDefineBase ())
7389                                 return false;
7390
7391                         if (!DoDefine ())
7392                                 return false;
7393
7394                         if (!TypeManager.IsDelegateType (MemberType)) {
7395                                 Report.Error (66, Location, "`{0}': event must be of a delegate type", GetSignatureForError ());
7396                                 return false;
7397                         }
7398
7399                         parameters = new Parameters (
7400                                 new Parameter[] { new Parameter (MemberType, "value", Parameter.Modifier.NONE, null, Location) },
7401                                 new Type[] { MemberType } );
7402
7403                         if (!CheckBase ())
7404                                 return false;
7405
7406                         //
7407                         // Now define the accessors
7408                         //
7409
7410                         AddBuilder = Add.Define (Parent);
7411                         if (AddBuilder == null)
7412                                 return false;
7413
7414                         RemoveBuilder = Remove.Define (Parent);
7415                         if (RemoveBuilder == null)
7416                                 return false;
7417
7418                         EventBuilder = new MyEventBuilder (this, Parent.TypeBuilder, Name, EventAttributes.None, MemberType);                                           
7419                         EventBuilder.SetAddOnMethod (AddBuilder);
7420                         EventBuilder.SetRemoveOnMethod (RemoveBuilder);
7421                         return true;
7422                 }
7423
7424                 public override void Emit ()
7425                 {
7426                         if (OptAttributes != null) {
7427                                 OptAttributes.Emit ();
7428                         }
7429
7430                         Add.Emit (Parent);
7431                         Remove.Emit (Parent);
7432
7433                         base.Emit ();
7434                 }
7435
7436                 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
7437                 {
7438                         MethodInfo mi = (MethodInfo) Parent.PartialContainer.BaseCache.FindBaseEvent (
7439                                 Parent.TypeBuilder, Name);
7440
7441                         if (mi == null)
7442                                 return null;
7443
7444                         ParameterData pd = TypeManager.GetParameterData (mi);
7445                         base_ret_type = pd.ParameterType (0);
7446                         return mi;
7447                 }
7448
7449                 //
7450                 //   Represents header string for documentation comment.
7451                 //
7452                 public override string DocCommentHeader {
7453                         get { return "E:"; }
7454                 }
7455         }
7456
7457  
7458         public class Indexer : PropertyBase {
7459
7460                 class GetIndexerMethod : GetMethod
7461                 {
7462                         public GetIndexerMethod (PropertyBase method):
7463                                 base (method)
7464                         {
7465                         }
7466
7467                         public GetIndexerMethod (PropertyBase method, Accessor accessor):
7468                                 base (method, accessor)
7469                         {
7470                         }
7471
7472                         public override Parameters ParameterInfo {
7473                                 get {
7474                                         return ((Indexer)method).parameters;
7475                                 }
7476                         }
7477                 }
7478
7479                 class SetIndexerMethod: SetMethod
7480                 {
7481                         public SetIndexerMethod (PropertyBase method):
7482                                 base (method)
7483                         {
7484                         }
7485
7486                         public SetIndexerMethod (PropertyBase method, Accessor accessor):
7487                                 base (method, accessor)
7488                         {
7489                         }
7490
7491                         protected override void DefineParameters ()
7492                         {
7493                                 parameters = Parameters.MergeGenerated (((Indexer)method).parameters,
7494                                         new Parameter (method.MemberType, "value", Parameter.Modifier.NONE, null, method.Location));
7495                         }
7496                 }
7497
7498                 const int AllowedModifiers =
7499                         Modifiers.NEW |
7500                         Modifiers.PUBLIC |
7501                         Modifiers.PROTECTED |
7502                         Modifiers.INTERNAL |
7503                         Modifiers.PRIVATE |
7504                         Modifiers.VIRTUAL |
7505                         Modifiers.SEALED |
7506                         Modifiers.OVERRIDE |
7507                         Modifiers.UNSAFE |
7508                         Modifiers.EXTERN |
7509                         Modifiers.ABSTRACT;
7510
7511                 const int AllowedInterfaceModifiers =
7512                         Modifiers.NEW;
7513
7514                 public readonly Parameters parameters;
7515
7516                 public Indexer (DeclSpace parent, Expression type, MemberName name, int mod,
7517                                 bool is_iface, Parameters parameters, Attributes attrs,
7518                                 Accessor get_block, Accessor set_block, bool define_set_first)
7519                         : base (parent, type, mod,
7520                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
7521                                 is_iface, name, attrs, define_set_first)
7522                 {
7523                         this.parameters = parameters;
7524
7525                         if (get_block == null)
7526                                 Get = new GetIndexerMethod (this);
7527                         else
7528                                 Get = new GetIndexerMethod (this, get_block);
7529
7530                         if (set_block == null)
7531                                 Set = new SetIndexerMethod (this);
7532                         else
7533                                 Set = new SetIndexerMethod (this, set_block);
7534                 }
7535                 
7536                 protected override bool CheckForDuplications ()
7537                 {
7538                         ArrayList ar = Parent.PartialContainer.Indexers;
7539                         if (ar != null) {
7540                                 int arLen = ar.Count;
7541                                         
7542                                 for (int i = 0; i < arLen; i++) {
7543                                         Indexer m = (Indexer) ar [i];
7544                                         if (IsDuplicateImplementation (m))
7545                                                 return false;
7546                                 }
7547                         }
7548
7549                         return true;
7550                 }
7551
7552                 bool IsDuplicateImplementation (Indexer indexer)
7553                 {
7554                         if (this == indexer)
7555                                 return false;
7556
7557                         if (!MemberName.Equals (indexer.MemberName))
7558                                 return false;
7559
7560                         Type[] param_types = indexer.parameters.Types;
7561
7562                         // When it is not yet defined
7563                         if (param_types == null)
7564                                 return false;
7565
7566                         if (param_types.Length != parameters.Count)
7567                                 return false;
7568
7569                         for (int i = 0; i < param_types.Length; i++)
7570                                 if (param_types [i] != parameters.Types [i])
7571                                         return false;
7572
7573                         Report.SymbolRelatedToPreviousError (indexer);
7574                         Report.Error (111, Location, TypeContainer.Error111, indexer.GetSignatureForError ());
7575                         return true;
7576                 }
7577
7578
7579                 public override bool Define ()
7580                 {
7581                         if (!DoDefineBase ())
7582                                 return false;
7583
7584                         if (!base.Define ())
7585                                 return false;
7586
7587                         if (!parameters.Resolve (ds))
7588                                 return false;
7589
7590                         if (!CheckParameters (parameters))
7591                                 return false;
7592
7593                         if (MemberType == TypeManager.void_type) {
7594                                 Report.Error (620, Location, "Indexers cannot have void type");
7595                                 return false;
7596                         }
7597
7598                         if (OptAttributes != null) {
7599                                 Attribute indexer_attr = OptAttributes.Search (TypeManager.indexer_name_type);
7600                                 if (indexer_attr != null) {
7601                                         // Remove the attribute from the list because it is not emitted
7602                                         OptAttributes.Attrs.Remove (indexer_attr);
7603
7604                                         string name = indexer_attr.GetIndexerAttributeValue ();
7605                                         if (name == null)
7606                                                 return false;
7607
7608                                         ShortName = name;
7609
7610                                         if (IsExplicitImpl) {
7611                                                 Report.Error (415, indexer_attr.Location,
7612                                                               "The `IndexerName' attribute is valid only on an " +
7613                                                               "indexer that is not an explicit interface member declaration");
7614                                                 return false;
7615                                         }
7616
7617                                         if ((ModFlags & Modifiers.OVERRIDE) != 0) {
7618                                                 Report.Error (609, indexer_attr.Location,
7619                                                               "Cannot set the `IndexerName' attribute on an indexer marked override");
7620                                                 return false;
7621                                         }
7622                                 }
7623                         }
7624
7625                         if (InterfaceType != null) {
7626                                 string base_IndexerName = TypeManager.IndexerPropertyName (InterfaceType);
7627                                 if (base_IndexerName != Name)
7628                                         ShortName = base_IndexerName;
7629                         }
7630
7631                         if (!Parent.PartialContainer.AddMember (this) ||
7632                                 !Parent.PartialContainer.AddMember (Get) || !Parent.PartialContainer.AddMember (Set))
7633                                 return false;
7634
7635                         if (!CheckBase ())
7636                                 return false;
7637
7638                         flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
7639                         
7640                         if (!DefineAccessors ())
7641                                 return false;
7642
7643                         if (!Get.IsDummy) {
7644                                 // Setup iterator if we are one
7645                                 if ((ModFlags & Modifiers.METHOD_YIELDS) != 0){
7646                                         Iterator iterator = Iterator.CreateIterator (Get, Parent, null, ModFlags);
7647                                         if (iterator == null)
7648                                                 return false;
7649                                 }
7650                         }
7651
7652                         //
7653                         // Now name the parameters
7654                         //
7655                         Parameter [] p = parameters.FixedParameters;
7656                         if (p != null) {
7657                                 // TODO: should be done in parser and it needs to do cycle
7658                                 if ((p [0].ModFlags & Parameter.Modifier.ISBYREF) != 0) {
7659                                         CSharpParser.Error_ParameterModifierNotValid (Location);
7660                                         return false;
7661                                 }
7662                         }
7663
7664                         PropertyBuilder = Parent.TypeBuilder.DefineProperty (
7665                                 Name, PropertyAttributes.None, MemberType, parameters.Types);
7666                         
7667                         if (!Get.IsDummy)
7668                                 PropertyBuilder.SetGetMethod (GetBuilder);
7669
7670                         if (!Set.IsDummy)
7671                                 PropertyBuilder.SetSetMethod (SetBuilder);
7672                                 
7673                         TypeManager.RegisterIndexer (PropertyBuilder, GetBuilder, SetBuilder, parameters.Types);
7674
7675                         return true;
7676                 }
7677
7678                 public override string GetDocCommentName (DeclSpace ds)
7679                 {
7680                         return DocUtil.GetMethodDocCommentName (this, parameters, ds);
7681                 }
7682
7683                 public override string GetSignatureForError ()
7684                 {
7685                         StringBuilder sb = new StringBuilder (Parent.GetSignatureForError ());
7686                         if (MemberName.Left != null) {
7687                                 sb.Append ('.');
7688                                 sb.Append (MemberName.Left);
7689                         }
7690
7691                         sb.Append (".this");
7692                         sb.Append (parameters.GetSignatureForError ().Replace ('(', '[').Replace (')', ']'));
7693                         return sb.ToString ();
7694                 }
7695
7696                 public override bool MarkForDuplicationCheck ()
7697                 {
7698                         caching_flags |= Flags.TestMethodDuplication;
7699                         return true;
7700                 }
7701
7702                 protected override PropertyInfo ResolveBaseProperty ()
7703                 {
7704                         return Parent.PartialContainer.BaseCache.FindMemberToOverride (
7705                                 Parent.TypeBuilder, Name, parameters.Types, null, true) as PropertyInfo;
7706                 }
7707
7708                 protected override bool VerifyClsCompliance ()
7709                 {
7710                         if (!base.VerifyClsCompliance ())
7711                                 return false;
7712
7713                         parameters.VerifyClsCompliance ();
7714                         return true;
7715                 }
7716         }
7717
7718         public class Operator : MethodOrOperator, IAnonymousHost {
7719
7720                 const int AllowedModifiers =
7721                         Modifiers.PUBLIC |
7722                         Modifiers.UNSAFE |
7723                         Modifiers.EXTERN |
7724                         Modifiers.STATIC;
7725
7726                 public enum OpType : byte {
7727
7728                         // Unary operators
7729                         LogicalNot,
7730                         OnesComplement,
7731                         Increment,
7732                         Decrement,
7733                         True,
7734                         False,
7735
7736                         // Unary and Binary operators
7737                         Addition,
7738                         Subtraction,
7739
7740                         UnaryPlus,
7741                         UnaryNegation,
7742                         
7743                         // Binary operators
7744                         Multiply,
7745                         Division,
7746                         Modulus,
7747                         BitwiseAnd,
7748                         BitwiseOr,
7749                         ExclusiveOr,
7750                         LeftShift,
7751                         RightShift,
7752                         Equality,
7753                         Inequality,
7754                         GreaterThan,
7755                         LessThan,
7756                         GreaterThanOrEqual,
7757                         LessThanOrEqual,
7758
7759                         // Implicit and Explicit
7760                         Implicit,
7761                         Explicit,
7762
7763                         // Just because of enum
7764                         TOP
7765                 };
7766
7767                 public readonly OpType OperatorType;
7768                 
7769                 public Operator (DeclSpace parent, OpType type, Expression ret_type,
7770                                  int mod_flags, Parameters parameters,
7771                                  ToplevelBlock block, Attributes attrs, Location loc)
7772                         : base (parent, null, ret_type, mod_flags, AllowedModifiers, false,
7773                                 new MemberName ("op_" + type.ToString(), loc), attrs, parameters)
7774                 {
7775                         OperatorType = type;
7776                         Block = block;
7777                 }
7778
7779                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb) 
7780                 {
7781                         if (a.Type == TypeManager.conditional_attribute_type) {
7782                                 Error_ConditionalAttributeIsNotValid ();
7783                                 return;
7784                         }
7785
7786                         base.ApplyAttributeBuilder (a, cb);
7787                 }
7788                 
7789                 protected override bool CheckForDuplications ()
7790                 {
7791                         ArrayList ar = Parent.PartialContainer.Operators;
7792                         if (ar != null) {
7793                                 int arLen = ar.Count;
7794                                         
7795                                 for (int i = 0; i < arLen; i++) {
7796                                         Operator o = (Operator) ar [i];
7797                                         if (IsDuplicateImplementation (o))
7798                                                 return false;
7799                                 }
7800                         }
7801
7802                         ar = Parent.PartialContainer.Methods;
7803                         if (ar != null) {
7804                                 int arLen = ar.Count;
7805                                         
7806                                 for (int i = 0; i < arLen; i++) {
7807                                         Method m = (Method) ar [i];
7808                                         if (IsDuplicateImplementation (m))
7809                                                 return false;
7810                                 }
7811                         }
7812
7813                         return true;
7814                 }
7815
7816                 public override bool Define ()
7817                 {
7818                         const int RequiredModifiers = Modifiers.PUBLIC | Modifiers.STATIC;
7819                         if ((ModFlags & RequiredModifiers) != RequiredModifiers){
7820                                 Report.Error (558, Location, "User-defined operator `{0}' must be declared static and public", GetSignatureForError ());
7821                                 return false;
7822                         }
7823
7824                         // imlicit and explicit operator of same types are not allowed
7825                         if (OperatorType == OpType.Explicit || OperatorType == OpType.Implicit)
7826                                 MarkForDuplicationCheck ();
7827
7828                         if (!base.Define ())
7829                                 return false;
7830
7831                         if (MemberType == TypeManager.void_type) {
7832                                 Report.Error (590, Location, "User-defined operators cannot return void");
7833                                 return false;
7834                         }
7835
7836                         Type declaring_type = MethodData.DeclaringType;
7837                         Type return_type = MemberType;
7838                         Type first_arg_type = ParameterTypes [0];
7839
7840                         // Rules for conversion operators
7841                         
7842                         if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
7843                                 if (first_arg_type == return_type && first_arg_type == declaring_type){
7844                                         Report.Error (555, Location,
7845                                                 "User-defined operator cannot take an object of the enclosing type and convert to an object of the enclosing type");
7846                                         return false;
7847                                 }
7848                                 
7849                                 if ((first_arg_type != declaring_type) && (return_type != declaring_type) &&
7850                                     !TypeManager.IsNullableTypeOf (first_arg_type, declaring_type) &&
7851                                     !TypeManager.IsNullableTypeOf (return_type, declaring_type)) {
7852                                         Report.Error (
7853                                                 556, Location, 
7854                                                 "User-defined conversion must convert to or from the " +
7855                                                 "enclosing type");
7856                                         return false;
7857                                 }
7858
7859                                 if (first_arg_type.IsInterface || return_type.IsInterface){
7860                                         Report.Error (552, Location, "User-defined conversion `{0}' cannot convert to or from an interface type",
7861                                                 GetSignatureForError ());
7862                                         return false;
7863                                 }
7864                                 
7865                                 if (first_arg_type.IsSubclassOf (return_type) || return_type.IsSubclassOf (first_arg_type)) {
7866                                         if (declaring_type.IsSubclassOf (return_type) || declaring_type.IsSubclassOf (first_arg_type)) {
7867                                                 Report.Error (553, Location, "User-defined conversion `{0}' cannot convert to or from base class",
7868                                                         GetSignatureForError ());
7869                                                 return false;
7870                                         }
7871                                         Report.Error (554, Location, "User-defined conversion `{0}' cannot convert to or from derived class",
7872                                                 GetSignatureForError ());
7873                                         return false;
7874                                 }
7875                         } else if (OperatorType == OpType.LeftShift || OperatorType == OpType.RightShift) {
7876                                 if (first_arg_type != declaring_type || ParameterTypes [1] != TypeManager.int32_type) {
7877                                         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");
7878                                         return false;
7879                                 }
7880                         } else if (Parameters.Count == 1) {
7881                                 // Checks for Unary operators
7882
7883                                 if (OperatorType == OpType.Increment || OperatorType == OpType.Decrement) {
7884                                         if (return_type != declaring_type && !TypeManager.IsSubclassOf (return_type, declaring_type)) {
7885                                                 Report.Error (448, Location,
7886                                                         "The return type for ++ or -- operator must be the containing type or derived from the containing type");
7887                                                 return false;
7888                                         }
7889                                         if (first_arg_type != declaring_type) {
7890                                                 Report.Error (
7891                                                         559, Location, "The parameter type for ++ or -- operator must be the containing type");
7892                                                 return false;
7893                                         }
7894                                 }
7895                                 
7896                                 if (first_arg_type != declaring_type){
7897                                         Report.Error (
7898                                                 562, Location,
7899                                                 "The parameter of a unary operator must be the " +
7900                                                 "containing type");
7901                                         return false;
7902                                 }
7903                                 
7904                                 if (OperatorType == OpType.True || OperatorType == OpType.False) {
7905                                         if (return_type != TypeManager.bool_type){
7906                                                 Report.Error (
7907                                                         215, Location,
7908                                                         "The return type of operator True or False " +
7909                                                         "must be bool");
7910                                                 return false;
7911                                         }
7912                                 }
7913                                 
7914                         } else {
7915                                 // Checks for Binary operators
7916                                 
7917                                 if (first_arg_type != declaring_type &&
7918                                     ParameterTypes [1] != declaring_type){
7919                                         Report.Error (
7920                                                 563, Location,
7921                                                 "One of the parameters of a binary operator must " +
7922                                                 "be the containing type");
7923                                         return false;
7924                                 }
7925                         }
7926
7927                         return true;
7928                 }
7929
7930                 protected override bool DoDefine ()
7931                 {
7932                         if (!base.DoDefine ())
7933                                 return false;
7934
7935                         flags |= MethodAttributes.SpecialName | MethodAttributes.HideBySig;
7936                         return true;
7937                 }
7938                 
7939                 public override void Emit ()
7940                 {
7941                         base.Emit ();
7942
7943                         Parameters.ApplyAttributes (MethodBuilder);
7944
7945                         //
7946                         // abstract or extern methods have no bodies
7947                         //
7948                         if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
7949                                 return;
7950                         
7951                         EmitContext ec;
7952                         if ((flags & MethodAttributes.PinvokeImpl) == 0)
7953                                 ec = CreateEmitContext (Parent, MethodBuilder.GetILGenerator ());
7954                         else
7955                                 ec = CreateEmitContext (Parent, null);
7956                         
7957                         SourceMethod source = SourceMethod.Create (Parent, MethodBuilder, Block);
7958                         ec.EmitTopBlock (this, Block);
7959
7960                         if (source != null)
7961                                 source.CloseMethod ();
7962
7963                         Block = null;
7964                 }
7965
7966                 // Operator cannot be override
7967                 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
7968                 {
7969                         return null;
7970                 }
7971
7972                 public static string GetName (OpType ot)
7973                 {
7974                         switch (ot){
7975                         case OpType.LogicalNot:
7976                                 return "!";
7977                         case OpType.OnesComplement:
7978                                 return "~";
7979                         case OpType.Increment:
7980                                 return "++";
7981                         case OpType.Decrement:
7982                                 return "--";
7983                         case OpType.True:
7984                                 return "true";
7985                         case OpType.False:
7986                                 return "false";
7987                         case OpType.Addition:
7988                                 return "+";
7989                         case OpType.Subtraction:
7990                                 return "-";
7991                         case OpType.UnaryPlus:
7992                                 return "+";
7993                         case OpType.UnaryNegation:
7994                                 return "-";
7995                         case OpType.Multiply:
7996                                 return "*";
7997                         case OpType.Division:
7998                                 return "/";
7999                         case OpType.Modulus:
8000                                 return "%";
8001                         case OpType.BitwiseAnd:
8002                                 return "&";
8003                         case OpType.BitwiseOr:
8004                                 return "|";
8005                         case OpType.ExclusiveOr:
8006                                 return "^";
8007                         case OpType.LeftShift:
8008                                 return "<<";
8009                         case OpType.RightShift:
8010                                 return ">>";
8011                         case OpType.Equality:
8012                                 return "==";
8013                         case OpType.Inequality:
8014                                 return "!=";
8015                         case OpType.GreaterThan:
8016                                 return ">";
8017                         case OpType.LessThan:
8018                                 return "<";
8019                         case OpType.GreaterThanOrEqual:
8020                                 return ">=";
8021                         case OpType.LessThanOrEqual:
8022                                 return "<=";
8023                         case OpType.Implicit:
8024                                 return "implicit";
8025                         case OpType.Explicit:
8026                                 return "explicit";
8027                         default: return "";
8028                         }
8029                 }
8030
8031                 public static OpType GetOperatorType (string name)
8032                 {
8033                         if (name.StartsWith ("op_")){
8034                                 for (int i = 0; i < Unary.oper_names.Length; ++i) {
8035                                         if (Unary.oper_names [i] == name)
8036                                                 return (OpType)i;
8037                                 }
8038
8039                                 for (int i = 0; i < Binary.oper_names.Length; ++i) {
8040                                         if (Binary.oper_names [i] == name)
8041                                                 return (OpType)i;
8042                                 }
8043                         }
8044                         return OpType.TOP;
8045                 }
8046
8047                 public override string GetSignatureForError ()
8048                 {
8049                         StringBuilder sb = new StringBuilder ();
8050                         if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
8051                                 sb.AppendFormat ("{0}.{1} operator {2}", Parent.GetSignatureForError (), GetName (OperatorType), Type.Type == null ? Type.ToString () : TypeManager.CSharpName (Type.Type));
8052                         }
8053                         else {
8054                                 sb.AppendFormat ("{0}.operator {1}", Parent.GetSignatureForError (), GetName (OperatorType));
8055                         }
8056
8057                         sb.Append (Parameters.GetSignatureForError ());
8058                         return sb.ToString ();
8059                 }
8060         }
8061
8062         //
8063         // This is used to compare method signatures
8064         //
8065         struct MethodSignature {
8066                 public string Name;
8067                 public Type RetType;
8068                 public Type [] Parameters;
8069                 
8070                 /// <summary>
8071                 ///    This delegate is used to extract methods which have the
8072                 ///    same signature as the argument
8073                 /// </summary>
8074                 public static MemberFilter method_signature_filter = new MemberFilter (MemberSignatureCompare);
8075                 
8076                 public MethodSignature (string name, Type ret_type, Type [] parameters)
8077                 {
8078                         Name = name;
8079                         RetType = ret_type;
8080
8081                         if (parameters == null)
8082                                 Parameters = Type.EmptyTypes;
8083                         else
8084                                 Parameters = parameters;
8085                 }
8086
8087                 public override string ToString ()
8088                 {
8089                         string pars = "";
8090                         if (Parameters.Length != 0){
8091                                 System.Text.StringBuilder sb = new System.Text.StringBuilder ();
8092                                 for (int i = 0; i < Parameters.Length; i++){
8093                                         sb.Append (Parameters [i]);
8094                                         if (i+1 < Parameters.Length)
8095                                                 sb.Append (", ");
8096                                 }
8097                                 pars = sb.ToString ();
8098                         }
8099
8100                         return String.Format ("{0} {1} ({2})", RetType, Name, pars);
8101                 }
8102                 
8103                 public override int GetHashCode ()
8104                 {
8105                         return Name.GetHashCode ();
8106                 }
8107
8108                 public override bool Equals (Object o)
8109                 {
8110                         MethodSignature other = (MethodSignature) o;
8111
8112                         if (other.Name != Name)
8113                                 return false;
8114
8115                         if (other.RetType != RetType)
8116                                 return false;
8117                         
8118                         if (Parameters == null){
8119                                 if (other.Parameters == null)
8120                                         return true;
8121                                 return false;
8122                         }
8123
8124                         if (other.Parameters == null)
8125                                 return false;
8126                         
8127                         int c = Parameters.Length;
8128                         if (other.Parameters.Length != c)
8129                                 return false;
8130
8131                         for (int i = 0; i < c; i++)
8132                                 if (other.Parameters [i] != Parameters [i])
8133                                         return false;
8134
8135                         return true;
8136                 }
8137
8138                 static bool MemberSignatureCompare (MemberInfo m, object filter_criteria)
8139                 {
8140                         MethodSignature sig = (MethodSignature) filter_criteria;
8141
8142                         if (m.Name != sig.Name)
8143                                 return false;
8144
8145                         Type ReturnType;
8146                         MethodInfo mi = m as MethodInfo;
8147                         PropertyInfo pi = m as PropertyInfo;
8148
8149                         if (mi != null)
8150                                 ReturnType = mi.ReturnType;
8151                         else if (pi != null)
8152                                 ReturnType = pi.PropertyType;
8153                         else
8154                                 return false;
8155                         
8156                         //
8157                         // we use sig.RetType == null to mean `do not check the
8158                         // method return value.  
8159                         //
8160                         if (sig.RetType != null)
8161                                 if (ReturnType != sig.RetType)
8162                                         return false;
8163
8164                         Type [] args;
8165                         if (mi != null)
8166                                 args = TypeManager.GetParameterData (mi).Types;
8167                         else
8168                                 args = TypeManager.GetArgumentTypes (pi);
8169                         Type [] sigp = sig.Parameters;
8170
8171                         if (args.Length != sigp.Length)
8172                                 return false;
8173
8174                         for (int i = args.Length; i > 0; ){
8175                                 i--;
8176                                 if (args [i] != sigp [i])
8177                                         return false;
8178                         }
8179                         return true;
8180                 }
8181         }
8182 }