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