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                         if (OptAttributes != null) 
4559                                 OptAttributes.Emit ();
4560
4561                         ec.EmitTopBlock (this, block);
4562
4563                         if (source != null)
4564                                 source.CloseMethod ();
4565
4566                         base.Emit ();
4567
4568                         if (declarative_security != null) {
4569                                 foreach (DictionaryEntry de in declarative_security) {
4570                                         ConstructorBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
4571                                 }
4572                         }
4573
4574                         block = null;
4575                 }
4576
4577                 // Is never override
4578                 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
4579                 {
4580                         return null;
4581                 }
4582
4583                 public override string GetSignatureForError()
4584                 {
4585                         return base.GetSignatureForError () + Parameters.GetSignatureForError ();
4586                 }
4587
4588                 protected override bool VerifyClsCompliance ()
4589                 {
4590                         if (!base.VerifyClsCompliance () || !IsExposedFromAssembly ()) {
4591                                 return false;
4592                         }
4593                         
4594                         if (ParameterInfo.Count > 0) {
4595                                 ArrayList al = (ArrayList)Parent.MemberCache.Members [".ctor"];
4596                                 if (al.Count > 3)
4597                                         MemberCache.VerifyClsParameterConflict (al, this, ConstructorBuilder);
4598  
4599                                 if (Parent.TypeBuilder.IsSubclassOf (TypeManager.attribute_type)) {
4600                                         foreach (Type param in ParameterTypes) {
4601                                                 if (param.IsArray) {
4602                                                         return true;
4603                                                 }
4604                                         }
4605                                 }
4606                         }
4607                         has_compliant_args = true;
4608                         return true;
4609                 }
4610
4611                 #region IMethodData Members
4612
4613                 public System.Reflection.CallingConventions CallingConventions {
4614                         get {
4615                                 CallingConventions cc = Parameters.CallingConvention;
4616
4617                                 if (ParentContainer.Kind == Kind.Class)
4618                                         if ((ModFlags & Modifiers.STATIC) == 0)
4619                                                 cc |= CallingConventions.HasThis;
4620
4621                                 // FIXME: How is `ExplicitThis' used in C#?
4622                         
4623                                 return cc;
4624                                 }
4625                         }
4626                         
4627                 public new Location Location {
4628                         get {
4629                                 return base.Location;
4630                         }
4631                 }
4632
4633                 public MemberName MethodName {
4634                         get {
4635                                 return MemberName;
4636                         }
4637                 }
4638                         
4639                 public Type ReturnType {
4640                         get {
4641                                 return MemberType;
4642                         }
4643                 }
4644
4645                 public EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig)
4646                 {
4647                         ILGenerator ig_ = ConstructorBuilder.GetILGenerator ();
4648                         return new EmitContext (this, Parent, Location, ig_, null, ModFlags, true);
4649                 }
4650
4651                 public bool IsExcluded()
4652                 {
4653                         return false;
4654                 }
4655
4656                 GenericMethod IMethodData.GenericMethod {
4657                         get {
4658                                 return null;
4659                         }
4660                 }
4661
4662                 #endregion
4663         }
4664
4665         /// <summary>
4666         /// Interface for MethodData class. Holds links to parent members to avoid member duplication.
4667         /// </summary>
4668         public interface IMethodData
4669         {
4670                 CallingConventions CallingConventions { get; }
4671                 Location Location { get; }
4672                 MemberName MethodName { get; }
4673                 Type ReturnType { get; }
4674                 GenericMethod GenericMethod { get; }
4675                 Parameters ParameterInfo { get; }
4676
4677                 Attributes OptAttributes { get; }
4678                 ToplevelBlock Block { get; set; }
4679
4680                 EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig);
4681                 ObsoleteAttribute GetObsoleteAttribute ();
4682                 string GetSignatureForError ();
4683                 bool IsExcluded ();
4684                 bool IsClsComplianceRequired ();
4685                 void SetMemberIsUsed ();
4686         }
4687
4688         //
4689         // Encapsulates most of the Method's state
4690         //
4691         public class MethodData {
4692
4693                 readonly IMethodData method;
4694
4695                 public readonly GenericMethod GenericMethod;
4696
4697                 //
4698                 // Are we implementing an interface ?
4699                 //
4700                 public MethodInfo implementing;
4701
4702                 //
4703                 // Protected data.
4704                 //
4705                 protected MemberBase member;
4706                 protected int modifiers;
4707                 protected MethodAttributes flags;
4708                 protected Type declaring_type;
4709                 protected MethodInfo parent_method;
4710
4711                 MethodBuilder builder = null;
4712                 public MethodBuilder MethodBuilder {
4713                         get {
4714                                 return builder;
4715                         }
4716                 }
4717
4718                 public Type DeclaringType {
4719                         get {
4720                                 return declaring_type;
4721                         }
4722                 }
4723
4724                 public MethodData (MemberBase member,
4725                                    int modifiers, MethodAttributes flags, IMethodData method)
4726                 {
4727                         this.member = member;
4728                         this.modifiers = modifiers;
4729                         this.flags = flags;
4730
4731                         this.method = method;
4732                 }
4733
4734                 public MethodData (MemberBase member, 
4735                                    int modifiers, MethodAttributes flags, 
4736                                    IMethodData method, MethodBuilder builder,
4737                                    GenericMethod generic, MethodInfo parent_method)
4738                         : this (member, modifiers, flags, method)
4739                 {
4740                         this.builder = builder;
4741                         this.GenericMethod = generic;
4742                         this.parent_method = parent_method;
4743                 }
4744
4745                 public bool Define (DeclSpace parent)
4746                 {
4747                         string name = method.MethodName.Basename;
4748                         string method_name = method.MethodName.FullName;
4749
4750                         TypeContainer container = ((TypeContainer) parent).PartialContainer;
4751
4752                         PendingImplementation pending = container.PendingImplementations;
4753                         if (pending != null){
4754                                 if (member is Indexer) // TODO: test it, but it should work without this IF
4755                                         implementing = pending.IsInterfaceIndexer (
4756                                                 member.InterfaceType, method.ReturnType, method.ParameterInfo);
4757                                 else
4758                                         implementing = pending.IsInterfaceMethod (
4759                                                 member.InterfaceType, name, method.ReturnType, method.ParameterInfo);
4760
4761                                 if (member.InterfaceType != null){
4762                                         if (implementing == null){
4763                                                 if (member is PropertyBase) {
4764                                                         Report.Error (550, method.Location, "`{0}' is an accessor not found in interface member `{1}{2}'",
4765                                                                       method.GetSignatureForError (), TypeManager.CSharpName (member.InterfaceType),
4766                                                                       member.GetSignatureForError ().Substring (member.GetSignatureForError ().LastIndexOf ('.')));
4767
4768                                                 } else {
4769                                                         Report.Error (539, method.Location,
4770                                                                       "`{0}.{1}' in explicit interface declaration is not a member of interface",
4771                                                                       TypeManager.CSharpName (member.InterfaceType), member.ShortName);
4772                                                 }
4773                                                 return false;
4774                                         }
4775                                         if (implementing.IsSpecialName && !(method is AbstractPropertyEventMethod)) {
4776                                                 Report.SymbolRelatedToPreviousError (implementing);
4777                                                 Report.Error (683, method.Location, "`{0}' explicit method implementation cannot implement `{1}' because it is an accessor",
4778                                                         member.GetSignatureForError (), TypeManager.CSharpSignature (implementing));
4779                                                 return false;
4780                                         }
4781
4782                                         method_name = TypeManager.GetFullName (member.InterfaceType) +
4783                                                 '.' + method_name;
4784                                 } else {
4785                                         if (implementing != null) {
4786                                                 AbstractPropertyEventMethod prop_method = method as AbstractPropertyEventMethod;
4787                                                 if (prop_method != null) {
4788                                                         if (!implementing.IsSpecialName) {
4789                                                                 Report.SymbolRelatedToPreviousError (implementing);
4790                                                                 Report.Error (686, method.Location, "Accessor `{0}' cannot implement interface member `{1}' for type `{2}'. Use an explicit interface implementation",
4791                                                                         method.GetSignatureForError (), TypeManager.CSharpSignature (implementing), container.GetSignatureForError ());
4792                                                                 return false;
4793                                                         }
4794                                                         PropertyBase.PropertyMethod pm = prop_method as PropertyBase.PropertyMethod;
4795                                                         if (pm != null && pm.HasCustomAccessModifier && (pm.ModFlags & Modifiers.PUBLIC) == 0) {
4796                                                                 Report.SymbolRelatedToPreviousError (implementing);
4797                                                                 Report.Error (277, method.Location, "Accessor `{0}' must be declared public to implement interface member `{1}'",
4798                                                                         method.GetSignatureForError (), TypeManager.CSharpSignature (implementing, true));
4799                                                                 return false;
4800                                                         }
4801                                                 }
4802                                         }
4803                                 }
4804                         }
4805
4806                         //
4807                         // For implicit implementations, make sure we are public, for
4808                         // explicit implementations, make sure we are private.
4809                         //
4810                         if (implementing != null){
4811                                 //
4812                                 // Setting null inside this block will trigger a more
4813                                 // verbose error reporting for missing interface implementations
4814                                 //
4815                                 // The "candidate" function has been flagged already
4816                                 // but it wont get cleared
4817                                 //
4818                                 if (member.IsExplicitImpl){
4819                                         if ((modifiers & (Modifiers.PUBLIC | Modifiers.ABSTRACT | Modifiers.VIRTUAL)) != 0){
4820                                                 Modifiers.Error_InvalidModifier (method.Location, "public, virtual or abstract");
4821                                                 implementing = null;
4822                                         }
4823                                 } else if ((flags & MethodAttributes.MemberAccessMask) != MethodAttributes.Public){
4824                                         if (TypeManager.IsInterfaceType (implementing.DeclaringType)){
4825                                                 //
4826                                                 // If this is an interface method implementation,
4827                                                 // check for public accessibility
4828                                                 //
4829                                                 implementing = null;
4830                                         } else if ((flags & MethodAttributes.MemberAccessMask) == MethodAttributes.Private){
4831                                                 // We may never be private.
4832                                                 implementing = null;
4833                                         } else if ((modifiers & Modifiers.OVERRIDE) == 0){
4834                                                 //
4835                                                 // We may be protected if we're overriding something.
4836                                                 //
4837                                                 implementing = null;
4838                                         }
4839                                 } 
4840                                         
4841                                 //
4842                                 // Static is not allowed
4843                                 //
4844                                 if ((modifiers & Modifiers.STATIC) != 0){
4845                                         implementing = null;
4846                                 }
4847                         }
4848                         
4849                         //
4850                         // If implementing is still valid, set flags
4851                         //
4852                         if (implementing != null){
4853                                 //
4854                                 // When implementing interface methods, set NewSlot
4855                                 // unless, we are overwriting a method.
4856                                 //
4857                                 if (implementing.DeclaringType.IsInterface){
4858                                         if ((modifiers & Modifiers.OVERRIDE) == 0)
4859                                                 flags |= MethodAttributes.NewSlot;
4860                                 }
4861                                 flags |=
4862                                         MethodAttributes.Virtual |
4863                                         MethodAttributes.HideBySig;
4864
4865                                 // Set Final unless we're virtual, abstract or already overriding a method.
4866                                 if ((modifiers & (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE)) == 0)
4867                                         flags |= MethodAttributes.Final;
4868                         }
4869
4870                         EmitContext ec = method.CreateEmitContext (container, null);
4871
4872                         DefineMethodBuilder (container, method_name, method.ParameterInfo.Types);
4873
4874                         if (builder == null)
4875                                 return false;
4876
4877                         if (container.CurrentType != null)
4878                                 declaring_type = container.CurrentType;
4879                         else
4880                                 declaring_type = container.TypeBuilder;
4881
4882                         if ((modifiers & Modifiers.UNSAFE) != 0)
4883                                 builder.InitLocals = false;
4884
4885                         if (implementing != null){
4886                                 //
4887                                 // clear the pending implemntation flag
4888                                 //
4889                                 if (member is Indexer) {
4890                                         pending.ImplementIndexer (
4891                                                 member.InterfaceType, builder, method.ReturnType,
4892                                                 method.ParameterInfo, member.IsExplicitImpl);
4893                                 } else
4894                                         pending.ImplementMethod (
4895                                                 member.InterfaceType, name, method.ReturnType,
4896                                                 method.ParameterInfo, member.IsExplicitImpl);
4897
4898                                 if (member.IsExplicitImpl)
4899                                         container.TypeBuilder.DefineMethodOverride (
4900                                                 builder, implementing);
4901
4902                         }
4903
4904                         TypeManager.AddMethod (builder, method);
4905
4906                         if (GenericMethod != null) {
4907                                 bool is_override = member.IsExplicitImpl |
4908                                         ((modifiers & Modifiers.OVERRIDE) != 0);
4909
4910                                 if (implementing != null)
4911                                         parent_method = implementing;
4912
4913                                 if (!GenericMethod.DefineType (ec, builder, parent_method, is_override))
4914                                         return false;
4915                         }
4916
4917                         return true;
4918                 }
4919
4920
4921                 /// <summary>
4922                 /// Create the MethodBuilder for the method 
4923                 /// </summary>
4924                 void DefineMethodBuilder (TypeContainer container, string method_name, Type[] ParameterTypes)
4925                 {
4926                         const int extern_static = Modifiers.EXTERN | Modifiers.STATIC;
4927
4928                         if ((modifiers & extern_static) == extern_static) {
4929
4930                                 if (method.OptAttributes != null) {
4931                                         Attribute dllimport_attribute = method.OptAttributes.Search (TypeManager.dllimport_type);
4932                                         if (dllimport_attribute != null) {
4933                                                 flags |= MethodAttributes.PinvokeImpl;
4934                                                 builder = dllimport_attribute.DefinePInvokeMethod (
4935                                                         container.TypeBuilder, method_name, flags,
4936                                                         method.ReturnType, ParameterTypes);
4937
4938                                                 return;
4939                                         }
4940                                 }
4941
4942                                 // for extern static method must be specified either DllImport attribute or MethodImplAttribute.
4943                                 // We are more strict than Microsoft and report CS0626 like error
4944                                 if (method.OptAttributes == null ||
4945                                         !method.OptAttributes.Contains (TypeManager.methodimpl_attr_type)) {
4946                                         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",
4947                                                 method.GetSignatureForError ());
4948                                         return;
4949                                 }
4950                         }
4951
4952                         if (builder == null) {
4953                                 builder = container.TypeBuilder.DefineMethod (
4954                                         method_name, flags, method.CallingConventions,
4955                                         method.ReturnType, ParameterTypes);
4956                                 return;
4957                         }
4958 #if !MS_COMPATIBLE
4959                                 builder.SetGenericMethodSignature (
4960                                         flags, method.CallingConventions,
4961                                         method.ReturnType, ParameterTypes);
4962 #endif
4963                 }
4964
4965                 //
4966                 // Emits the code
4967                 // 
4968                 public void Emit (DeclSpace parent)
4969                 {
4970                         EmitContext ec;
4971                         if ((flags & MethodAttributes.PinvokeImpl) == 0)
4972                                 ec = method.CreateEmitContext (parent, builder.GetILGenerator ());
4973                         else
4974                                 ec = method.CreateEmitContext (parent, null);
4975
4976                         method.ParameterInfo.ApplyAttributes (MethodBuilder);
4977
4978                         if (GenericMethod != null)
4979                                 GenericMethod.EmitAttributes ();
4980
4981                         ToplevelBlock block = method.Block;
4982                         
4983                         SourceMethod source = SourceMethod.Create (parent, MethodBuilder, method.Block);
4984
4985                         //
4986                         // Handle destructors specially
4987                         //
4988                         // FIXME: This code generates buggy code
4989                         //
4990                         if (member is Destructor)
4991                                 EmitDestructor (ec, block);
4992                         else
4993                                 ec.EmitTopBlock (method, block);
4994
4995                         if (source != null)
4996                                 source.CloseMethod ();
4997                 }
4998
4999                 void EmitDestructor (EmitContext ec, ToplevelBlock block)
5000                 {
5001                         ILGenerator ig = ec.ig;
5002                         
5003                         Label finish = ig.DefineLabel ();
5004
5005                         block.SetDestructor ();
5006                         
5007                         ig.BeginExceptionBlock ();
5008                         ec.ReturnLabel = finish;
5009                         ec.HasReturnLabel = true;
5010                         ec.EmitTopBlock (method, block);
5011                         
5012                         // ig.MarkLabel (finish);
5013                         ig.BeginFinallyBlock ();
5014                         
5015                         if (ec.ContainerType.BaseType != null) {
5016                                 Expression member_lookup = Expression.MemberLookup (
5017                                         ec.ContainerType.BaseType, null, ec.ContainerType.BaseType,
5018                                         "Finalize", MemberTypes.Method, Expression.AllBindingFlags, method.Location);
5019
5020                                 if (member_lookup != null){
5021                                         MethodGroupExpr base_destructor = ((MethodGroupExpr) member_lookup);
5022                                 
5023                                         ig.Emit (OpCodes.Ldarg_0);
5024                                         ig.Emit (OpCodes.Call, (MethodInfo) base_destructor.Methods [0]);
5025                                 }
5026                         }
5027                         
5028                         ig.EndExceptionBlock ();
5029                         //ig.MarkLabel (ec.ReturnLabel);
5030                         ig.Emit (OpCodes.Ret);
5031                 }
5032         }
5033
5034         // TODO: Should derive from MethodCore
5035         public class Destructor : Method {
5036
5037                 public Destructor (DeclSpace parent, Expression return_type, int mod,
5038                                    string name, Parameters parameters, Attributes attrs,
5039                                    Location l)
5040                         : base (parent, null, return_type, mod, false, new MemberName (name, l),
5041                                 parameters, attrs)
5042                 { }
5043
5044                 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
5045                 {
5046                         if (a.Type == TypeManager.conditional_attribute_type) {
5047                                 Error_ConditionalAttributeIsNotValid ();
5048                                 return;
5049                         }
5050
5051                         base.ApplyAttributeBuilder (a, cb);
5052                 }
5053
5054                 public override string GetSignatureForError ()
5055                 {
5056                         return Parent.GetSignatureForError () + ".~" + Parent.MemberName.Name + "()";
5057                 }
5058
5059         }
5060         
5061         abstract public class MemberBase : MemberCore {
5062                 public Expression Type;
5063
5064                 public MethodAttributes flags;
5065                 public readonly DeclSpace ds;
5066                 public readonly GenericMethod GenericMethod;
5067
5068                 protected readonly int explicit_mod_flags;
5069
5070                 //
5071                 // The "short" name of this property / indexer / event.  This is the
5072                 // name without the explicit interface.
5073                 //
5074                 public string ShortName {
5075                         get { return MemberName.Name; }
5076                         set { SetMemberName (new MemberName (MemberName.Left, value, Location)); }
5077                 }
5078
5079                 public TypeContainer ParentContainer {
5080                         get { return ((TypeContainer) Parent).PartialContainer; }
5081                 }
5082
5083                 //
5084                 // The type of this property / indexer / event
5085                 //
5086                 protected Type member_type;
5087                 public Type MemberType {
5088                         get {
5089                                 if (member_type == null && Type != null) {
5090                                         IResolveContext rc = GenericMethod == null ? this : (IResolveContext)ds;
5091                                         Type = Type.ResolveAsTypeTerminal (rc, false);
5092                                         if (Type != null) {
5093                                                 member_type = Type.Type;
5094                                         }
5095                                 }
5096                                 return member_type;
5097                         }
5098                 }
5099
5100                 //
5101                 // Whether this is an interface member.
5102                 //
5103                 public bool IsInterface;
5104
5105                 //
5106                 // If true, this is an explicit interface implementation
5107                 //
5108                 public bool IsExplicitImpl;
5109
5110                 //
5111                 // The interface type we are explicitly implementing
5112                 //
5113                 public Type InterfaceType = null;
5114
5115                 //
5116                 // The constructor is only exposed to our children
5117                 //
5118                 protected MemberBase (DeclSpace parent, GenericMethod generic,
5119                                       Expression type, int mod, int allowed_mod, int def_mod,
5120                                       MemberName name, Attributes attrs)
5121                         : base (parent, name, attrs)
5122                 {
5123                         this.ds = generic != null ? generic : (DeclSpace) parent;
5124                         explicit_mod_flags = mod;
5125                         Type = type;
5126                         ModFlags = Modifiers.Check (allowed_mod, mod, def_mod, Location);
5127                         IsExplicitImpl = (MemberName.Left != null);
5128                         GenericMethod = generic;
5129                         if (GenericMethod != null)
5130                                 GenericMethod.ModFlags = ModFlags;
5131                 }
5132
5133                 protected virtual bool CheckBase ()
5134                 {
5135                         if ((ModFlags & Modifiers.PROTECTED) != 0 && ParentContainer.Kind == Kind.Struct) {
5136                                 Report.Error (666, Location, "`{0}': new protected member declared in struct", GetSignatureForError ());
5137                                 return false;
5138                         }
5139    
5140                         if ((RootContext.WarningLevel >= 4) &&
5141                             ((Parent.ModFlags & Modifiers.SEALED) != 0) &&
5142                             ((ModFlags & Modifiers.PROTECTED) != 0) &&
5143                             ((ModFlags & Modifiers.OVERRIDE) == 0) && (Name != "Finalize")) {
5144                                 Report.Warning (628, 4, Location, "`{0}': new protected member declared in sealed class", GetSignatureForError ());
5145                         }
5146                         return true;
5147                 }
5148
5149                 protected virtual bool DoDefineBase ()
5150                 {
5151                         if (Name == null)
5152                                 throw new InternalErrorException ();
5153
5154                         if (IsInterface) {
5155                                 ModFlags = Modifiers.PUBLIC |
5156                                         Modifiers.ABSTRACT |
5157                                         Modifiers.VIRTUAL | (ModFlags & Modifiers.UNSAFE) | (ModFlags & Modifiers.NEW);
5158
5159                                 flags = MethodAttributes.Public |
5160                                         MethodAttributes.Abstract |
5161                                         MethodAttributes.HideBySig |
5162                                         MethodAttributes.NewSlot |
5163                                         MethodAttributes.Virtual;
5164                         } else {
5165                                 if (!ParentContainer.MethodModifiersValid (this))
5166                                         return false;
5167
5168                                 flags = Modifiers.MethodAttr (ModFlags);
5169                         }
5170
5171                         if (IsExplicitImpl) {
5172                                 Expression expr = MemberName.Left.GetTypeExpression ();
5173                                 TypeExpr iface_texpr = expr.ResolveAsTypeTerminal (this, false);
5174                                 if (iface_texpr == null)
5175                                         return false;
5176
5177                                 InterfaceType = iface_texpr.Type;
5178
5179                                 if (!InterfaceType.IsInterface) {
5180                                         Report.Error (538, Location, "'{0}' in explicit interface declaration is not an interface", TypeManager.CSharpName (InterfaceType));
5181                                         return false;
5182                                 }
5183
5184                                 if (!ParentContainer.VerifyImplements (this))
5185                                         return false;
5186                                 
5187                                 Modifiers.Check (Modifiers.AllowedExplicitImplFlags, explicit_mod_flags, 0, Location);
5188                         }
5189
5190                         return true;
5191                 }
5192
5193                 protected virtual bool DoDefine ()
5194                 {
5195                         if (MemberType == null)
5196                                 return false;
5197
5198                         if ((Parent.ModFlags & Modifiers.SEALED) != 0 && 
5199                                 (ModFlags & (Modifiers.VIRTUAL|Modifiers.ABSTRACT)) != 0) {
5200                                         Report.Error (549, Location, "New virtual member `{0}' is declared in a sealed class `{1}'",
5201                                                 GetSignatureForError (), Parent.GetSignatureForError ());
5202                                         return false;
5203                         }
5204                         
5205                         // verify accessibility
5206                         if (!Parent.AsAccessible (MemberType, ModFlags)) {
5207                                 Report.SymbolRelatedToPreviousError (MemberType);
5208                                 if (this is Property)
5209                                         Report.Error (53, Location,
5210                                                       "Inconsistent accessibility: property type `" +
5211                                                       TypeManager.CSharpName (MemberType) + "' is less " +
5212                                                       "accessible than property `" + GetSignatureForError () + "'");
5213                                 else if (this is Indexer)
5214                                         Report.Error (54, Location,
5215                                                       "Inconsistent accessibility: indexer return type `" +
5216                                                       TypeManager.CSharpName (MemberType) + "' is less " +
5217                                                       "accessible than indexer `" + GetSignatureForError () + "'");
5218                                 else if (this is MethodCore) {
5219                                         if (this is Operator)
5220                                                 Report.Error (56, Location,
5221                                                               "Inconsistent accessibility: return type `" +
5222                                                               TypeManager.CSharpName (MemberType) + "' is less " +
5223                                                               "accessible than operator `" + GetSignatureForError () + "'");
5224                                         else
5225                                                 Report.Error (50, Location,
5226                                                               "Inconsistent accessibility: return type `" +
5227                                                               TypeManager.CSharpName (MemberType) + "' is less " +
5228                                                               "accessible than method `" + GetSignatureForError () + "'");
5229                                 } else {
5230                                         Report.Error (52, Location,
5231                                                       "Inconsistent accessibility: field type `" +
5232                                                       TypeManager.CSharpName (MemberType) + "' is less " +
5233                                                       "accessible than field `" + GetSignatureForError () + "'");
5234                                 }
5235                                 return false;
5236                         }
5237
5238                         if (IsExplicitImpl) {
5239                                 Expression expr = MemberName.Left.GetTypeExpression ();
5240                                 TypeExpr texpr = expr.ResolveAsTypeTerminal (this, false);
5241                                 if (texpr == null)
5242                                         return false;
5243
5244                                 InterfaceType = texpr.Type;
5245
5246                                 if (!InterfaceType.IsInterface) {
5247                                         Report.Error (538, Location, "`{0}' in explicit interface declaration is not an interface", TypeManager.CSharpName (InterfaceType));
5248                                         return false;
5249                                 }
5250                                 
5251                                 if (!ParentContainer.VerifyImplements (this))
5252                                         return false;
5253                                 
5254                                 Modifiers.Check (Modifiers.AllowedExplicitImplFlags, explicit_mod_flags, 0, Location);
5255                                 
5256                         }
5257                         return true;
5258                 }
5259
5260                 protected bool IsTypePermitted ()
5261                 {
5262                         if (MemberType == TypeManager.arg_iterator_type || MemberType == TypeManager.typed_reference_type) {
5263                                 Report.Error (610, Location, "Field or property cannot be of type `{0}'", TypeManager.CSharpName (MemberType));
5264                                 return false;
5265                         }
5266                         return true;
5267                 }
5268
5269                 protected override bool VerifyClsCompliance()
5270                 {
5271                         if (base.VerifyClsCompliance ()) {
5272                                 return true;
5273                         }
5274
5275                         if (IsInterface && HasClsCompliantAttribute && Parent.IsClsComplianceRequired ()) {
5276                                 Report.Error (3010, Location, "`{0}': CLS-compliant interfaces must have only CLS-compliant members", GetSignatureForError ());
5277                         }
5278                         return false;
5279                 }
5280
5281         }
5282
5283         //
5284         // Fields and Events both generate FieldBuilders, we use this to share 
5285         // their common bits.  This is also used to flag usage of the field
5286         //
5287         abstract public class FieldBase : MemberBase {
5288                 public FieldBuilder  FieldBuilder;
5289                 public Status status;
5290                 protected Expression initializer;
5291                 ExpressionStatement initializerStatement;
5292
5293                 [Flags]
5294                 public enum Status : byte {
5295                         HAS_OFFSET = 4          // Used by FieldMember.
5296                 }
5297
5298                 static string[] attribute_targets = new string [] { "field" };
5299
5300                 /// <summary>
5301                 ///  Symbol with same name in base class/struct
5302                 /// </summary>
5303                 public MemberInfo conflict_symbol;
5304
5305                 protected FieldBase (DeclSpace parent, Expression type, int mod,
5306                                      int allowed_mod, MemberName name, Attributes attrs)
5307                         : base (parent, null, type, mod, allowed_mod, Modifiers.PRIVATE,
5308                                 name, attrs)
5309                 {
5310                 }
5311
5312                 public override AttributeTargets AttributeTargets {
5313                         get {
5314                                 return AttributeTargets.Field;
5315                         }
5316                 }
5317
5318                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
5319                 {
5320                         if (a.Type == TypeManager.marshal_as_attr_type) {
5321                                 UnmanagedMarshal marshal = a.GetMarshal (this);
5322                                 if (marshal != null) {
5323                                         FieldBuilder.SetMarshal (marshal);
5324                                 }
5325                                 return;
5326                         }
5327
5328                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
5329                                 a.Error_InvalidSecurityParent ();
5330                                 return;
5331                         }
5332
5333                         FieldBuilder.SetCustomAttribute (cb);
5334                 }
5335
5336                 public void EmitInitializer (EmitContext ec)
5337                 {
5338                         initializerStatement.EmitStatement (ec);
5339                 }
5340
5341                 protected override bool CheckBase ()
5342                 {
5343                         if (!base.CheckBase ())
5344                                 return false;
5345
5346                         // TODO: Implement
5347                         if (IsInterface)
5348                                 return true;
5349
5350                         conflict_symbol = ParentContainer.FindBaseMemberWithSameName (Name, false);
5351                         if (conflict_symbol == null) {
5352                                 if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0)) {
5353                                         Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
5354                                 }
5355                                 return true;
5356                         }
5357
5358                         if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE)) == 0) {
5359                                 Report.SymbolRelatedToPreviousError (conflict_symbol);
5360                                 Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
5361                                         GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
5362                         }
5363
5364                         return true;
5365                 }
5366
5367                 public Expression Initializer {
5368                         set {
5369                                 if (value != null) {
5370                                         this.initializer = value;
5371                                         ParentContainer.RegisterFieldForInitialization (this);
5372                                 }
5373                         }
5374                 }
5375
5376                 protected virtual bool IsFieldClsCompliant {
5377                         get {
5378                                 if (FieldBuilder == null)
5379                                         return true;
5380
5381                                 return AttributeTester.IsClsCompliant (FieldBuilder.FieldType);
5382                         }
5383                 }
5384
5385                 public Expression ResolveInitializer ()
5386                 {
5387                         // TODO: again it's too heavy-weight
5388                         EmitContext ec = new EmitContext (this, Parent, Location, null, null, ModFlags);
5389                         ec.IsFieldInitializer = true;
5390                         initializer = initializer.Resolve (ec);
5391                         if (initializer == null)
5392                                 return null;
5393
5394                         FieldExpr fe = new FieldExpr (FieldBuilder, Location, true);
5395                         if ((ModFlags & Modifiers.STATIC) == 0) 
5396                         {
5397                                 fe.InstanceExpression = CompilerGeneratedThis.Instance;
5398                         }
5399
5400                         initializerStatement = new Assign (fe, initializer, Location).ResolveStatement (ec);
5401                         return initializer;
5402                 }
5403
5404                 public bool HasDefaultInitializer
5405                 {
5406                         get
5407                         {
5408                                 Constant c = initializer as Constant;
5409                                 if (c == null)
5410                                         return false;
5411
5412                                 return c.IsDefaultInitializer (MemberType);
5413                         }
5414                 }
5415
5416                 public override string[] ValidAttributeTargets 
5417                 {
5418                         get {
5419                                 return attribute_targets;
5420                         }
5421                 }
5422
5423                 protected override bool VerifyClsCompliance ()
5424                 {
5425                         if (!base.VerifyClsCompliance ())
5426                                 return false;
5427
5428                         if (!IsFieldClsCompliant) {
5429                                 Report.Error (3003, Location, "Type of `{0}' is not CLS-compliant", GetSignatureForError ());
5430                         }
5431                         return true;
5432                 }
5433
5434
5435                 public void SetAssigned ()
5436                 {
5437                         caching_flags |= Flags.IsAssigned;
5438                 }
5439         }
5440
5441         public abstract class FieldMember : FieldBase
5442         {
5443                 protected FieldMember (DeclSpace parent, Expression type, int mod,
5444                         int allowed_mod, MemberName name, Attributes attrs)
5445                         : base (parent, type, mod, allowed_mod | Modifiers.ABSTRACT, name, attrs)
5446                 {
5447                         if ((mod & Modifiers.ABSTRACT) != 0)
5448                                 Report.Error (681, Location, "The modifier 'abstract' is not valid on fields. Try using a property instead");
5449                 }
5450
5451                 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
5452                 {
5453                         if (a.Type == TypeManager.field_offset_attribute_type)
5454                         {
5455                                 status |= Status.HAS_OFFSET;
5456
5457                                 if (!ParentContainer.HasExplicitLayout) {
5458                                         Report.Error (636, Location, "The FieldOffset attribute can only be placed on members of types marked with the StructLayout(LayoutKind.Explicit)");
5459                                         return;
5460                                 }
5461
5462                                 if ((ModFlags & Modifiers.STATIC) != 0 || this is Const) {
5463                                         Report.Error (637, Location, "The FieldOffset attribute is not allowed on static or const fields");
5464                                         return;
5465                                 }
5466                         }
5467
5468                         if (a.Type == TypeManager.fixed_buffer_attr_type) {
5469                                 Report.Error (1716, Location, "Do not use 'System.Runtime.CompilerServices.FixedBuffer' attribute. Use the 'fixed' field modifier instead");
5470                                 return;
5471                         }
5472
5473                         base.ApplyAttributeBuilder (a, cb);
5474                 }
5475
5476                 public override bool Define()
5477                 {
5478                         if (MemberType == null || Type == null)
5479                                 return false;
5480                         
5481                         if (MemberType == TypeManager.void_type) {
5482                                 Report.Error (1547, Location, "Keyword 'void' cannot be used in this context");
5483                                 return false;
5484                         }
5485
5486                         if (!CheckBase ())
5487                                 return false;
5488                         
5489                         if (!Parent.AsAccessible (MemberType, ModFlags)) {
5490                                 Report.Error (52, Location,
5491                                         "Inconsistent accessibility: field type `" +
5492                                         TypeManager.CSharpName (MemberType) + "' is less " +
5493                                         "accessible than field `" + GetSignatureForError () + "'");
5494                                 return false;
5495                         }
5496
5497                         if (!IsTypePermitted ())
5498                                 return false;
5499
5500                         return true;
5501                 }
5502
5503                 public override void Emit ()
5504                 {
5505                         if (OptAttributes != null) {
5506                                 OptAttributes.Emit ();
5507                         }
5508
5509                         if (((status & Status.HAS_OFFSET) == 0) && (ModFlags & Modifiers.STATIC) == 0 && ParentContainer.HasExplicitLayout) {
5510                                 Report.Error (625, Location, "`{0}': Instance field types marked with StructLayout(LayoutKind.Explicit) must have a FieldOffset attribute.", GetSignatureForError ());
5511                         }
5512
5513                         base.Emit ();
5514                 }
5515
5516                 //
5517                 //   Represents header string for documentation comment.
5518                 //
5519                 public override string DocCommentHeader {
5520                         get { return "F:"; }
5521                 }
5522         }
5523
5524         interface IFixedBuffer
5525         {
5526                 FieldInfo Element { get; }
5527                 Type ElementType { get; }
5528         }
5529
5530         public class FixedFieldExternal: IFixedBuffer
5531         {
5532                 FieldInfo element_field;
5533
5534                 public FixedFieldExternal (FieldInfo fi)
5535                 {
5536                         element_field = fi.FieldType.GetField (FixedField.FixedElementName);
5537                 }
5538
5539                 #region IFixedField Members
5540
5541                 public FieldInfo Element {
5542                         get {
5543                                 return element_field;
5544                         }
5545                 }
5546
5547                 public Type ElementType {
5548                         get {
5549                                 return element_field.FieldType;
5550                         }
5551                 }
5552
5553                 #endregion
5554         }
5555
5556         /// <summary>
5557         /// Fixed buffer implementation
5558         /// </summary>
5559         public class FixedField : FieldMember, IFixedBuffer
5560         {
5561                 public const string FixedElementName = "FixedElementField";
5562                 static int GlobalCounter = 0;
5563                 static object[] ctor_args = new object[] { (short)LayoutKind.Sequential };
5564                 static FieldInfo[] fi;
5565
5566                 TypeBuilder fixed_buffer_type;
5567                 FieldBuilder element;
5568                 Expression size_expr;
5569                 int buffer_size;
5570
5571                 const int AllowedModifiers =
5572                         Modifiers.NEW |
5573                         Modifiers.PUBLIC |
5574                         Modifiers.PROTECTED |
5575                         Modifiers.INTERNAL |
5576                         Modifiers.PRIVATE;
5577
5578                 public FixedField (DeclSpace parent, Expression type, int mod, string name,
5579                         Expression size_expr, Attributes attrs, Location loc):
5580                         base (parent, type, mod, AllowedModifiers, new MemberName (name, loc), attrs)
5581                 {
5582                         if (RootContext.Version == LanguageVersion.ISO_1)
5583                                 Report.FeatureIsNotStandardized (loc, "fixed size buffers");
5584
5585                         this.size_expr = size_expr;
5586                 }
5587
5588                 public override bool Define()
5589                 {
5590 #if !NET_2_0
5591                         if ((ModFlags & (Modifiers.PUBLIC | Modifiers.PROTECTED)) != 0)
5592                                 Report.Warning (-23, 1, Location, "Only private or internal fixed sized buffers are supported by .NET 1.x");
5593 #endif
5594
5595                         if (ParentContainer.Kind != Kind.Struct) {
5596                                 Report.Error (1642, Location, "`{0}': Fixed size buffer fields may only be members of structs",
5597                                         GetSignatureForError ());
5598                                 return false;
5599                         }
5600
5601                         if (!base.Define ())
5602                                 return false;
5603
5604                         if (!TypeManager.IsPrimitiveType (MemberType)) {
5605                                 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",
5606                                         GetSignatureForError ());
5607                                 return false;
5608                         }
5609
5610                         EmitContext ec = new EmitContext (this, Parent, Location, null, null, ModFlags);
5611                         Constant c = size_expr.ResolveAsConstant (ec, this);
5612                         if (c == null)
5613                                 return false;
5614
5615                         IntConstant buffer_size_const = c.ToInt (Location);
5616                         if (buffer_size_const == null)
5617                                 return false;
5618
5619                         buffer_size = buffer_size_const.Value;
5620
5621                         if (buffer_size <= 0) {
5622                                 Report.Error (1665, Location, "`{0}': Fixed size buffers must have a length greater than zero", GetSignatureForError ());
5623                                 return false;
5624                         }
5625
5626                         int type_size = Expression.GetTypeSize (MemberType);
5627
5628                         if (buffer_size > int.MaxValue / type_size) {
5629                                 Report.Error (1664, Location, "Fixed size buffer `{0}' of length `{1}' and type `{2}' exceeded 2^31 limit",
5630                                         GetSignatureForError (), buffer_size.ToString (), TypeManager.CSharpName (MemberType));
5631                                 return false;
5632                         }
5633
5634                         buffer_size *= type_size;
5635
5636                         // Define nested
5637                         string name = String.Format ("<{0}>__FixedBuffer{1}", Name, GlobalCounter++);
5638
5639                         fixed_buffer_type = Parent.TypeBuilder.DefineNestedType (name,
5640                                 TypeAttributes.NestedPublic | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit, TypeManager.value_type);
5641                         element = fixed_buffer_type.DefineField (FixedElementName, MemberType, FieldAttributes.Public);
5642                         RootContext.RegisterCompilerGeneratedType (fixed_buffer_type);
5643
5644                         FieldBuilder = Parent.TypeBuilder.DefineField (Name, fixed_buffer_type, Modifiers.FieldAttr (ModFlags));
5645                         TypeManager.RegisterFieldBase (FieldBuilder, this);
5646
5647                         return true;
5648                 }
5649
5650                 public override void Emit()
5651                 {
5652                         if (fi == null)
5653                                 fi = new FieldInfo [] { TypeManager.struct_layout_attribute_type.GetField ("Size") };
5654
5655                         object[] fi_val = new object[1];
5656                         fi_val [0] = buffer_size;
5657
5658                         CustomAttributeBuilder cab = new CustomAttributeBuilder (TypeManager.struct_layout_attribute_ctor, 
5659                                 ctor_args, fi, fi_val);
5660                         fixed_buffer_type.SetCustomAttribute (cab);
5661
5662                         cab = new CustomAttributeBuilder (TypeManager.fixed_buffer_attr_ctor, new object[] { MemberType, buffer_size } );
5663                         FieldBuilder.SetCustomAttribute (cab);
5664                         base.Emit ();
5665                 }
5666
5667                 protected override bool IsFieldClsCompliant {
5668                         get {
5669                                 return false;
5670                         }
5671                 }
5672
5673                 #region IFixedField Members
5674
5675                 public FieldInfo Element {
5676                         get {
5677                                 return element;
5678                         }
5679                 }
5680
5681                 public Type ElementType {
5682                         get {
5683                                 return MemberType;
5684                         }
5685                 }
5686
5687                 #endregion
5688         }
5689
5690         //
5691         // The Field class is used to represents class/struct fields during parsing.
5692         //
5693         public class Field : FieldMember {
5694                 // <summary>
5695                 //   Modifiers allowed in a class declaration
5696                 // </summary>
5697                 const int AllowedModifiers =
5698                         Modifiers.NEW |
5699                         Modifiers.PUBLIC |
5700                         Modifiers.PROTECTED |
5701                         Modifiers.INTERNAL |
5702                         Modifiers.PRIVATE |
5703                         Modifiers.STATIC |
5704                         Modifiers.VOLATILE |
5705                         Modifiers.UNSAFE |
5706                         Modifiers.READONLY;
5707
5708                 public Field (DeclSpace parent, Expression type, int mod, string name,
5709                               Attributes attrs, Location loc)
5710                         : base (parent, type, mod, AllowedModifiers, new MemberName (name, loc),
5711                                 attrs)
5712                 {
5713                 }
5714
5715                 public override bool Define ()
5716                 {
5717                         if (!base.Define ())
5718                                 return false;
5719
5720                         if (RootContext.WarningLevel > 1){
5721                                 Type ptype = Parent.TypeBuilder.BaseType;
5722
5723                                 // ptype is only null for System.Object while compiling corlib.
5724                                 if (ptype != null){
5725                                         TypeContainer.FindMembers (
5726                                                 ptype, MemberTypes.Method,
5727                                                 BindingFlags.Public |
5728                                                 BindingFlags.Static | BindingFlags.Instance,
5729                                                 System.Type.FilterName, Name);
5730                                 }
5731                         }
5732
5733                         if ((ModFlags & Modifiers.VOLATILE) != 0){
5734                                 if (!MemberType.IsClass){
5735                                         Type vt = MemberType;
5736                                         
5737                                         if (TypeManager.IsEnumType (vt))
5738                                                 vt = TypeManager.EnumToUnderlying (MemberType);
5739
5740                                         if (!((vt == TypeManager.bool_type) ||
5741                                               (vt == TypeManager.sbyte_type) ||
5742                                               (vt == TypeManager.byte_type) ||
5743                                               (vt == TypeManager.short_type) ||
5744                                               (vt == TypeManager.ushort_type) ||
5745                                               (vt == TypeManager.int32_type) ||
5746                                               (vt == TypeManager.uint32_type) ||    
5747                                               (vt == TypeManager.char_type) ||
5748                                               (vt == TypeManager.float_type) ||
5749                                               (!vt.IsValueType))){
5750                                                 Report.Error (677, Location, "`{0}': A volatile field cannot be of the type `{1}'",
5751                                                         GetSignatureForError (), TypeManager.CSharpName (vt));
5752                                                 return false;
5753                                         }
5754                                 }
5755
5756                                 if ((ModFlags & Modifiers.READONLY) != 0){
5757                                         Report.Error (678, Location, "`{0}': A field cannot be both volatile and readonly",
5758                                                 GetSignatureForError ());
5759                                         return false;
5760                                 }
5761                         }
5762
5763                         FieldAttributes fa = Modifiers.FieldAttr (ModFlags);
5764
5765                         if (ParentContainer.Kind == Kind.Struct && 
5766                             ((fa & FieldAttributes.Static) == 0) &&
5767                             MemberType == Parent.TypeBuilder &&
5768                             !TypeManager.IsBuiltinType (MemberType)){
5769                                 Report.Error (523, Location, "Struct member `" + Parent.Name + "." + Name + 
5770                                               "' causes a cycle in the structure layout");
5771                                 return false;
5772                         }
5773
5774                         try {
5775                                 FieldBuilder = Parent.TypeBuilder.DefineField (
5776                                         Name, MemberType, Modifiers.FieldAttr (ModFlags));
5777
5778                         TypeManager.RegisterFieldBase (FieldBuilder, this);
5779                         }
5780                         catch (ArgumentException) {
5781                                 Report.Warning (-24, 1, Location, "The Microsoft runtime is unable to use [void|void*] as a field type, try using the Mono runtime.");
5782                                 return false;
5783                         }
5784
5785                         return true;
5786                 }
5787
5788                 protected override bool VerifyClsCompliance ()
5789                 {
5790                         if (!base.VerifyClsCompliance ())
5791                                 return false;
5792
5793                         if ((ModFlags & Modifiers.VOLATILE) != 0) {
5794                                 Report.Warning (3026, 1, Location, "CLS-compliant field `{0}' cannot be volatile", GetSignatureForError ());
5795                         }
5796
5797                         return true;
5798                 }
5799         }
5800
5801         //
5802         // `set' and `get' accessors are represented with an Accessor.
5803         // 
5804         public class Accessor : IIteratorContainer {
5805                 //
5806                 // Null if the accessor is empty, or a Block if not
5807                 //
5808                 public const int AllowedModifiers = 
5809                         Modifiers.PUBLIC |
5810                         Modifiers.PROTECTED |
5811                         Modifiers.INTERNAL |
5812                         Modifiers.PRIVATE;
5813                 
5814                 public ToplevelBlock Block;
5815                 public Attributes Attributes;
5816                 public Location Location;
5817                 public int ModFlags;
5818                 public bool Yields;
5819                 
5820                 public Accessor (ToplevelBlock b, int mod, Attributes attrs, Location loc)
5821                 {
5822                         Block = b;
5823                         Attributes = attrs;
5824                         Location = loc;
5825                         ModFlags = Modifiers.Check (AllowedModifiers, mod, 0, loc);
5826                 }
5827
5828                 public void SetYields ()
5829                 {
5830                         Yields = true;
5831                 }
5832         }
5833
5834         // Ooouh Martin, templates are missing here.
5835         // When it will be possible move here a lot of child code and template method type.
5836         public abstract class AbstractPropertyEventMethod : MemberCore, IMethodData {
5837                 protected MethodData method_data;
5838                 protected ToplevelBlock block;
5839                 protected ListDictionary declarative_security;
5840
5841                 // The accessor are created event if they are not wanted.
5842                 // But we need them because their names are reserved.
5843                 // Field says whether accessor will be emited or not
5844                 public readonly bool IsDummy;
5845
5846                 protected readonly string prefix;
5847
5848                 ReturnParameter return_attributes;
5849
5850                 public AbstractPropertyEventMethod (MemberBase member, string prefix)
5851                         : base (member.Parent, SetupName (prefix, member, member.Location), null)
5852                 {
5853                         this.prefix = prefix;
5854                         IsDummy = true;
5855                 }
5856
5857                 public AbstractPropertyEventMethod (MemberBase member, Accessor accessor,
5858                                                     string prefix)
5859                         : base (member.Parent, SetupName (prefix, member, accessor.Location),
5860                                 accessor.Attributes)
5861                 {
5862                         this.prefix = prefix;
5863                         this.block = accessor.Block;
5864                 }
5865
5866                 static MemberName SetupName (string prefix, MemberBase member, Location loc)
5867                 {
5868                         return new MemberName (member.MemberName.Left, prefix + member.ShortName, loc);
5869                 }
5870
5871                 public void UpdateName (MemberBase member)
5872                 {
5873                         SetMemberName (SetupName (prefix, member, Location));
5874                 }
5875
5876                 #region IMethodData Members
5877
5878                 public ToplevelBlock Block {
5879                         get {
5880                                 return block;
5881                         }
5882
5883                         set {
5884                                 block = value;
5885                         }
5886                 }
5887
5888                 public CallingConventions CallingConventions {
5889                         get {
5890                                 return CallingConventions.Standard;
5891                         }
5892                 }
5893
5894                 public bool IsExcluded ()
5895                 {
5896                         return false;
5897                 }
5898
5899                 GenericMethod IMethodData.GenericMethod {
5900                         get {
5901                                 return null;
5902                         }
5903                 }
5904
5905                 public MemberName MethodName {
5906                         get {
5907                                 return MemberName;
5908                         }
5909                 }
5910
5911                 public Type[] ParameterTypes { 
5912                         get {
5913                                 return ParameterInfo.Types;
5914                         }
5915                 }
5916
5917                 public abstract Parameters ParameterInfo { get ; }
5918                 public abstract Type ReturnType { get; }
5919                 public abstract EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig);
5920
5921                 #endregion
5922
5923                 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
5924                 {
5925                         if (a.Type == TypeManager.cls_compliant_attribute_type || a.Type == TypeManager.obsolete_attribute_type ||
5926                                         a.Type == TypeManager.conditional_attribute_type) {
5927                                 Report.Error (1667, a.Location,
5928                                         "Attribute `{0}' is not valid on property or event accessors. It is valid on `{1}' declarations only",
5929                                         TypeManager.CSharpName (a.Type), a.GetValidTargets ());
5930                                 return;
5931                         }
5932
5933                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
5934                                 if (declarative_security == null)
5935                                         declarative_security = new ListDictionary ();
5936                                 a.ExtractSecurityPermissionSet (declarative_security);
5937                                 return;
5938                         }
5939
5940                         if (a.Target == AttributeTargets.Method) {
5941                                 method_data.MethodBuilder.SetCustomAttribute (cb);
5942                                 return;
5943                         }
5944
5945                         if (a.Target == AttributeTargets.ReturnValue) {
5946                                 if (return_attributes == null)
5947                                         return_attributes = new ReturnParameter (method_data.MethodBuilder, Location);
5948
5949                                 return_attributes.ApplyAttributeBuilder (a, cb);
5950                                 return;
5951                         }
5952
5953                         ApplyToExtraTarget (a, cb);
5954                 }
5955
5956                 virtual protected void ApplyToExtraTarget (Attribute a, CustomAttributeBuilder cb)
5957                 {
5958                         System.Diagnostics.Debug.Fail ("You forgot to define special attribute target handling");
5959                 }
5960
5961                 public override bool Define()
5962                 {
5963                         throw new NotSupportedException ();
5964                 }
5965
5966                 public void Emit (DeclSpace parent)
5967                 {
5968                         EmitMethod (parent);
5969
5970                         if (OptAttributes != null)
5971                                 OptAttributes.Emit ();
5972
5973                         if (declarative_security != null) {
5974                                 foreach (DictionaryEntry de in declarative_security) {
5975                                         method_data.MethodBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
5976                                 }
5977                         }
5978
5979                         block = null;
5980                 }
5981
5982                 protected virtual void EmitMethod (DeclSpace parent)
5983                 {
5984                         method_data.Emit (parent);
5985                 }
5986
5987                 public override bool IsClsComplianceRequired()
5988                 {
5989                         return false;
5990                 }
5991
5992                 public bool IsDuplicateImplementation (MethodCore method)
5993                 {
5994                         if (!MemberName.Equals (method.MemberName))
5995                                 return false;
5996
5997                         Type[] param_types = method.ParameterTypes;
5998
5999                         if (param_types.Length != ParameterTypes.Length)
6000                                 return false;
6001
6002                         for (int i = 0; i < param_types.Length; i++)
6003                                 if (param_types [i] != ParameterTypes [i])
6004                                         return false;
6005
6006                         Report.SymbolRelatedToPreviousError (method);
6007                         Report.Error (111, Location, TypeContainer.Error111, method.GetSignatureForError ());
6008                         return true;
6009                 }
6010
6011                 public override bool IsUsed
6012                 {
6013                         get {
6014                                 if (IsDummy)
6015                                         return false;
6016
6017                                 return base.IsUsed;
6018                         }
6019                 }
6020
6021                 public new Location Location { 
6022                         get {
6023                                 return base.Location;
6024                         }
6025                 }
6026
6027                 //
6028                 //   Represents header string for documentation comment.
6029                 //
6030                 public override string DocCommentHeader {
6031                         get { throw new InvalidOperationException ("Unexpected attempt to get doc comment from " + this.GetType () + "."); }
6032                 }
6033
6034         }
6035
6036         //
6037         // Properties and Indexers both generate PropertyBuilders, we use this to share 
6038         // their common bits.
6039         //
6040         abstract public class PropertyBase : MethodCore {
6041
6042                 public class GetMethod : PropertyMethod
6043                 {
6044                         static string[] attribute_targets = new string [] { "method", "return" };
6045
6046                         public GetMethod (MethodCore method):
6047                                 base (method, "get_")
6048                         {
6049                         }
6050
6051                         public GetMethod (MethodCore method, Accessor accessor):
6052                                 base (method, accessor, "get_")
6053                         {
6054                         }
6055
6056                         public override MethodBuilder Define (DeclSpace parent)
6057                         {
6058                                 base.Define (parent);
6059                                 
6060                                 method_data = new MethodData (method, ModFlags, flags, this);
6061
6062                                 if (!method_data.Define (parent))
6063                                         return null;
6064
6065                                 return method_data.MethodBuilder;
6066                         }
6067
6068                         public override Type ReturnType {
6069                                 get {
6070                                         return method.MemberType;
6071                                 }
6072                         }
6073
6074                         public override Parameters ParameterInfo {
6075                                 get {
6076                                         return Parameters.EmptyReadOnlyParameters;
6077                                 }
6078                         }
6079
6080                         public override string[] ValidAttributeTargets {
6081                                 get {
6082                                         return attribute_targets;
6083                                 }
6084                         }
6085                 }
6086
6087                 public class SetMethod : PropertyMethod {
6088
6089                         static string[] attribute_targets = new string [] { "method", "param", "return" };
6090                         ImplicitParameter param_attr;
6091                         protected Parameters parameters;
6092
6093                         public SetMethod (MethodCore method):
6094                                 base (method, "set_")
6095                         {
6096                         }
6097
6098                         public SetMethod (MethodCore method, Accessor accessor):
6099                                 base (method, accessor, "set_")
6100                         {
6101                         }
6102
6103                         protected override void ApplyToExtraTarget(Attribute a, CustomAttributeBuilder cb)
6104                         {
6105                                 if (a.Target == AttributeTargets.Parameter) {
6106                                         if (param_attr == null)
6107                                                 param_attr = new ImplicitParameter (method_data.MethodBuilder);
6108
6109                                         param_attr.ApplyAttributeBuilder (a, cb);
6110                                         return;
6111                                 }
6112
6113                                 base.ApplyAttributeBuilder (a, cb);
6114                         }
6115
6116                         public override Parameters ParameterInfo {
6117                                 get {
6118                                         return parameters;
6119                                 }
6120                         }
6121
6122                         protected virtual void DefineParameters ()
6123                         {
6124                                 parameters = new Parameters (
6125                                         new Parameter[] { new Parameter (method.MemberType, "value", Parameter.Modifier.NONE, null, Location) },
6126                                         new Type[] { method.MemberType });
6127                         }
6128
6129                         public override MethodBuilder Define (DeclSpace parent)
6130                         {
6131                                 DefineParameters ();
6132                                 if (IsDummy)
6133                                         return null;
6134
6135                                 base.Define (parent);
6136
6137                                 method_data = new MethodData (method, ModFlags, flags, this);
6138
6139                                 if (!method_data.Define (parent))
6140                                         return null;
6141
6142                                 return method_data.MethodBuilder;
6143                         }
6144
6145                         public override Type ReturnType {
6146                                 get {
6147                                         return TypeManager.void_type;
6148                                 }
6149                         }
6150
6151                         public override string[] ValidAttributeTargets {
6152                                 get {
6153                                         return attribute_targets;
6154                                 }
6155                         }
6156                 }
6157
6158                 static string[] attribute_targets = new string [] { "property" };
6159
6160                 public abstract class PropertyMethod : AbstractPropertyEventMethod
6161                 {
6162                         protected readonly MethodCore method;
6163                         protected MethodAttributes flags;
6164                         bool yields;
6165
6166                         public PropertyMethod (MethodCore method, string prefix)
6167                                 : base (method, prefix)
6168                         {
6169                                 this.method = method;
6170                         }
6171
6172                         public PropertyMethod (MethodCore method, Accessor accessor,
6173                                                string prefix)
6174                                 : base (method, accessor, prefix)
6175                         {
6176                                 this.method = method;
6177                                 this.ModFlags = accessor.ModFlags;
6178                                 yields = accessor.Yields;
6179
6180                                 if (accessor.ModFlags != 0 && RootContext.Version == LanguageVersion.ISO_1) {
6181                                         Report.FeatureIsNotStandardized (Location, "access modifiers on properties");
6182                                 }
6183                         }
6184
6185                         public override AttributeTargets AttributeTargets {
6186                                 get {
6187                                         return AttributeTargets.Method;
6188                                 }
6189                         }
6190
6191                         public override bool IsClsComplianceRequired ()
6192                         {
6193                                 return method.IsClsComplianceRequired ();
6194                         }
6195
6196                         public virtual MethodBuilder Define (DeclSpace parent)
6197                         {
6198                                 if (!method.CheckAbstractAndExtern (block != null))
6199                                         return null;
6200
6201                                 TypeContainer container = ((TypeContainer) parent).PartialContainer;
6202
6203                                 //
6204                                 // Check for custom access modifier
6205                                 //
6206                                 if (ModFlags == 0) {
6207                                         ModFlags = method.ModFlags;
6208                                         flags = method.flags;
6209                                 } else {
6210                                         if (container.Kind == Kind.Interface)
6211                                                 Report.Error (275, Location, "`{0}': accessibility modifiers may not be used on accessors in an interface",
6212                                                         GetSignatureForError ());
6213
6214                                         if ((method.ModFlags & Modifiers.ABSTRACT) != 0 && (ModFlags & Modifiers.PRIVATE) != 0) {
6215                                                 Report.Error (442, Location, "`{0}': abstract properties cannot have private accessors", GetSignatureForError ());
6216                                         }
6217
6218                                         CheckModifiers (ModFlags);
6219                                         ModFlags |= (method.ModFlags & (~Modifiers.Accessibility));
6220                                         ModFlags |= Modifiers.PROPERTY_CUSTOM;
6221                                         flags = Modifiers.MethodAttr (ModFlags);
6222                                         flags |= (method.flags & (~MethodAttributes.MemberAccessMask));
6223                                 }
6224
6225                                 //
6226                                 // Setup iterator if we are one
6227                                 //
6228                                 if (yields) {
6229                                         Iterator iterator = new Iterator (this, Parent as TypeContainer, null, ModFlags);
6230                                         
6231                                         if (!iterator.DefineIterator ())
6232                                                 return null;
6233                                 }
6234
6235                                 return null;
6236                         }
6237
6238                         public bool HasCustomAccessModifier
6239                         {
6240                                 get {
6241                                         return (ModFlags & Modifiers.PROPERTY_CUSTOM) != 0;
6242                                 }
6243                         }
6244
6245                         public override EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig)
6246                         {
6247                                 return new EmitContext (method,
6248                                         ds, method.ds, method.Location, ig, ReturnType,
6249                                         method.ModFlags, false);
6250                         }
6251
6252                         public override ObsoleteAttribute GetObsoleteAttribute ()
6253                         {
6254                                 return method.GetObsoleteAttribute ();
6255                         }
6256
6257                         public override string GetSignatureForError()
6258                         {
6259                                 return method.GetSignatureForError () + '.' + prefix.Substring (0, 3);
6260                         }
6261
6262                         void CheckModifiers (int modflags)
6263                         {
6264                                 int flags = 0;
6265                                 int mflags = method.ModFlags & Modifiers.Accessibility;
6266
6267                                 if ((mflags & Modifiers.PUBLIC) != 0) {
6268                                         flags |= Modifiers.PROTECTED | Modifiers.INTERNAL | Modifiers.PRIVATE;
6269                                 }
6270                                 else if ((mflags & Modifiers.PROTECTED) != 0) {
6271                                         if ((mflags & Modifiers.INTERNAL) != 0)
6272                                                 flags |= Modifiers.PROTECTED | Modifiers.INTERNAL;
6273
6274                                         flags |= Modifiers.PRIVATE;
6275                                 }
6276                                 else if ((mflags & Modifiers.INTERNAL) != 0)
6277                                         flags |= Modifiers.PRIVATE;
6278
6279                                 if ((mflags == modflags) || (modflags & (~flags)) != 0) {
6280                                         Report.Error (273, Location,
6281                                                 "The accessibility modifier of the `{0}' accessor must be more restrictive than the modifier of the property or indexer `{1}'",
6282                                                 GetSignatureForError (), method.GetSignatureForError ());
6283                                 }
6284                         }
6285
6286                         public override bool MarkForDuplicationCheck ()
6287                         {
6288                                 caching_flags |= Flags.TestMethodDuplication;
6289                                 return true;
6290                         }
6291                 }
6292
6293                 public PropertyMethod Get, Set;
6294                 public PropertyBuilder PropertyBuilder;
6295                 public MethodBuilder GetBuilder, SetBuilder;
6296
6297                 protected EmitContext ec;
6298
6299                 public PropertyBase (DeclSpace parent, Expression type, int mod_flags,
6300                                      int allowed_mod, bool is_iface, MemberName name,
6301                                      Parameters parameters, Attributes attrs)
6302                         : base (parent, null, type, mod_flags, allowed_mod, is_iface, name,
6303                                 attrs, parameters)
6304                 {
6305                 }
6306
6307                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
6308                 {
6309                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
6310                                 a.Error_InvalidSecurityParent ();
6311                                 return;
6312                         }
6313
6314                         PropertyBuilder.SetCustomAttribute (cb);
6315                 }
6316
6317                 public override AttributeTargets AttributeTargets {
6318                         get {
6319                                 return AttributeTargets.Property;
6320                         }
6321                 }
6322
6323                 public override bool Define ()
6324                 {
6325                         if (!DoDefine ())
6326                                 return false;
6327
6328                         if (!IsTypePermitted ())
6329                                 return false;
6330
6331                         return true;
6332                 }
6333
6334                 protected override bool DoDefine ()
6335                 {
6336                         if (!base.DoDefine ())
6337                                 return false;
6338
6339                         //
6340                         // Accessors modifiers check
6341                         //
6342                         if (Get.ModFlags != 0 && Set.ModFlags != 0) {
6343                                 Report.Error (274, Location, "`{0}': Cannot specify accessibility modifiers for both accessors of the property or indexer",
6344                                                 GetSignatureForError ());
6345                                 return false;
6346                         }
6347
6348                         if ((Get.IsDummy || Set.IsDummy)
6349                                         && (Get.ModFlags != 0 || Set.ModFlags != 0) && (ModFlags & Modifiers.OVERRIDE) == 0) {
6350                                 Report.Error (276, Location, 
6351                                         "`{0}': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor",
6352                                         GetSignatureForError ());
6353                                 return false;
6354                         }
6355
6356                         if (MemberType.IsAbstract && MemberType.IsSealed) {
6357                                 Report.Error (722, Location, Error722, TypeManager.CSharpName (MemberType));
6358                                 return false;
6359                         }
6360
6361                         ec = new EmitContext (this, Parent, Location, null, MemberType, ModFlags);
6362                         return true;
6363                 }
6364
6365                 protected override bool CheckForDuplications ()
6366                 {
6367                         ArrayList ar = ParentContainer.Indexers;
6368                         if (ar != null) {
6369                                 int arLen = ar.Count;
6370                                         
6371                                 for (int i = 0; i < arLen; i++) {
6372                                         Indexer m = (Indexer) ar [i];
6373                                         if (IsDuplicateImplementation (m))
6374                                                 return false;
6375                                 }
6376                         }
6377
6378                         ar = ParentContainer.Properties;
6379                         if (ar != null) {
6380                                 int arLen = ar.Count;
6381                                         
6382                                 for (int i = 0; i < arLen; i++) {
6383                                         Property m = (Property) ar [i];
6384                                         if (IsDuplicateImplementation (m))
6385                                                 return false;
6386                                 }
6387                         }
6388
6389                         return true;
6390                 }
6391
6392                 // TODO: rename to Resolve......
6393                 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
6394                 {
6395                         PropertyInfo base_property = ParentContainer.BaseCache.FindMemberToOverride (
6396                                 Parent.TypeBuilder, Name, ParameterTypes, null, true) as PropertyInfo;
6397
6398                         if (base_property == null)
6399                                 return null;
6400
6401                         base_ret_type = base_property.PropertyType;
6402                         MethodInfo get_accessor = base_property.GetGetMethod (true);
6403                         MethodInfo set_accessor = base_property.GetSetMethod (true);
6404                         MethodAttributes get_accessor_access, set_accessor_access;
6405
6406                         if ((ModFlags & Modifiers.OVERRIDE) != 0) {
6407                                 if (Get != null && !Get.IsDummy && get_accessor == null) {
6408                                         Report.SymbolRelatedToPreviousError (base_property);
6409                                         Report.Error (545, Location, "`{0}.get': cannot override because `{1}' does not have an overridable get accessor", GetSignatureForError (), TypeManager.GetFullNameSignature (base_property));
6410                                 }
6411
6412                                 if (Set != null && !Set.IsDummy && set_accessor == null) {
6413                                         Report.SymbolRelatedToPreviousError (base_property);
6414                                         Report.Error (546, Location, "`{0}.set': cannot override because `{1}' does not have an overridable set accessor", GetSignatureForError (), TypeManager.GetFullNameSignature (base_property));
6415                                 }
6416                         }
6417                         
6418                         //
6419                         // Check base class accessors access
6420                         //
6421
6422                         // TODO: rewrite to reuse Get|Set.CheckAccessModifiers and share code there
6423                         get_accessor_access = set_accessor_access = 0;
6424                         if ((ModFlags & Modifiers.NEW) == 0) {
6425                                 if (get_accessor != null) {
6426                                         MethodAttributes get_flags = Modifiers.MethodAttr (Get.ModFlags != 0 ? Get.ModFlags : ModFlags);
6427                                         get_accessor_access = (get_accessor.Attributes & MethodAttributes.MemberAccessMask);
6428
6429                                         if (!Get.IsDummy && !CheckAccessModifiers (get_flags & MethodAttributes.MemberAccessMask, get_accessor_access, get_accessor))
6430                                                 Error_CannotChangeAccessModifiers (get_accessor, get_accessor_access,  ".get");
6431                                 }
6432
6433                                 if (set_accessor != null)  {
6434                                         MethodAttributes set_flags = Modifiers.MethodAttr (Set.ModFlags != 0 ? Set.ModFlags : ModFlags);
6435                                         set_accessor_access = (set_accessor.Attributes & MethodAttributes.MemberAccessMask);
6436
6437                                         if (!Set.IsDummy && !CheckAccessModifiers (set_flags & MethodAttributes.MemberAccessMask, set_accessor_access, set_accessor))
6438                                                 Error_CannotChangeAccessModifiers (set_accessor, set_accessor_access, ".set");
6439                                 }
6440                         }
6441
6442                         //
6443                         // Get the less restrictive access
6444                         //
6445                         return get_accessor_access > set_accessor_access ? get_accessor : set_accessor;
6446                 }
6447
6448                 public override void Emit ()
6449                 {
6450                         //
6451                         // The PropertyBuilder can be null for explicit implementations, in that
6452                         // case, we do not actually emit the ".property", so there is nowhere to
6453                         // put the attribute
6454                         //
6455                         if (PropertyBuilder != null && OptAttributes != null)
6456                                 OptAttributes.Emit ();
6457
6458                         if (!Get.IsDummy)
6459                                 Get.Emit (Parent);
6460
6461                         if (!Set.IsDummy)
6462                                 Set.Emit (Parent);
6463
6464                         base.Emit ();
6465                 }
6466
6467                 /// <summary>
6468                 /// Tests whether accessors are not in collision with some method (CS0111)
6469                 /// </summary>
6470                 public bool AreAccessorsDuplicateImplementation (MethodCore mc)
6471                 {
6472                         return Get.IsDuplicateImplementation (mc) || Set.IsDuplicateImplementation (mc);
6473                 }
6474
6475                 public override bool IsUsed
6476                 {
6477                         get {
6478                                 if (IsExplicitImpl)
6479                                         return true;
6480
6481                                 return Get.IsUsed | Set.IsUsed;
6482                         }
6483                 }
6484
6485                 protected override void SetMemberName (MemberName new_name)
6486                 {
6487                         base.SetMemberName (new_name);
6488
6489                         Get.UpdateName (this);
6490                         Set.UpdateName (this);
6491                 }
6492
6493                 public override string[] ValidAttributeTargets {
6494                         get {
6495                                 return attribute_targets;
6496                         }
6497                 }
6498
6499                 //
6500                 //   Represents header string for documentation comment.
6501                 //
6502                 public override string DocCommentHeader {
6503                         get { return "P:"; }
6504                 }
6505         }
6506                         
6507         public class Property : PropertyBase {
6508                 const int AllowedModifiers =
6509                         Modifiers.NEW |
6510                         Modifiers.PUBLIC |
6511                         Modifiers.PROTECTED |
6512                         Modifiers.INTERNAL |
6513                         Modifiers.PRIVATE |
6514                         Modifiers.STATIC |
6515                         Modifiers.SEALED |
6516                         Modifiers.OVERRIDE |
6517                         Modifiers.ABSTRACT |
6518                         Modifiers.UNSAFE |
6519                         Modifiers.EXTERN |
6520                         Modifiers.METHOD_YIELDS |
6521                         Modifiers.VIRTUAL;
6522
6523                 const int AllowedInterfaceModifiers =
6524                         Modifiers.NEW;
6525
6526                 public Property (DeclSpace parent, Expression type, int mod, bool is_iface,
6527                                  MemberName name, Attributes attrs, Accessor get_block,
6528                                  Accessor set_block)
6529                         : base (parent, type, mod,
6530                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
6531                                 is_iface, name, Parameters.EmptyReadOnlyParameters, attrs)
6532                 {
6533                         if (get_block == null)
6534                                 Get = new GetMethod (this);
6535                         else
6536                                 Get = new GetMethod (this, get_block);
6537
6538                         if (set_block == null)
6539                                 Set = new SetMethod (this);
6540                         else
6541                                 Set = new SetMethod (this, set_block);
6542                 }
6543
6544                 public override bool Define ()
6545                 {
6546                         if (!DoDefineBase ())
6547                                 return false;
6548
6549                         if (!base.Define ())
6550                                 return false;
6551
6552                         if (!CheckBase ())
6553                                 return false;
6554
6555                         flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
6556
6557                         if (!Get.IsDummy) {
6558                                 GetBuilder = Get.Define (Parent);
6559                                 if (GetBuilder == null)
6560                                         return false;
6561                         }
6562
6563                         SetBuilder = Set.Define (Parent);
6564                         if (!Set.IsDummy) {
6565                                 if (SetBuilder == null)
6566                                         return false;
6567                         }
6568
6569                         // FIXME - PropertyAttributes.HasDefault ?
6570
6571                         PropertyBuilder = Parent.TypeBuilder.DefineProperty (
6572                                 MemberName.ToString (), PropertyAttributes.None, MemberType, null);
6573
6574                         if (!Get.IsDummy)
6575                                 PropertyBuilder.SetGetMethod (GetBuilder);
6576
6577                         if (!Set.IsDummy)
6578                                 PropertyBuilder.SetSetMethod (SetBuilder);
6579
6580                         TypeManager.RegisterProperty (PropertyBuilder, this);
6581                         return true;
6582                 }
6583         }
6584
6585         /// </summary>
6586         ///  Gigantic workaround  for lameness in SRE follows :
6587         ///  This class derives from EventInfo and attempts to basically
6588         ///  wrap around the EventBuilder so that FindMembers can quickly
6589         ///  return this in it search for members
6590         /// </summary>
6591         public class MyEventBuilder : EventInfo {
6592                 
6593                 //
6594                 // We use this to "point" to our Builder which is
6595                 // not really a MemberInfo
6596                 //
6597                 EventBuilder MyBuilder;
6598                 
6599                 //
6600                 // We "catch" and wrap these methods
6601                 //
6602                 MethodInfo raise, remove, add;
6603
6604                 EventAttributes attributes;
6605                 Type declaring_type, reflected_type, event_type;
6606                 string name;
6607
6608                 Event my_event;
6609
6610                 public MyEventBuilder (Event ev, TypeBuilder type_builder, string name, EventAttributes event_attr, Type event_type)
6611                 {
6612                         MyBuilder = type_builder.DefineEvent (name, event_attr, event_type);
6613
6614                         // And now store the values in our own fields.
6615                         
6616                         declaring_type = type_builder;
6617
6618                         reflected_type = type_builder;
6619                         
6620                         attributes = event_attr;
6621                         this.name = name;
6622                         my_event = ev;
6623                         this.event_type = event_type;
6624                 }
6625                 
6626                 //
6627                 // Methods that you have to override.  Note that you only need 
6628                 // to "implement" the variants that take the argument (those are
6629                 // the "abstract" methods, the others (GetAddMethod()) are 
6630                 // regular.
6631                 //
6632                 public override MethodInfo GetAddMethod (bool nonPublic)
6633                 {
6634                         return add;
6635                 }
6636                 
6637                 public override MethodInfo GetRemoveMethod (bool nonPublic)
6638                 {
6639                         return remove;
6640                 }
6641                 
6642                 public override MethodInfo GetRaiseMethod (bool nonPublic)
6643                 {
6644                         return raise;
6645                 }
6646                 
6647                 //
6648                 // These methods make "MyEventInfo" look like a Builder
6649                 //
6650                 public void SetRaiseMethod (MethodBuilder raiseMethod)
6651                 {
6652                         raise = raiseMethod;
6653                         MyBuilder.SetRaiseMethod (raiseMethod);
6654                 }
6655
6656                 public void SetRemoveOnMethod (MethodBuilder removeMethod)
6657                 {
6658                         remove = removeMethod;
6659                         MyBuilder.SetRemoveOnMethod (removeMethod);
6660                 }
6661
6662                 public void SetAddOnMethod (MethodBuilder addMethod)
6663                 {
6664                         add = addMethod;
6665                         MyBuilder.SetAddOnMethod (addMethod);
6666                 }
6667
6668                 public void SetCustomAttribute (CustomAttributeBuilder cb)
6669                 {
6670                         MyBuilder.SetCustomAttribute (cb);
6671                 }
6672                 
6673                 public override object [] GetCustomAttributes (bool inherit)
6674                 {
6675                         // FIXME : There's nothing which can be seemingly done here because
6676                         // we have no way of getting at the custom attribute objects of the
6677                         // EventBuilder !
6678                         return null;
6679                 }
6680
6681                 public override object [] GetCustomAttributes (Type t, bool inherit)
6682                 {
6683                         // FIXME : Same here !
6684                         return null;
6685                 }
6686
6687                 public override bool IsDefined (Type t, bool b)
6688                 {
6689                         return true;
6690                 }
6691
6692                 public override EventAttributes Attributes {
6693                         get {
6694                                 return attributes;
6695                         }
6696                 }
6697
6698                 public override string Name {
6699                         get {
6700                                 return name;
6701                         }
6702                 }
6703
6704                 public override Type DeclaringType {
6705                         get {
6706                                 return declaring_type;
6707                         }
6708                 }
6709
6710                 public override Type ReflectedType {
6711                         get {
6712                                 return reflected_type;
6713                         }
6714                 }
6715
6716                 public Type EventType {
6717                         get {
6718                                 return event_type;
6719                         }
6720                 }
6721                 
6722                 public void SetUsed ()
6723                 {
6724                         if (my_event != null) {
6725                                 my_event.SetAssigned ();
6726                                 my_event.SetMemberIsUsed ();
6727                         }
6728                 }
6729         }
6730         
6731         /// <summary>
6732         /// For case when event is declared like property (with add and remove accessors).
6733         /// </summary>
6734         public class EventProperty: Event {
6735
6736                 static string[] attribute_targets = new string [] { "event" }; // "property" target was disabled for 2.0 version
6737
6738                 public EventProperty (DeclSpace parent, Expression type, int mod_flags,
6739                                       bool is_iface, MemberName name,
6740                                       Attributes attrs, Accessor add, Accessor remove)
6741                         : base (parent, type, mod_flags, is_iface, name, attrs)
6742                 {
6743                         Add = new AddDelegateMethod (this, add);
6744                         Remove = new RemoveDelegateMethod (this, remove);
6745
6746                         // For this event syntax we don't report error CS0067
6747                         // because it is hard to do it.
6748                         SetAssigned ();
6749                 }
6750
6751                 public override string[] ValidAttributeTargets {
6752                         get {
6753                                 return attribute_targets;
6754                         }
6755                 }
6756         }
6757
6758         /// <summary>
6759         /// Event is declared like field.
6760         /// </summary>
6761         public class EventField : Event {
6762
6763                 static string[] attribute_targets = new string [] { "event", "field", "method" };
6764                 static string[] attribute_targets_interface = new string[] { "event", "method" };
6765
6766                 public EventField (DeclSpace parent, Expression type, int mod_flags,
6767                                    bool is_iface, MemberName name,
6768                                    Attributes attrs)
6769                         : base (parent, type, mod_flags, is_iface, name, attrs)
6770                 {
6771                         Add = new AddDelegateMethod (this);
6772                         Remove = new RemoveDelegateMethod (this);
6773                 }
6774
6775                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
6776                 {
6777                         if (a.Target == AttributeTargets.Field) {
6778                                 FieldBuilder.SetCustomAttribute (cb);
6779                                 return;
6780                         }
6781
6782                         if (a.Target == AttributeTargets.Method) {
6783                                 Add.ApplyAttributeBuilder (a, cb);
6784                                 Remove.ApplyAttributeBuilder (a, cb);
6785                                 return;
6786                         }
6787
6788                         base.ApplyAttributeBuilder (a, cb);
6789                 }
6790
6791                 public override bool Define()
6792                 {
6793                         if (!base.Define ())
6794                                 return false;
6795
6796                         if (initializer != null) {
6797                                 if (((ModFlags & Modifiers.ABSTRACT) != 0)) {
6798                                         Report.Error (74, Location, "`{0}': abstract event cannot have an initializer",
6799                                                 GetSignatureForError ());
6800                                         return false;
6801                                 }
6802                         }
6803
6804                         return true;
6805                 }
6806
6807                 public override string[] ValidAttributeTargets {
6808                         get {
6809                                 return IsInterface ? attribute_targets_interface : attribute_targets;
6810                         }
6811                 }
6812         }
6813
6814         public abstract class Event : FieldBase {
6815
6816                 protected sealed class AddDelegateMethod: DelegateMethod
6817                 {
6818
6819                         public AddDelegateMethod (Event method):
6820                                 base (method, "add_")
6821                         {
6822                         }
6823
6824                         public AddDelegateMethod (Event method, Accessor accessor):
6825                                 base (method, accessor, "add_")
6826                         {
6827                         }
6828
6829                         protected override MethodInfo DelegateMethodInfo {
6830                                 get {
6831                                         return TypeManager.delegate_combine_delegate_delegate;
6832                                 }
6833                         }
6834
6835                 }
6836
6837                 protected sealed class RemoveDelegateMethod: DelegateMethod
6838                 {
6839                         public RemoveDelegateMethod (Event method):
6840                                 base (method, "remove_")
6841                         {
6842                         }
6843
6844                         public RemoveDelegateMethod (Event method, Accessor accessor):
6845                                 base (method, accessor, "remove_")
6846                         {
6847                         }
6848
6849                         protected override MethodInfo DelegateMethodInfo {
6850                                 get {
6851                                         return TypeManager.delegate_remove_delegate_delegate;
6852                                 }
6853                         }
6854
6855                 }
6856
6857                 public abstract class DelegateMethod : AbstractPropertyEventMethod
6858                 {
6859                         protected readonly Event method;
6860                         ImplicitParameter param_attr;
6861
6862                         static string[] attribute_targets = new string [] { "method", "param", "return" };
6863
6864                         public DelegateMethod (Event method, string prefix)
6865                                 : base (method, prefix)
6866                         {
6867                                 this.method = method;
6868                         }
6869
6870                         public DelegateMethod (Event method, Accessor accessor, string prefix)
6871                                 : base (method, accessor, prefix)
6872                         {
6873                                 this.method = method;
6874                         }
6875
6876                         protected override void ApplyToExtraTarget(Attribute a, CustomAttributeBuilder cb)
6877                         {
6878                                 if (a.Target == AttributeTargets.Parameter) {
6879                                         if (param_attr == null)
6880                                                 param_attr = new ImplicitParameter (method_data.MethodBuilder);
6881
6882                                         param_attr.ApplyAttributeBuilder (a, cb);
6883                                         return;
6884                                 }
6885
6886                                 base.ApplyAttributeBuilder (a, cb);
6887                         }
6888
6889                         public override AttributeTargets AttributeTargets {
6890                                 get {
6891                                         return AttributeTargets.Method;
6892                                 }
6893                         }
6894
6895                         public override bool IsClsComplianceRequired ()
6896                         {
6897                                 return method.IsClsComplianceRequired ();
6898                         }
6899
6900                         public MethodBuilder Define (DeclSpace parent)
6901                         {
6902                                 method_data = new MethodData (method, method.ModFlags,
6903                                         method.flags | MethodAttributes.HideBySig | MethodAttributes.SpecialName, this);
6904
6905                                 if (!method_data.Define (parent))
6906                                         return null;
6907
6908                                 MethodBuilder mb = method_data.MethodBuilder;
6909                                 ParameterInfo.ApplyAttributes (mb);
6910                                 return mb;
6911                         }
6912
6913
6914                         protected override void EmitMethod (DeclSpace parent)
6915                         {
6916                                 if (block != null) {
6917                                         base.EmitMethod (parent);
6918                                         return;
6919                                 }
6920
6921                                 if ((method.ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
6922                                         return;
6923
6924                                 ILGenerator ig = method_data.MethodBuilder.GetILGenerator ();
6925                                 FieldInfo field_info = (FieldInfo)method.FieldBuilder;
6926
6927                                 method_data.MethodBuilder.SetImplementationFlags (MethodImplAttributes.Synchronized);
6928                                 if ((method.ModFlags & Modifiers.STATIC) != 0) {
6929                                         ig.Emit (OpCodes.Ldsfld, field_info);
6930                                         ig.Emit (OpCodes.Ldarg_0);
6931                                         ig.Emit (OpCodes.Call, DelegateMethodInfo);
6932                                         ig.Emit (OpCodes.Castclass, method.MemberType);
6933                                         ig.Emit (OpCodes.Stsfld, field_info);
6934                                 } else {
6935                                         ig.Emit (OpCodes.Ldarg_0);
6936                                         ig.Emit (OpCodes.Ldarg_0);
6937                                         ig.Emit (OpCodes.Ldfld, field_info);
6938                                         ig.Emit (OpCodes.Ldarg_1);
6939                                         ig.Emit (OpCodes.Call, DelegateMethodInfo);
6940                                         ig.Emit (OpCodes.Castclass, method.MemberType);
6941                                         ig.Emit (OpCodes.Stfld, field_info);
6942                                 }
6943                                 ig.Emit (OpCodes.Ret);
6944                         }
6945
6946                         protected abstract MethodInfo DelegateMethodInfo { get; }
6947
6948                         public override Type ReturnType {
6949                                 get {
6950                                         return TypeManager.void_type;
6951                                 }
6952                         }
6953
6954                         public override EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig)
6955                         {
6956                                 return new EmitContext (
6957                                         ds, method.Parent, Location, ig, ReturnType,
6958                                         method.ModFlags, false);
6959                         }
6960
6961                         public override ObsoleteAttribute GetObsoleteAttribute ()
6962                         {
6963                                 return method.GetObsoleteAttribute ();
6964                         }
6965
6966                         public override string[] ValidAttributeTargets {
6967                                 get {
6968                                         return attribute_targets;
6969                                 }
6970                         }
6971
6972                         public override Parameters ParameterInfo {
6973                                 get {
6974                                         return method.parameters;
6975                                 }
6976                         }
6977
6978                 }
6979
6980
6981                 const int AllowedModifiers =
6982                         Modifiers.NEW |
6983                         Modifiers.PUBLIC |
6984                         Modifiers.PROTECTED |
6985                         Modifiers.INTERNAL |
6986                         Modifiers.PRIVATE |
6987                         Modifiers.STATIC |
6988                         Modifiers.VIRTUAL |
6989                         Modifiers.SEALED |
6990                         Modifiers.OVERRIDE |
6991                         Modifiers.UNSAFE |
6992                         Modifiers.ABSTRACT;
6993
6994                 const int AllowedInterfaceModifiers =
6995                         Modifiers.NEW;
6996
6997                 public DelegateMethod Add, Remove;
6998                 public MyEventBuilder     EventBuilder;
6999                 public MethodBuilder AddBuilder, RemoveBuilder;
7000                 Parameters parameters;
7001
7002                 protected Event (DeclSpace parent, Expression type, int mod_flags,
7003                               bool is_iface, MemberName name, Attributes attrs)
7004                         : base (parent, type, mod_flags,
7005                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
7006                                 name, attrs)
7007                 {
7008                         IsInterface = is_iface;
7009                 }
7010
7011                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
7012                 {
7013                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
7014                                 a.Error_InvalidSecurityParent ();
7015                                 return;
7016                         }
7017                         
7018                         EventBuilder.SetCustomAttribute (cb);
7019                 }
7020
7021                 public bool AreAccessorsDuplicateImplementation (MethodCore mc)
7022                 {
7023                         return Add.IsDuplicateImplementation (mc) || Remove.IsDuplicateImplementation (mc);
7024                 }
7025
7026                 public override AttributeTargets AttributeTargets {
7027                         get {
7028                                 return AttributeTargets.Event;
7029                         }
7030                 }
7031   
7032                 public override bool Define ()
7033                 {
7034                         EventAttributes e_attr;
7035                         e_attr = EventAttributes.None;
7036
7037                         if (!DoDefineBase ())
7038                                 return false;
7039
7040                         if (!DoDefine ())
7041                                 return false;
7042
7043                         if (!TypeManager.IsDelegateType (MemberType)) {
7044                                 Report.Error (66, Location, "`{0}': event must be of a delegate type", GetSignatureForError ());
7045                                 return false;
7046                         }
7047
7048                         parameters = new Parameters (
7049                                 new Parameter[] { new Parameter (MemberType, "value", Parameter.Modifier.NONE, null, Location) },
7050                                 new Type[] { MemberType } );
7051
7052                         if (!CheckBase ())
7053                                 return false;
7054
7055                         //
7056                         // Now define the accessors
7057                         //
7058
7059                         AddBuilder = Add.Define (Parent);
7060                         if (AddBuilder == null)
7061                                 return false;
7062
7063                         RemoveBuilder = Remove.Define (Parent);
7064                         if (RemoveBuilder == null)
7065                                 return false;
7066
7067                         EventBuilder = new MyEventBuilder (this, Parent.TypeBuilder, Name, e_attr, MemberType);
7068                         
7069                         if (Add.Block == null && Remove.Block == null && !IsInterface) {
7070                                 FieldBuilder = Parent.TypeBuilder.DefineField (
7071                                         Name, MemberType,
7072                                         FieldAttributes.Private | ((ModFlags & Modifiers.STATIC) != 0 ? FieldAttributes.Static : 0));
7073                                 TypeManager.RegisterPrivateFieldOfEvent (
7074                                         (EventInfo) EventBuilder, FieldBuilder);
7075                                 TypeManager.RegisterFieldBase (FieldBuilder, this);
7076                         }
7077                         
7078                         EventBuilder.SetAddOnMethod (AddBuilder);
7079                         EventBuilder.SetRemoveOnMethod (RemoveBuilder);
7080
7081                         TypeManager.RegisterEvent (EventBuilder, AddBuilder, RemoveBuilder);
7082                         return true;
7083                 }
7084
7085                 protected override bool CheckBase ()
7086                 {
7087                         if (!base.CheckBase ())
7088                                 return false;
7089  
7090                         if (conflict_symbol != null && (ModFlags & Modifiers.NEW) == 0) {
7091                                 if (!(conflict_symbol is EventInfo)) {
7092                                         Report.SymbolRelatedToPreviousError (conflict_symbol);
7093                                         Report.Error (72, Location, "Event `{0}' can override only event", GetSignatureForError ());
7094                                         return false;
7095                                 }
7096                         }
7097  
7098                         return true;
7099                 }
7100
7101                 public override void Emit ()
7102                 {
7103                         if (OptAttributes != null) {
7104                                 OptAttributes.Emit ();
7105                         }
7106
7107                         Add.Emit (Parent);
7108                         Remove.Emit (Parent);
7109
7110                         base.Emit ();
7111                 }
7112
7113                 public override string GetSignatureForError ()
7114                 {
7115                         return base.GetSignatureForError ();
7116                 }
7117
7118                 //
7119                 //   Represents header string for documentation comment.
7120                 //
7121                 public override string DocCommentHeader {
7122                         get { return "E:"; }
7123                 }
7124         }
7125
7126  
7127         public class Indexer : PropertyBase, IIteratorContainer {
7128
7129                 class GetIndexerMethod : GetMethod
7130                 {
7131                         public GetIndexerMethod (MethodCore method):
7132                                 base (method)
7133                         {
7134                         }
7135
7136                         public GetIndexerMethod (MethodCore method, Accessor accessor):
7137                                 base (method, accessor)
7138                         {
7139                         }
7140
7141                         public override Parameters ParameterInfo {
7142                                 get {
7143                                         return method.ParameterInfo;
7144                                 }
7145                         }
7146                 }
7147
7148                 class SetIndexerMethod: SetMethod
7149                 {
7150                         public SetIndexerMethod (MethodCore method):
7151                                 base (method)
7152                         {
7153                         }
7154
7155                         public SetIndexerMethod (MethodCore method, Accessor accessor):
7156                                 base (method, accessor)
7157                         {
7158                         }
7159
7160                         protected override void DefineParameters ()
7161                         {
7162                                 parameters = Parameters.MergeGenerated (method.Parameters,
7163                                         new Parameter (method.MemberType, "value", Parameter.Modifier.NONE, null, method.Location));
7164                         }
7165                 }
7166
7167                 const int AllowedModifiers =
7168                         Modifiers.NEW |
7169                         Modifiers.PUBLIC |
7170                         Modifiers.PROTECTED |
7171                         Modifiers.INTERNAL |
7172                         Modifiers.PRIVATE |
7173                         Modifiers.VIRTUAL |
7174                         Modifiers.SEALED |
7175                         Modifiers.OVERRIDE |
7176                         Modifiers.UNSAFE |
7177                         Modifiers.EXTERN |
7178                         Modifiers.ABSTRACT;
7179
7180                 const int AllowedInterfaceModifiers =
7181                         Modifiers.NEW;
7182
7183                 //
7184                 // Are we implementing an interface ?
7185                 //
7186                 public Indexer (DeclSpace parent, Expression type, MemberName name, int mod,
7187                                 bool is_iface, Parameters parameters, Attributes attrs,
7188                                 Accessor get_block, Accessor set_block)
7189                         : base (parent, type, mod,
7190                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
7191                                 is_iface, name, parameters, attrs)
7192                 {
7193                         if (get_block == null)
7194                                 Get = new GetIndexerMethod (this);
7195                         else
7196                                 Get = new GetIndexerMethod (this, get_block);
7197
7198                         if (set_block == null)
7199                                 Set = new SetIndexerMethod (this);
7200                         else
7201                                 Set = new SetIndexerMethod (this, set_block);
7202                 }
7203                        
7204                 public override bool Define ()
7205                 {
7206                         if (!DoDefineBase ())
7207                                 return false;
7208
7209                         if (!base.Define ())
7210                                 return false;
7211
7212                         if (MemberType == TypeManager.void_type) {
7213                                 Report.Error (620, Location, "Indexers cannot have void type");
7214                                 return false;
7215                         }
7216
7217                         if (OptAttributes != null) {
7218                                 Attribute indexer_attr = OptAttributes.Search (TypeManager.indexer_name_type);
7219                                 if (indexer_attr != null) {
7220                                         // Remove the attribute from the list because it is not emitted
7221                                         OptAttributes.Attrs.Remove (indexer_attr);
7222
7223                                         string name = indexer_attr.GetIndexerAttributeValue ();
7224                                         if (name == null)
7225                                                 return false;
7226
7227                                         ShortName = name;
7228
7229                                         if (IsExplicitImpl) {
7230                                                 Report.Error (415, indexer_attr.Location,
7231                                                               "The `IndexerName' attribute is valid only on an " +
7232                                                               "indexer that is not an explicit interface member declaration");
7233                                                 return false;
7234                                         }
7235
7236                                         if ((ModFlags & Modifiers.OVERRIDE) != 0) {
7237                                                 Report.Error (609, indexer_attr.Location,
7238                                                               "Cannot set the `IndexerName' attribute on an indexer marked override");
7239                                                 return false;
7240                                         }
7241                                 }
7242                         }
7243
7244                         if (InterfaceType != null) {
7245                                 string base_IndexerName = TypeManager.IndexerPropertyName (InterfaceType);
7246                                 if (base_IndexerName != Name)
7247                                         ShortName = base_IndexerName;
7248                         }
7249
7250                         if (!ParentContainer.AddToMemberContainer (this) ||
7251                                 !ParentContainer.AddToMemberContainer (Get) || !ParentContainer.AddToMemberContainer (Set))
7252                                 return false;
7253
7254                         if (!CheckBase ())
7255                                 return false;
7256
7257                         flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
7258                         if (!Get.IsDummy){
7259                                 GetBuilder = Get.Define (Parent);
7260                                 if (GetBuilder == null)
7261                                         return false;
7262
7263                                 //
7264                                 // Setup iterator if we are one
7265                                 //
7266                                 if ((ModFlags & Modifiers.METHOD_YIELDS) != 0){
7267                                         Iterator iterator = new Iterator (
7268                                                 Get, Parent, null, ModFlags);
7269
7270                                         if (!iterator.DefineIterator ())
7271                                                 return false;
7272                                 }
7273                         }
7274                         
7275                         SetBuilder = Set.Define (Parent);
7276                         if (!Set.IsDummy){
7277                                 if (SetBuilder == null)
7278                                         return false;
7279                         }
7280
7281                         //
7282                         // Now name the parameters
7283                         //
7284                         Parameter [] p = Parameters.FixedParameters;
7285                         if (p != null) {
7286                                 // TODO: should be done in parser and it needs to do cycle
7287                                 if ((p [0].ModFlags & Parameter.Modifier.ISBYREF) != 0) {
7288                                         Report.Error (631, Location, "ref and out are not valid in this context");
7289                                         return false;
7290                                 }
7291                         }
7292
7293                         PropertyBuilder = Parent.TypeBuilder.DefineProperty (
7294                                 Name, PropertyAttributes.None, MemberType, ParameterTypes);
7295                         
7296                         if (!Get.IsDummy)
7297                                 PropertyBuilder.SetGetMethod (GetBuilder);
7298
7299                         if (!Set.IsDummy)
7300                                 PropertyBuilder.SetSetMethod (SetBuilder);
7301                                 
7302                         TypeManager.RegisterIndexer (PropertyBuilder, GetBuilder, SetBuilder, ParameterTypes);
7303
7304                         return true;
7305                 }
7306
7307                 public override string GetSignatureForError ()
7308                 {
7309                         StringBuilder sb = new StringBuilder (Parent.GetSignatureForError ());
7310                         if (MemberName.Left != null) {
7311                                 sb.Append ('.');
7312                                 sb.Append (MemberName.Left);
7313                         }
7314
7315                         sb.Append (".this");
7316                         sb.Append (Parameters.GetSignatureForError ().Replace ('(', '[').Replace (')', ']'));
7317                         return sb.ToString ();
7318                 }
7319
7320                 public override bool MarkForDuplicationCheck ()
7321                 {
7322                         caching_flags |= Flags.TestMethodDuplication;
7323                         return true;
7324                 }
7325         }
7326
7327         public class Operator : MethodOrOperator, IIteratorContainer {
7328
7329                 const int AllowedModifiers =
7330                         Modifiers.PUBLIC |
7331                         Modifiers.UNSAFE |
7332                         Modifiers.EXTERN |
7333                         Modifiers.STATIC;
7334
7335                 public enum OpType : byte {
7336
7337                         // Unary operators
7338                         LogicalNot,
7339                         OnesComplement,
7340                         Increment,
7341                         Decrement,
7342                         True,
7343                         False,
7344
7345                         // Unary and Binary operators
7346                         Addition,
7347                         Subtraction,
7348
7349                         UnaryPlus,
7350                         UnaryNegation,
7351                         
7352                         // Binary operators
7353                         Multiply,
7354                         Division,
7355                         Modulus,
7356                         BitwiseAnd,
7357                         BitwiseOr,
7358                         ExclusiveOr,
7359                         LeftShift,
7360                         RightShift,
7361                         Equality,
7362                         Inequality,
7363                         GreaterThan,
7364                         LessThan,
7365                         GreaterThanOrEqual,
7366                         LessThanOrEqual,
7367
7368                         // Implicit and Explicit
7369                         Implicit,
7370                         Explicit,
7371
7372                         // Just because of enum
7373                         TOP
7374                 };
7375
7376                 public readonly OpType OperatorType;
7377                 
7378                 public Method OperatorMethod;
7379
7380                 static string[] attribute_targets = new string [] { "method", "return" };
7381
7382                 public Operator (DeclSpace parent, OpType type, Expression ret_type,
7383                                  int mod_flags, Parameters parameters,
7384                                  ToplevelBlock block, Attributes attrs, Location loc)
7385                         : base (parent, null, ret_type, mod_flags, AllowedModifiers, false,
7386                                 new MemberName ("op_" + type, loc), attrs, parameters)
7387                 {
7388                         OperatorType = type;
7389                         Block = block;
7390                 }
7391
7392                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb) 
7393                 {
7394                         if (a.Type == TypeManager.conditional_attribute_type) {
7395                                 Error_ConditionalAttributeIsNotValid ();
7396                                 return;
7397                         }
7398
7399                         base.ApplyAttributeBuilder (a, cb);
7400                 }
7401                 
7402                 protected override bool CheckForDuplications ()
7403                 {
7404                         ArrayList ar = ParentContainer.Operators;
7405                         if (ar != null) {
7406                                 int arLen = ar.Count;
7407
7408                                 for (int i = 0; i < arLen; i++) {
7409                                         Operator o = (Operator) ar [i];
7410                                         if (IsDuplicateImplementation (o))
7411                                                 return false;
7412                                 }
7413                         }
7414
7415                         ar = ParentContainer.Methods;
7416                         if (ar != null) {
7417                                 int arLen = ar.Count;
7418
7419                                 for (int i = 0; i < arLen; i++) {
7420                                         Method m = (Method) ar [i];
7421                                         if (IsDuplicateImplementation (m))
7422                                                 return false;
7423                                 }
7424                         }
7425
7426                         return true;
7427                 }
7428
7429                 public override bool Define ()
7430                 {
7431                         const int RequiredModifiers = Modifiers.PUBLIC | Modifiers.STATIC;
7432                         if ((ModFlags & RequiredModifiers) != RequiredModifiers){
7433                                 Report.Error (558, Location, "User-defined operator `{0}' must be declared static and public", GetSignatureForError ());
7434                                 return false;
7435                         }
7436
7437                         if (!DoDefine ())
7438                                 return false;
7439
7440                         if (MemberType == TypeManager.void_type) {
7441                                 Report.Error (590, Location, "User-defined operators cannot return void");
7442                                 return false;
7443                         }
7444
7445                         // Don't pass the attributes, they are handled here.
7446                         OperatorMethod = new Method (
7447                                 Parent, null, Type, ModFlags, false, MemberName,
7448                                 Parameters, null);
7449
7450                         OperatorMethod.Block = Block;
7451                         OperatorMethod.IsOperator = this;                       
7452                         OperatorMethod.flags |= MethodAttributes.SpecialName | MethodAttributes.HideBySig;
7453                         OperatorMethod.Define ();
7454
7455                         if (OperatorMethod.MethodBuilder == null)
7456                                 return false;
7457
7458                         MethodBuilder = OperatorMethod.MethodBuilder;
7459
7460                         Type[] parameter_types = OperatorMethod.ParameterTypes;
7461                         Type declaring_type = OperatorMethod.MethodData.DeclaringType;
7462                         Type return_type = OperatorMethod.ReturnType;
7463                         Type first_arg_type = parameter_types [0];
7464
7465                         if (!CheckBase ())
7466                                 return false;
7467
7468                         // Rules for conversion operators
7469                         
7470                         if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
7471                                 if (first_arg_type == return_type && first_arg_type == declaring_type){
7472                                         Report.Error (555, Location,
7473                                                 "User-defined operator cannot take an object of the enclosing type and convert to an object of the enclosing type");
7474                                         return false;
7475                                 }
7476                                 
7477                                 if (first_arg_type != declaring_type && return_type != declaring_type){
7478                                         Report.Error (
7479                                                 556, Location, 
7480                                                 "User-defined conversion must convert to or from the " +
7481                                                 "enclosing type");
7482                                         return false;
7483                                 }
7484
7485                                 if (first_arg_type.IsInterface || return_type.IsInterface){
7486                                         Report.Error (552, Location, "User-defined conversion `{0}' cannot convert to or from an interface type",
7487                                                 GetSignatureForError ());
7488                                         return false;
7489                                 }
7490                                 
7491                                 if (first_arg_type.IsSubclassOf (return_type) || return_type.IsSubclassOf (first_arg_type)) {
7492                                         if (declaring_type.IsSubclassOf (return_type) || declaring_type.IsSubclassOf (first_arg_type)) {
7493                                                 Report.Error (553, Location, "User-defined conversion `{0}' cannot convert to or from base class",
7494                                                         GetSignatureForError ());
7495                                                 return false;
7496                                         }
7497                                         Report.Error (554, Location, "User-defined conversion `{0}' cannot convert to or from derived class",
7498                                                 GetSignatureForError ());
7499                                         return false;
7500                                 }
7501                         } else if (OperatorType == OpType.LeftShift || OperatorType == OpType.RightShift) {
7502                                 if (first_arg_type != declaring_type || parameter_types [1] != TypeManager.int32_type) {
7503                                         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");
7504                                         return false;
7505                                 }
7506                         } else if (Parameters.Count == 1) {
7507                                 // Checks for Unary operators
7508                                 
7509                                 if (OperatorType == OpType.Increment || OperatorType == OpType.Decrement) {
7510                                         if (return_type != declaring_type && !return_type.IsSubclassOf (declaring_type)) {
7511                                                 Report.Error (448, Location,
7512                                                         "The return type for ++ or -- operator must be the containing type or derived from the containing type");
7513                                                 return false;
7514                                         }
7515                                         if (first_arg_type != declaring_type) {
7516                                                 Report.Error (
7517                                                         559, Location, "The parameter type for ++ or -- operator must be the containing type");
7518                                                 return false;
7519                                         }
7520                                 }
7521                                 
7522                                 if (first_arg_type != declaring_type){
7523                                                 Report.Error (
7524                                                 562, Location,
7525                                                 "The parameter of a unary operator must be the " +
7526                                                 "containing type");
7527                                                 return false;
7528                                 }
7529                                 
7530                                 if (OperatorType == OpType.True || OperatorType == OpType.False) {
7531                                         if (return_type != TypeManager.bool_type){
7532                                                 Report.Error (
7533                                                         215, Location,
7534                                                         "The return type of operator True or False " +
7535                                                         "must be bool");
7536                                                 return false;
7537                                         }
7538                                 }
7539                                 
7540                         } else {
7541                                 // Checks for Binary operators
7542                                 
7543                                 if (first_arg_type != declaring_type &&
7544                                     parameter_types [1] != declaring_type){
7545                                         Report.Error (
7546                                                 563, Location,
7547                                                 "One of the parameters of a binary operator must " +
7548                                                 "be the containing type");
7549                                         return false;
7550                                 }
7551                         }
7552
7553                         return true;
7554                 }
7555                 
7556                 public override void Emit ()
7557                 {
7558                         base.Emit ();
7559
7560                         Parameters.ApplyAttributes (MethodBuilder);
7561
7562                         //
7563                         // abstract or extern methods have no bodies
7564                         //
7565                         if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
7566                                 return;
7567                         
7568                         EmitContext ec;
7569                         if ((flags & MethodAttributes.PinvokeImpl) == 0)
7570                                 ec = CreateEmitContext (Parent, MethodBuilder.GetILGenerator ());
7571                         else
7572                                 ec = CreateEmitContext (Parent, null);
7573                         
7574                         SourceMethod source = SourceMethod.Create (Parent, MethodBuilder, Block);
7575                         ec.EmitTopBlock (OperatorMethod, Block);
7576
7577                         if (source != null)
7578                                 source.CloseMethod ();
7579
7580                         Block = null;
7581                 }
7582
7583                 // Operator cannot be override
7584                 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
7585                 {
7586                         return null;
7587                 }
7588
7589                 public static string GetName (OpType ot)
7590                 {
7591                         switch (ot){
7592                         case OpType.LogicalNot:
7593                                 return "!";
7594                         case OpType.OnesComplement:
7595                                 return "~";
7596                         case OpType.Increment:
7597                                 return "++";
7598                         case OpType.Decrement:
7599                                 return "--";
7600                         case OpType.True:
7601                                 return "true";
7602                         case OpType.False:
7603                                 return "false";
7604                         case OpType.Addition:
7605                                 return "+";
7606                         case OpType.Subtraction:
7607                                 return "-";
7608                         case OpType.UnaryPlus:
7609                                 return "+";
7610                         case OpType.UnaryNegation:
7611                                 return "-";
7612                         case OpType.Multiply:
7613                                 return "*";
7614                         case OpType.Division:
7615                                 return "/";
7616                         case OpType.Modulus:
7617                                 return "%";
7618                         case OpType.BitwiseAnd:
7619                                 return "&";
7620                         case OpType.BitwiseOr:
7621                                 return "|";
7622                         case OpType.ExclusiveOr:
7623                                 return "^";
7624                         case OpType.LeftShift:
7625                                 return "<<";
7626                         case OpType.RightShift:
7627                                 return ">>";
7628                         case OpType.Equality:
7629                                 return "==";
7630                         case OpType.Inequality:
7631                                 return "!=";
7632                         case OpType.GreaterThan:
7633                                 return ">";
7634                         case OpType.LessThan:
7635                                 return "<";
7636                         case OpType.GreaterThanOrEqual:
7637                                 return ">=";
7638                         case OpType.LessThanOrEqual:
7639                                 return "<=";
7640                         case OpType.Implicit:
7641                                 return "implicit";
7642                         case OpType.Explicit:
7643                                 return "explicit";
7644                         default: return "";
7645                         }
7646                 }
7647
7648                 public static OpType GetOperatorType (string name)
7649                 {
7650                         if (name.StartsWith ("op_")){
7651                                 for (int i = 0; i < Unary.oper_names.Length; ++i) {
7652                                         if (Unary.oper_names [i] == name)
7653                                                 return (OpType)i;
7654                                 }
7655
7656                                 for (int i = 0; i < Binary.oper_names.Length; ++i) {
7657                                         if (Binary.oper_names [i] == name)
7658                                                 return (OpType)i;
7659                                 }
7660                         }
7661                         return OpType.TOP;
7662                 }
7663
7664                 public override string GetSignatureForError ()
7665                 {
7666                         StringBuilder sb = new StringBuilder ();
7667                         if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
7668                                 sb.AppendFormat ("{0}.{1} operator {2}", Parent.GetSignatureForError (), GetName (OperatorType), Type.Type == null ? Type.ToString () : TypeManager.CSharpName (Type.Type));
7669                         }
7670                         else {
7671                                 sb.AppendFormat ("{0}.operator {1}", Parent.GetSignatureForError (), GetName (OperatorType));
7672                         }
7673
7674                         sb.Append (Parameters.GetSignatureForError ());
7675                         return sb.ToString ();
7676                 }
7677                 
7678                 public override bool MarkForDuplicationCheck ()
7679                 {
7680                         caching_flags |= Flags.TestMethodDuplication;
7681                         return true;
7682                 }
7683
7684                 public override string[] ValidAttributeTargets {
7685                         get {
7686                                 return attribute_targets;
7687                         }
7688                 }
7689         }
7690
7691         //
7692         // This is used to compare method signatures
7693         //
7694         struct MethodSignature {
7695                 public string Name;
7696                 public Type RetType;
7697                 public Type [] Parameters;
7698                 
7699                 /// <summary>
7700                 ///    This delegate is used to extract methods which have the
7701                 ///    same signature as the argument
7702                 /// </summary>
7703                 public static MemberFilter method_signature_filter = new MemberFilter (MemberSignatureCompare);
7704                 
7705                 public MethodSignature (string name, Type ret_type, Type [] parameters)
7706                 {
7707                         Name = name;
7708                         RetType = ret_type;
7709
7710                         if (parameters == null)
7711                                 Parameters = Type.EmptyTypes;
7712                         else
7713                                 Parameters = parameters;
7714                 }
7715
7716                 public override string ToString ()
7717                 {
7718                         string pars = "";
7719                         if (Parameters.Length != 0){
7720                                 System.Text.StringBuilder sb = new System.Text.StringBuilder ();
7721                                 for (int i = 0; i < Parameters.Length; i++){
7722                                         sb.Append (Parameters [i]);
7723                                         if (i+1 < Parameters.Length)
7724                                                 sb.Append (", ");
7725                                 }
7726                                 pars = sb.ToString ();
7727                         }
7728
7729                         return String.Format ("{0} {1} ({2})", RetType, Name, pars);
7730                 }
7731                 
7732                 public override int GetHashCode ()
7733                 {
7734                         return Name.GetHashCode ();
7735                 }
7736
7737                 public override bool Equals (Object o)
7738                 {
7739                         MethodSignature other = (MethodSignature) o;
7740
7741                         if (other.Name != Name)
7742                                 return false;
7743
7744                         if (other.RetType != RetType)
7745                                 return false;
7746                         
7747                         if (Parameters == null){
7748                                 if (other.Parameters == null)
7749                                         return true;
7750                                 return false;
7751                         }
7752
7753                         if (other.Parameters == null)
7754                                 return false;
7755                         
7756                         int c = Parameters.Length;
7757                         if (other.Parameters.Length != c)
7758                                 return false;
7759
7760                         for (int i = 0; i < c; i++)
7761                                 if (other.Parameters [i] != Parameters [i])
7762                                         return false;
7763
7764                         return true;
7765                 }
7766
7767                 static bool MemberSignatureCompare (MemberInfo m, object filter_criteria)
7768                 {
7769                         MethodSignature sig = (MethodSignature) filter_criteria;
7770
7771                         if (m.Name != sig.Name)
7772                                 return false;
7773
7774                         Type ReturnType;
7775                         MethodInfo mi = m as MethodInfo;
7776                         PropertyInfo pi = m as PropertyInfo;
7777
7778                         if (mi != null)
7779                                 ReturnType = mi.ReturnType;
7780                         else if (pi != null)
7781                                 ReturnType = pi.PropertyType;
7782                         else
7783                                 return false;
7784                         
7785                         //
7786                         // we use sig.RetType == null to mean `do not check the
7787                         // method return value.  
7788                         //
7789                         if (sig.RetType != null)
7790                                 if (ReturnType != sig.RetType)
7791                                         return false;
7792
7793                         Type [] args;
7794                         if (mi != null)
7795                                 args = TypeManager.GetParameterData (mi).Types;
7796                         else
7797                                 args = TypeManager.GetArgumentTypes (pi);
7798                         Type [] sigp = sig.Parameters;
7799
7800                         if (args.Length != sigp.Length)
7801                                 return false;
7802
7803                         for (int i = args.Length; i > 0; ){
7804                                 i--;
7805                                 if (args [i] != sigp [i])
7806                                         return false;
7807                         }
7808                         return true;
7809                 }
7810         }
7811 }