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