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