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