2006-04-25 Peter Dennis Bartok <pbartok@novell.com>
[mono.git] / mcs / gmcs / class.cs
1 //
2 // class.cs: Class and Struct handlers
3 //
4 // Authors: Miguel de Icaza (miguel@gnu.org)
5 //          Martin Baulig (martin@ximian.com)
6 //          Marek Safar (marek.safar@seznam.cz)
7 //
8 // Licensed under the terms of the GNU GPL
9 //
10 // (C) 2001, 2002, 2003 Ximian, Inc (http://www.ximian.com)
11 // (C) 2004 Novell, Inc
12 //
13 //
14 //  2002-10-11  Miguel de Icaza  <miguel@ximian.com>
15 //
16 //      * class.cs: Following the comment from 2002-09-26 to AddMethod, I
17 //      have fixed a remaining problem: not every AddXXXX was adding a
18 //      fully qualified name.  
19 //
20 //      Now everyone registers a fully qualified name in the DeclSpace as
21 //      being defined instead of the partial name.  
22 //
23 //      Downsides: we are slower than we need to be due to the excess
24 //      copies and the names being registered this way.  
25 //
26 //      The reason for this is that we currently depend (on the corlib
27 //      bootstrap for instance) that types are fully qualified, because
28 //      we dump all the types in the namespace, and we should really have
29 //      types inserted into the proper namespace, so we can only store the
30 //      basenames in the defined_names array.
31 //
32 //
33 #define CACHE
34 using System;
35 using System.Collections;
36 using System.Collections.Specialized;
37 using System.Reflection;
38 using System.Reflection.Emit;
39 using System.Runtime.CompilerServices;
40 using System.Runtime.InteropServices;
41 using System.Security;
42 using System.Security.Permissions;
43 using System.Text;
44 using System.Xml;
45
46 using Mono.CompilerServices.SymbolWriter;
47
48 namespace Mono.CSharp {
49
50         public enum Kind {
51                 Root,
52                 Struct,
53                 Class,
54                 Interface
55         }
56
57         /// <summary>
58         ///   This is the base class for structs and classes.  
59         /// </summary>
60         public abstract class TypeContainer : DeclSpace, IMemberContainer {
61
62                 public class MemberCoreArrayList: ArrayList
63                 {
64                         /// <summary>
65                         ///   Defines the MemberCore objects that are in this array
66                         /// </summary>
67                         public virtual void DefineContainerMembers ()
68                         {
69                                 foreach (MemberCore mc in this) {
70                                         try {
71                                                 mc.Define ();
72                                         }
73                                         catch (Exception e) {
74                                                 throw new InternalErrorException (mc.Location, mc.GetSignatureForError (), e);
75                                         }
76                                 }
77                         }
78
79                         public virtual void Emit ()
80                         {
81                                 foreach (MemberCore mc in this)
82                                         mc.Emit ();
83                         }
84                 }
85
86                 public class MethodArrayList : MemberCoreArrayList
87                 {
88                         [Flags]
89                         enum CachedMethods {
90                                 Equals                  = 1,
91                                 GetHashCode             = 1 << 1
92                         }
93  
94                         CachedMethods cached_method;
95                         TypeContainer container;
96
97                         public MethodArrayList (TypeContainer container)
98                         {
99                                 this.container = container;
100                         }
101  
102                         /// <summary>
103                         /// Method container contains Equals method
104                         /// </summary>
105                         public bool HasEquals {
106                                 set {
107                                         cached_method |= CachedMethods.Equals;
108                                 }
109  
110                                 get {
111                                         return (cached_method & CachedMethods.Equals) != 0;
112                                 }
113                         }
114  
115                         /// <summary>
116                         /// Method container contains GetHashCode method
117                         /// </summary>
118                         public bool HasGetHashCode {
119                                 set {
120                                         cached_method |= CachedMethods.GetHashCode;
121                                 }
122  
123                                 get {
124                                         return (cached_method & CachedMethods.GetHashCode) != 0;
125                                 }
126                         }
127  
128                         public override void DefineContainerMembers ()
129                         {
130                                 base.DefineContainerMembers ();
131  
132                                 if (HasEquals && !HasGetHashCode) {
133                                         Report.Warning (659, 3, container.Location, "`{0}' overrides Object.Equals(object) but does not override Object.GetHashCode()", container.GetSignatureForError ());
134                                 }
135                         }
136  
137                 }
138
139                 public sealed class IndexerArrayList : MemberCoreArrayList
140                 {
141                         /// <summary>
142                         /// The indexer name for this container
143                         /// </summary>
144                         public string IndexerName = DefaultIndexerName;
145
146                         bool seen_normal_indexers = false;
147
148                         TypeContainer container;
149
150                         public IndexerArrayList (TypeContainer container)
151                         {
152                                 this.container = container;
153                         }
154
155                         /// <summary>
156                         /// Defines the indexers, and also verifies that the IndexerNameAttribute in the
157                         /// class is consistent.  Either it is `Item' or it is the name defined by all the
158                         /// indexers with the `IndexerName' attribute.
159                         ///
160                         /// Turns out that the IndexerNameAttribute is applied to each indexer,
161                         /// but it is never emitted, instead a DefaultMember attribute is attached
162                         /// to the class.
163                         /// </summary>
164                         public override void DefineContainerMembers()
165                         {
166                                 base.DefineContainerMembers ();
167
168                                 string class_indexer_name = null;
169
170                                 //
171                                 // If there's both an explicit and an implicit interface implementation, the
172                                 // explicit one actually implements the interface while the other one is just
173                                 // a normal indexer.  See bug #37714.
174                                 //
175
176                                 // Invariant maintained by AddIndexer(): All explicit interface indexers precede normal indexers
177                                 foreach (Indexer i in this) {
178                                         if (i.InterfaceType != null) {
179                                                 if (seen_normal_indexers)
180                                                         throw new Exception ("Internal Error: 'Indexers' array not sorted properly.");
181                                                 continue;
182                                         }
183
184                                         seen_normal_indexers = true;
185
186                                         if (class_indexer_name == null) {
187                                                 class_indexer_name = i.ShortName;
188                                                 continue;
189                                         }
190
191                                         if (i.ShortName != class_indexer_name)
192                                                 Report.Error (668, i.Location, "Two indexers have different names; the IndexerName attribute must be used with the same name on every indexer within a type");
193                                 }
194
195                                 if (class_indexer_name != null)
196                                         IndexerName = class_indexer_name;
197                         }
198
199                         public override void Emit ()
200                         {
201                                 base.Emit ();
202
203                                 if (!seen_normal_indexers)
204                                         return;
205
206                                 CustomAttributeBuilder cb = new CustomAttributeBuilder (TypeManager.default_member_ctor, new string [] { IndexerName });
207                                 container.TypeBuilder.SetCustomAttribute (cb);
208                         }
209                 }
210
211                 public class OperatorArrayList: MemberCoreArrayList
212                 {
213                         TypeContainer container;
214
215                         public OperatorArrayList (TypeContainer container)
216                         {
217                                 this.container = container;
218                         }
219
220                         //
221                         // Operator pair checking
222                         //
223                         class OperatorEntry
224                         {
225                                 public int flags;
226                                 public Type ret_type;
227                                 public Type type1, type2;
228                                 public Operator op;
229                                 public Operator.OpType ot;
230                                 
231                                 public OperatorEntry (int f, Operator o)
232                                 {
233                                         flags = f;
234
235                                         ret_type = o.MemberType;
236                                         Type [] pt = o.ParameterTypes;
237                                         type1 = pt [0];
238                                         type2 = pt [1];
239                                         op = o;
240                                         ot = o.OperatorType;
241                                 }
242
243                                 public override int GetHashCode ()
244                                 {       
245                                         return ret_type.GetHashCode ();
246                                 }
247
248                                 public override bool Equals (object o)
249                                 {
250                                         OperatorEntry other = (OperatorEntry) o;
251
252                                         if (other.ret_type != ret_type)
253                                                 return false;
254                                         if (other.type1 != type1)
255                                                 return false;
256                                         if (other.type2 != type2)
257                                                 return false;
258                                         return true;
259                                 }
260                         }
261                                 
262                         //
263                         // Checks that some operators come in pairs:
264                         //  == and !=
265                         // > and <
266                         // >= and <=
267                         // true and false
268                         //
269                         // They are matched based on the return type and the argument types
270                         //
271                         void CheckPairedOperators ()
272                         {
273                                 IDictionary pairs = new HybridDictionary ();
274                                 Operator true_op = null;
275                                 Operator false_op = null;
276                                 bool has_equality_or_inequality = false;
277                                 
278                                 // Register all the operators we care about.
279                                 foreach (Operator op in this){
280                                         int reg = 0;
281
282                                         // Skip erroneous code.
283                                         if (op.MethodBuilder == null)
284                                                 continue;
285
286                                         switch (op.OperatorType){
287                                         case Operator.OpType.Equality:
288                                                 reg = 1;
289                                                 has_equality_or_inequality = true;
290                                                 break;
291                                         case Operator.OpType.Inequality:
292                                                 reg = 2;
293                                                 has_equality_or_inequality = true;
294                                                 break;
295
296                                         case Operator.OpType.True:
297                                                 true_op = op;
298                                                 break;
299                                         case Operator.OpType.False:
300                                                 false_op = op;
301                                                 break;
302                                                 
303                                         case Operator.OpType.GreaterThan:
304                                                 reg = 1; break;
305                                         case Operator.OpType.LessThan:
306                                                 reg = 2; break;
307                                                 
308                                         case Operator.OpType.GreaterThanOrEqual:
309                                                 reg = 1; break;
310                                         case Operator.OpType.LessThanOrEqual:
311                                                 reg = 2; break;
312                                         }
313                                         if (reg == 0)
314                                                 continue;
315
316                                         OperatorEntry oe = new OperatorEntry (reg, op);
317
318                                         object o = pairs [oe];
319                                         if (o == null)
320                                                 pairs [oe] = oe;
321                                         else {
322                                                 oe = (OperatorEntry) o;
323                                                 oe.flags |= reg;
324                                         }
325                                 }
326
327                                 if (true_op != null){
328                                         if (false_op == null)
329                                                 Report.Error (216, true_op.Location, "The operator `{0}' requires a matching operator `false' to also be defined",
330                                                         true_op.GetSignatureForError ());
331                                 } else if (false_op != null)
332                                         Report.Error (216, false_op.Location, "The operator `{0}' requires a matching operator `true' to also be defined",
333                                                 false_op.GetSignatureForError ());
334                                 
335                                 //
336                                 // Look for the mistakes.
337                                 //
338                                 foreach (DictionaryEntry de in pairs){
339                                         OperatorEntry oe = (OperatorEntry) de.Key;
340
341                                         if (oe.flags == 3)
342                                                 continue;
343
344                                         string s = "";
345                                         switch (oe.ot){
346                                         case Operator.OpType.Equality:
347                                                 s = "!=";
348                                                 break;
349                                         case Operator.OpType.Inequality: 
350                                                 s = "==";
351                                                 break;
352                                         case Operator.OpType.GreaterThan: 
353                                                 s = "<";
354                                                 break;
355                                         case Operator.OpType.LessThan:
356                                                 s = ">";
357                                                 break;
358                                         case Operator.OpType.GreaterThanOrEqual:
359                                                 s = "<=";
360                                                 break;
361                                         case Operator.OpType.LessThanOrEqual:
362                                                 s = ">=";
363                                                 break;
364                                         }
365                                         Report.Error (216, oe.op.Location,
366                                                 "The operator `{0}' requires a matching operator `{1}' to also be defined",
367                                                 oe.op.GetSignatureForError (), s);
368                                 }
369
370                                 if (has_equality_or_inequality && (RootContext.WarningLevel > 2)) {
371                                         if (container.Methods == null || !container.Methods.HasEquals)
372                                                 Report.Warning (660, 2, container.Location, "`{0}' defines operator == or operator != but does not override Object.Equals(object o)", container.GetSignatureForError ());
373  
374                                         if (container.Methods == null || !container.Methods.HasGetHashCode)
375                                                 Report.Warning (661, 2, container.Location, "`{0}' defines operator == or operator != but does not override Object.GetHashCode()", container.GetSignatureForError ());
376                                 }
377                         }
378
379                         public override void DefineContainerMembers ()
380                         {
381                                 base.DefineContainerMembers ();
382                                 CheckPairedOperators ();
383                         }
384                 }
385
386
387                 // Whether this is a struct, class or interface
388                 public readonly Kind Kind;
389
390                 // Holds a list of classes and structures
391                 protected ArrayList types;
392
393                 // Holds the list of properties
394                 MemberCoreArrayList properties;
395
396                 // Holds the list of enumerations
397                 MemberCoreArrayList enums;
398
399                 // Holds the list of delegates
400                 MemberCoreArrayList delegates;
401                 
402                 // Holds the list of constructors
403                 protected MemberCoreArrayList instance_constructors;
404
405                 // Holds the list of fields
406                 MemberCoreArrayList fields;
407
408                 // Holds a list of fields that have initializers
409                 protected ArrayList initialized_fields;
410
411                 // Holds a list of static fields that have initializers
412                 protected ArrayList initialized_static_fields;
413
414                 // Holds the list of constants
415                 MemberCoreArrayList constants;
416
417                 // Holds the list of
418                 MemberCoreArrayList interfaces;
419
420                 // Holds the methods.
421                 MethodArrayList methods;
422
423                 // Holds the events
424                 protected MemberCoreArrayList events;
425
426                 // Holds the indexers
427                 IndexerArrayList indexers;
428
429                 // Holds the operators
430                 MemberCoreArrayList operators;
431
432                 // Holds the iterators
433                 ArrayList iterators;
434
435                 //
436                 // Pointers to the default constructor and the default static constructor
437                 //
438                 protected Constructor default_constructor;
439                 protected Constructor default_static_constructor;
440
441                 //
442                 // Points to the first non-static field added to the container.
443                 //
444                 // This is an arbitrary choice.  We are interested in looking at _some_ non-static field,
445                 // and the first one's as good as any.
446                 //
447                 FieldBase first_nonstatic_field = null;
448
449                 //
450                 // This one is computed after we can distinguish interfaces
451                 // from classes from the arraylist `type_bases' 
452                 //
453                 TypeExpr base_type;
454                 TypeExpr[] iface_exprs;
455
456                 ArrayList type_bases;
457
458                 bool members_defined;
459                 bool members_defined_ok;
460
461                 // The interfaces we implement.
462                 protected Type[] ifaces;
463
464                 // The base member cache and our member cache
465                 MemberCache base_cache;
466                 MemberCache member_cache;
467
468                 public const string DefaultIndexerName = "Item";
469
470                 Type GenericType;
471                 GenericTypeParameterBuilder[] gen_params;
472
473                 public TypeContainer PartialContainer;
474                 ArrayList partial_parts;
475
476                 /// <remarks>
477                 ///  The pending methods that need to be implemented
478                 //   (interfaces or abstract methods)
479                 /// </remarks>
480                 PendingImplementation pending;
481
482                 public TypeContainer (NamespaceEntry ns, DeclSpace parent, MemberName name,
483                                       Attributes attrs, Kind kind)
484                         : base (ns, parent, name, attrs)
485                 {
486                         if (parent != null && parent != RootContext.Tree.Types && parent.NamespaceEntry != ns)
487                                 throw new InternalErrorException ("A nested type should be in the same NamespaceEntry as its enclosing class");
488
489                         this.Kind = kind;
490                         this.PartialContainer = this;
491                 }
492
493                 public bool AddToMemberContainer (MemberCore symbol)
494                 {
495                         return AddToContainer (symbol, symbol.MemberName.MethodName);
496                 }
497
498                 protected virtual bool AddToTypeContainer (DeclSpace ds)
499                 {
500                         return AddToContainer (ds, ds.Basename);
501                 }
502
503                 public void AddConstant (Const constant)
504                 {
505                         if (!AddToMemberContainer (constant))
506                                 return;
507
508                         if (constants == null)
509                                 constants = new MemberCoreArrayList ();
510
511                         constants.Add (constant);
512                 }
513
514                 public void AddEnum (Mono.CSharp.Enum e)
515                 {
516                         if (!AddToTypeContainer (e))
517                                 return;
518
519                         if (enums == null)
520                                 enums = new MemberCoreArrayList ();
521
522                         enums.Add (e);
523                 }
524                 
525                 public bool AddClassOrStruct (TypeContainer c)
526                 {
527                         if (!AddToTypeContainer (c))
528                                 return false;
529
530                         if (types == null)
531                                 types = new ArrayList (2);
532
533                         RootContext.Tree.RecordDecl (c.NamespaceEntry.NS, c.MemberName, c);
534                         types.Add (c);
535                         return true;
536                 }
537
538                 public virtual TypeContainer AddPartial (TypeContainer nextPart)
539                 {
540                         return AddPartial (nextPart, nextPart.Basename);
541                 }
542
543                 protected TypeContainer AddPartial (TypeContainer nextPart, string name)
544                 {
545                         nextPart.ModFlags |= Modifiers.PARTIAL;
546                         TypeContainer tc = defined_names [name] as TypeContainer;
547
548                         if (tc == null) {
549                                 if (nextPart is Interface)
550                                         AddInterface (nextPart);
551                                 else
552                                         AddClassOrStruct (nextPart);
553                                 return nextPart;
554                         }
555
556                         if ((tc.ModFlags & Modifiers.PARTIAL) == 0) {
557                                 Report.SymbolRelatedToPreviousError (tc);
558                                 Error_MissingPartialModifier (nextPart);
559                                 return tc;
560                         }
561
562                         if (tc.Kind != nextPart.Kind) {
563                                 Report.SymbolRelatedToPreviousError (tc);
564                                 Report.Error (261, nextPart.Location,
565                                         "Partial declarations of `{0}' must be all classes, all structs or all interfaces",
566                                         nextPart.GetSignatureForError ());
567                                 return tc;
568                         }
569
570                         if ((tc.ModFlags & Modifiers.Accessibility) != (nextPart.ModFlags & Modifiers.Accessibility) &&
571                                 ((tc.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) == 0 &&
572                                  (nextPart.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) == 0)) {
573                                 Report.SymbolRelatedToPreviousError (tc);
574                                 Report.Error (262, nextPart.Location,
575                                         "Partial declarations of `{0}' have conflicting accessibility modifiers",
576                                         nextPart.GetSignatureForError ());
577                                 return tc;
578                         }
579
580                         if (tc.partial_parts == null)
581                                 tc.partial_parts = new ArrayList (1);
582
583                         tc.ModFlags |= nextPart.ModFlags;
584                         if (nextPart.attributes != null) {
585                                 if (tc.attributes == null)
586                                         tc.attributes = nextPart.attributes;
587                                 else
588                                         tc.attributes.AddAttributes (nextPart.attributes.Attrs);
589                         }
590
591                         nextPart.PartialContainer = tc;
592                         tc.partial_parts.Add (nextPart);
593                         return tc;
594                 }
595
596                 public void AddDelegate (Delegate d)
597                 {
598                         if (!AddToTypeContainer (d))
599                                 return;
600
601                         if (delegates == null)
602                                 delegates = new MemberCoreArrayList ();
603                         
604                         delegates.Add (d);
605                 }
606
607                 public void AddMethod (Method method)
608                 {
609                         if (!AddToMemberContainer (method))
610                                 return;
611
612                         if (methods == null)
613                                 methods = new MethodArrayList (this);
614
615                         if (method.MemberName.Left != null)
616                                 methods.Insert (0, method);
617                         else 
618                                 methods.Add (method);
619                 }
620
621                 //
622                 // Do not use this method: use AddMethod.
623                 //
624                 // This is only used by iterators.
625                 //
626                 public void AppendMethod (Method method)
627                 {
628                         if (!AddToMemberContainer (method))
629                                 return;
630
631                         if (methods == null)
632                                 methods = new MethodArrayList (this);
633
634                         methods.Add (method);
635                 }
636
637                 public void AddConstructor (Constructor c)
638                 {
639                         if (c.Name != MemberName.Name) {
640                                 Report.Error (1520, c.Location, "Class, struct, or interface method must have a return type");
641                         }
642
643                         bool is_static = (c.ModFlags & Modifiers.STATIC) != 0;
644                         
645                         if (is_static){
646                                 if (default_static_constructor != null) {
647                                         Report.SymbolRelatedToPreviousError (default_static_constructor);
648                                         Report.Error (111, c.Location, Error111, c.GetSignatureForError ());
649                                         return;
650                                 }
651
652                                 default_static_constructor = c;
653                         } else {
654                                 if (c.Parameters.Empty){
655                                         if (default_constructor != null) {
656                                                 Report.SymbolRelatedToPreviousError (default_constructor);
657                                                 Report.Error (111, c.Location, Error111, c.GetSignatureForError ());
658                                                 return;
659                                         }
660                                         default_constructor = c;
661                                 }
662                                 
663                                 if (instance_constructors == null)
664                                         instance_constructors = new MemberCoreArrayList ();
665                                 
666                                 instance_constructors.Add (c);
667                         }
668                 }
669
670                 internal static string Error111 {
671                         get {
672                                 return "`{0}' is already defined. Rename this member or use different parameter types";
673                         }
674                 }
675                 
676                 public bool AddInterface (TypeContainer iface)
677                 {
678                         if (!AddToTypeContainer (iface))
679                                 return false;
680
681                         if (interfaces == null) {
682                                 interfaces = new MemberCoreArrayList ();
683                         }
684
685                         RootContext.Tree.RecordDecl (iface.NamespaceEntry.NS, iface.MemberName, iface);
686                         interfaces.Add (iface);
687                         return true;
688                 }
689
690                 public void AddField (FieldMember field)
691                 {
692                         if (!AddToMemberContainer (field))
693                                 return;
694
695                         if (fields == null)
696                                 fields = new MemberCoreArrayList ();
697
698                         fields.Add (field);
699                         
700                         if ((field.ModFlags & Modifiers.STATIC) != 0)
701                                 return;
702
703                         if (first_nonstatic_field == null) {
704                                 first_nonstatic_field = field;
705                                 return;
706                         }
707
708                         if (Kind == Kind.Struct &&
709                             first_nonstatic_field.Parent != field.Parent &&
710                             RootContext.WarningLevel >= 3) {
711                                 Report.SymbolRelatedToPreviousError (first_nonstatic_field.Parent);
712                                 Report.Warning (282, 3, field.Location,
713                                         "struct instance field `{0}' found in different declaration from instance field `{1}'",
714                                         field.GetSignatureForError (), first_nonstatic_field.GetSignatureForError ());
715                         }
716                 }
717
718                 public void AddProperty (Property prop)
719                 {
720                         if (!AddToMemberContainer (prop) || 
721                                 !AddToMemberContainer (prop.Get) || !AddToMemberContainer (prop.Set))
722                                 return;
723
724                         if (properties == null)
725                                 properties = new MemberCoreArrayList ();
726
727                         if (prop.MemberName.Left != null)
728                                 properties.Insert (0, prop);
729                         else
730                                 properties.Add (prop);
731                 }
732
733                 public void AddEvent (Event e)
734                 {
735                         if (!AddToMemberContainer (e))
736                                 return;
737
738                         if (e is EventProperty) {
739                                 if (!AddToMemberContainer (e.Add))
740                                         return;
741
742                                 if (!AddToMemberContainer (e.Remove))
743                                         return;
744                         }
745
746                         if (events == null)
747                                 events = new MemberCoreArrayList ();
748
749                         events.Add (e);
750                 }
751
752                 /// <summary>
753                 /// Indexer has special handling in constrast to other AddXXX because the name can be driven by IndexerNameAttribute
754                 /// </summary>
755                 public void AddIndexer (Indexer i)
756                 {
757                         if (indexers == null)
758                                 indexers = new IndexerArrayList (this);
759
760                         if (i.IsExplicitImpl)
761                                 indexers.Insert (0, i);
762                         else
763                                 indexers.Add (i);
764                 }
765
766                 public void AddOperator (Operator op)
767                 {
768                         if (!AddToMemberContainer (op))
769                                 return;
770
771                         if (operators == null)
772                                 operators = new OperatorArrayList (this);
773
774                         operators.Add (op);
775                 }
776
777                 public void AddIterator (Iterator i)
778                 {
779                         if (iterators == null)
780                                 iterators = new ArrayList ();
781
782                         iterators.Add (i);
783                 }
784
785                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
786                 {
787                         if (a.Type == TypeManager.default_member_type) {
788                                 if (Indexers != null) {
789                                         Report.Error (646, a.Location, "Cannot specify the `DefaultMember' attribute on type containing an indexer");
790                                         return;
791                                 }
792                         }
793                         
794                         base.ApplyAttributeBuilder (a, cb);
795                 } 
796
797                 public override AttributeTargets AttributeTargets {
798                         get {
799                                 throw new NotSupportedException ();
800                         }
801                 }
802
803                 public ArrayList Types {
804                         get {
805                                 return types;
806                         }
807                 }
808
809                 public MethodArrayList Methods {
810                         get {
811                                 return methods;
812                         }
813                 }
814
815                 public ArrayList Constants {
816                         get {
817                                 return constants;
818                         }
819                 }
820
821                 public ArrayList Interfaces {
822                         get {
823                                 return interfaces;
824                         }
825                 }
826
827                 public ArrayList Iterators {
828                         get {
829                                 return iterators;
830                         }
831                 }
832
833                 protected Type BaseType {
834                         get {
835                                 return TypeBuilder.BaseType;
836                         }
837                 }
838                 
839                 public ArrayList Bases {
840                         get {
841                                 return type_bases;
842                         }
843
844                         set {
845                                 type_bases = value;
846                         }
847                 }
848
849                 public ArrayList Fields {
850                         get {
851                                 return fields;
852                         }
853                 }
854
855                 public ArrayList InstanceConstructors {
856                         get {
857                                 return instance_constructors;
858                         }
859                 }
860
861                 public ArrayList Properties {
862                         get {
863                                 return properties;
864                         }
865                 }
866
867                 public ArrayList Events {
868                         get {
869                                 return events;
870                         }
871                 }
872                 
873                 public ArrayList Enums {
874                         get {
875                                 return enums;
876                         }
877                 }
878
879                 public ArrayList Indexers {
880                         get {
881                                 return indexers;
882                         }
883                 }
884
885                 public ArrayList Operators {
886                         get {
887                                 return operators;
888                         }
889                 }
890
891                 public ArrayList Delegates {
892                         get {
893                                 return delegates;
894                         }
895                 }
896                 
897                 protected override TypeAttributes TypeAttr {
898                         get {
899                                 return Modifiers.TypeAttr (ModFlags, IsTopLevel) | base.TypeAttr;
900                         }
901                 }
902
903                 public string IndexerName {
904                         get {
905                                 return indexers == null ? DefaultIndexerName : indexers.IndexerName;
906                         }
907                 }
908
909                 public bool IsComImport {
910                         get {
911                                 if (OptAttributes == null)
912                                         return false;
913
914                                 return OptAttributes.Contains (TypeManager.comimport_attr_type);
915                         }
916                 }
917
918                 public virtual void RegisterFieldForInitialization (FieldBase field)
919                 {
920                         if ((field.ModFlags & Modifiers.STATIC) != 0){
921                                 if (initialized_static_fields == null)
922                                         initialized_static_fields = new ArrayList (4);
923
924                                 initialized_static_fields.Add (field);
925                         } else {
926                                 if (initialized_fields == null)
927                                         initialized_fields = new ArrayList (4);
928
929                                 initialized_fields.Add (field);
930                         }
931                 }
932
933                 //
934                 // Emits the instance field initializers
935                 //
936                 public bool EmitFieldInitializers (EmitContext ec)
937                 {
938                         ArrayList fields;
939                         
940                         if (ec.IsStatic){
941                                 fields = initialized_static_fields;
942                         } else {
943                                 fields = initialized_fields;
944                         }
945
946                         if (fields == null)
947                                 return true;
948
949                         foreach (FieldBase f in fields) {
950                                 f.EmitInitializer (ec);
951                         }
952                         return true;
953                 }
954                 
955                 public override string DocComment {
956                         get {
957                                 return comment;
958                         }
959                         set {
960                                 if (value == null)
961                                         return;
962
963                                 comment += value;
964                         }
965                 }
966
967                 public PendingImplementation PendingImplementations {
968                         get { return pending; }
969                 }
970
971                 public override bool GetClsCompliantAttributeValue ()
972                 {
973                         if (PartialContainer != this)
974                                 return PartialContainer.GetClsCompliantAttributeValue ();
975
976                         return base.GetClsCompliantAttributeValue ();
977                 }
978
979                 TypeExpr[] GetNormalBases (out TypeExpr base_class)
980                 {
981                         base_class = null;
982                         if (Bases == null)
983                                 return null;
984
985                         int count = Bases.Count;
986                         int start = 0, i, j;
987
988                         if (Kind == Kind.Class){
989                                 TypeExpr name = ((Expression) Bases [0]).ResolveAsBaseTerminal (this, false);
990
991                                 if (name == null){
992                                         return null;
993                                 }
994
995                                 if (!name.IsInterface) {
996                                         // base_class could be a class, struct, enum, delegate.
997                                         // This is validated in GetClassBases.
998                                         base_class = name;
999                                         start = 1;
1000                                 }
1001                         }
1002
1003                         TypeExpr [] ifaces = new TypeExpr [count-start];
1004                         
1005                         for (i = start, j = 0; i < count; i++, j++){
1006                                 TypeExpr resolved = ((Expression) Bases [i]).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                 //
3127                 // The method we're overriding if this is an override method.
3128                 //
3129                 protected MethodInfo base_method = null;
3130
3131                 public MethodCore (DeclSpace parent, GenericMethod generic,
3132                                    Expression type, int mod, int allowed_mod, bool is_iface,
3133                                    MemberName name, Attributes attrs, Parameters parameters)
3134                         : base (parent, generic, type, mod, allowed_mod, Modifiers.PRIVATE,
3135                                 name, attrs)
3136                 {
3137                         Parameters = parameters;
3138                         IsInterface = is_iface;
3139                 }
3140                 
3141                 //
3142                 //  Returns the System.Type array for the parameters of this method
3143                 //
3144                 public Type [] ParameterTypes {
3145                         get {
3146                                 return Parameters.Types;
3147                         }
3148                 }
3149
3150                 public Parameters ParameterInfo
3151                 {
3152                         get {
3153                                 return Parameters;
3154                         }
3155                 }
3156
3157                 public ToplevelBlock Block {
3158                         get {
3159                                 return block;
3160                         }
3161
3162                         set {
3163                                 block = value;
3164                         }
3165                 }
3166
3167                 public void SetYields ()
3168                 {
3169                         ModFlags |= Modifiers.METHOD_YIELDS;
3170                 }
3171
3172                 protected override bool CheckBase ()
3173                 {
3174                         if (!base.CheckBase ())
3175                                 return false;
3176                         
3177                         // Check whether arguments were correct.
3178                         if (!DoDefineParameters ())
3179                                 return false;
3180
3181                         if ((caching_flags & Flags.TestMethodDuplication) != 0 && !CheckForDuplications ())
3182                                 return false;
3183
3184                         if (IsExplicitImpl)
3185                                 return true;
3186
3187                         // Is null for System.Object while compiling corlib and base interfaces
3188                         if (ParentContainer.BaseCache == null) {
3189                                 if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0)) {
3190                                         Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
3191                                 }
3192                                 return true;
3193                         }
3194
3195                         Type base_ret_type = null;
3196                         base_method = FindOutBaseMethod (ref base_ret_type);
3197
3198                         // method is override
3199                         if (base_method != null) {
3200
3201                                 if (!CheckMethodAgainstBase ())
3202                                         return false;
3203
3204                                 if ((ModFlags & Modifiers.NEW) == 0) {
3205                                         if (!TypeManager.IsEqual (MemberType, TypeManager.TypeToCoreType (base_ret_type))) {
3206                                                 Report.SymbolRelatedToPreviousError (base_method);
3207                                                 if (this is PropertyBase) {
3208                                                         Report.Error (1715, Location, "`{0}': type must be `{1}' to match overridden member `{2}'", 
3209                                                                 GetSignatureForError (), TypeManager.CSharpName (base_ret_type), TypeManager.CSharpSignature (base_method));
3210                                                 }
3211                                                 else {
3212                                                         Report.Error (508, Location, "`{0}': return type must be `{1}' to match overridden member `{2}'",
3213                                                                 GetSignatureForError (), TypeManager.CSharpName (base_ret_type), TypeManager.CSharpSignature (base_method));
3214                                                 }
3215                                                 return false;
3216                                         }
3217                                 } else {
3218                                         if (base_method.IsAbstract && !IsInterface) {
3219                                                 Report.SymbolRelatedToPreviousError (base_method);
3220                                                 Report.Error (533, Location, "`{0}' hides inherited abstract member `{1}'",
3221                                                         GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3222                                                 return false;
3223                                         }
3224                                 }
3225
3226                                 if (base_method.IsSpecialName && !(this is PropertyBase)) {
3227                                         Report.Error (115, Location, "`{0}': no suitable method found to override", GetSignatureForError ());
3228                                         return false;
3229                                 }
3230
3231                                 if (Name == "Equals" && Parameters.Count == 1 && ParameterTypes [0] == TypeManager.object_type)
3232                                         ParentContainer.Mark_HasEquals ();
3233                                 else if (Name == "GetHashCode" && Parameters.Empty)
3234                                         ParentContainer.Mark_HasGetHashCode ();
3235
3236                                 if ((ModFlags & Modifiers.OVERRIDE) != 0) {
3237                                         ObsoleteAttribute oa = AttributeTester.GetMethodObsoleteAttribute (base_method);
3238                                         if (oa != null) {
3239                                                 if (OptAttributes == null || !OptAttributes.Contains (TypeManager.obsolete_attribute_type)) {
3240                                                         Report.SymbolRelatedToPreviousError (base_method);
3241                                                         Report.Warning (672, 1, Location, "Member `{0}' overrides obsolete member `{1}'. Add the Obsolete attribute to `{0}'",
3242                                                                 GetSignatureForError (), TypeManager.CSharpSignature (base_method) );
3243                                                 }
3244                                         }
3245                                 }
3246                                 return true;
3247                         }
3248
3249                         MemberInfo conflict_symbol = ParentContainer.FindBaseMemberWithSameName (Name, !(this is Property));
3250                         if ((ModFlags & Modifiers.OVERRIDE) != 0) {
3251                                 if (conflict_symbol != null) {
3252                                         Report.SymbolRelatedToPreviousError (conflict_symbol);
3253                                         if (this is PropertyBase)
3254                                                 Report.Error (544, Location, "`{0}': cannot override because `{1}' is not a property", GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
3255                                         else
3256                                                 Report.Error (505, Location, "`{0}': cannot override because `{1}' is not a method", GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
3257                                 } else
3258                                         Report.Error (115, Location, "`{0}': no suitable method found to override", GetSignatureForError ());
3259                                 return false;
3260                         }
3261
3262                         if (conflict_symbol == null) {
3263                                 if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0)) {
3264                                         Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
3265                                 }
3266                                 return true;
3267                         }
3268
3269                         if ((ModFlags & Modifiers.NEW) == 0) {
3270                                 if (this is Method && conflict_symbol is MethodBase)
3271                                         return true;
3272
3273                                 Report.SymbolRelatedToPreviousError (conflict_symbol);
3274                                 Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
3275                                         GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
3276                         }
3277
3278                         return true;
3279                 }
3280
3281                 //
3282                 // Performs various checks on the MethodInfo `mb' regarding the modifier flags
3283                 // that have been defined.
3284                 //
3285                 // `name' is the user visible name for reporting errors (this is used to
3286                 // provide the right name regarding method names and properties)
3287                 //
3288                 bool CheckMethodAgainstBase ()
3289                 {
3290                         bool ok = true;
3291
3292                         if ((ModFlags & Modifiers.OVERRIDE) != 0){
3293                                 if (!(base_method.IsAbstract || base_method.IsVirtual)){
3294                                         Report.Error (506, Location,
3295                                                 "`{0}': cannot override inherited member `{1}' because it is not marked virtual, abstract or override",
3296                                                  GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3297                                         ok = false;
3298                                 }
3299                                 
3300                                 // Now we check that the overriden method is not final
3301                                 
3302                                 if (base_method.IsFinal) {
3303                                         Report.SymbolRelatedToPreviousError (base_method);
3304                                         Report.Error (239, Location, "`{0}': cannot override inherited member `{1}' because it is sealed",
3305                                                               GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3306                                         ok = false;
3307                                 }
3308                                 //
3309                                 // Check that the permissions are not being changed
3310                                 //
3311                                 MethodAttributes thisp = flags & MethodAttributes.MemberAccessMask;
3312                                 MethodAttributes base_classp = base_method.Attributes & MethodAttributes.MemberAccessMask;
3313
3314                                 if (!CheckAccessModifiers (thisp, base_classp, base_method)) {
3315                                         Error_CannotChangeAccessModifiers (base_method, base_classp, null);
3316                                         ok = false;
3317                                 }
3318                         }
3319
3320                         if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE)) == 0 && Name != "Finalize") {
3321                                 ModFlags |= Modifiers.NEW;
3322                                 Report.SymbolRelatedToPreviousError (base_method);
3323                                 if (!IsInterface && (base_method.IsVirtual || base_method.IsAbstract)) {
3324                                         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",
3325                                                 GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3326                                 } else {
3327                                         Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
3328                                                 GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3329                                 }
3330                         }
3331
3332                         return ok;
3333                 }
3334                 
3335                 protected bool CheckAccessModifiers (MethodAttributes thisp, MethodAttributes base_classp, MethodInfo base_method)
3336                 {
3337                         if ((base_classp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
3338                                 //
3339                                 // when overriding protected internal, the method can be declared
3340                                 // protected internal only within the same assembly
3341                                 //
3342
3343                                 if ((thisp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
3344                                         if (Parent.TypeBuilder.Assembly != base_method.DeclaringType.Assembly){
3345                                                 //
3346                                                 // assemblies differ - report an error
3347                                                 //
3348                                                 
3349                                                 return false;
3350                                         } else if (thisp != base_classp) {
3351                                                 //
3352                                                 // same assembly, but other attributes differ - report an error
3353                                                 //
3354                                                 
3355                                                 return false;
3356                                         };
3357                                 } else if ((thisp & MethodAttributes.Family) != MethodAttributes.Family) {
3358                                         //
3359                                         // if it's not "protected internal", it must be "protected"
3360                                         //
3361
3362                                         return false;
3363                                 } else if (Parent.TypeBuilder.Assembly == base_method.DeclaringType.Assembly) {
3364                                         //
3365                                         // protected within the same assembly - an error
3366                                         //
3367                                         return false;
3368                                 } else if ((thisp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem)) != 
3369                                            (base_classp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem))) {
3370                                         //
3371                                         // protected ok, but other attributes differ - report an error
3372                                         //
3373                                         return false;
3374                                 }
3375                                 return true;
3376                         } else {
3377                                 return (thisp == base_classp);
3378                         }
3379                 }
3380
3381                 public bool CheckAbstractAndExtern (bool has_block)
3382                 {
3383                         if (ParentContainer.Kind == Kind.Interface)
3384                                 return true;
3385
3386                         if (has_block) {
3387                                 if ((ModFlags & Modifiers.EXTERN) != 0) {
3388                                         Report.Error (179, Location, "`{0}' cannot declare a body because it is marked extern",
3389                                                 GetSignatureForError ());
3390                                         return false;
3391                                 }
3392
3393                                 if ((ModFlags & Modifiers.ABSTRACT) != 0) {
3394                                         Report.Error (500, Location, "`{0}' cannot declare a body because it is marked abstract",
3395                                                 GetSignatureForError ());
3396                                         return false;
3397                                 }
3398                         } else {
3399                                 if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) == 0) {
3400                                         Report.Error (501, Location, "`{0}' must declare a body because it is not marked abstract or extern",
3401                                                 GetSignatureForError ());
3402                                         return false;
3403                                 }
3404                         }
3405
3406                         return true;
3407                 }
3408
3409                 protected void Error_CannotChangeAccessModifiers (MemberInfo base_method, MethodAttributes ma, string suffix)
3410                 {
3411                         Report.SymbolRelatedToPreviousError (base_method);
3412                         string base_name = TypeManager.GetFullNameSignature (base_method);
3413                         string this_name = GetSignatureForError ();
3414                         if (suffix != null) {
3415                                 base_name += suffix;
3416                                 this_name += suffix;
3417                         }
3418
3419                         Report.Error (507, Location, "`{0}': cannot change access modifiers when overriding `{1}' inherited member `{2}'",
3420                                 this_name, Modifiers.GetDescription (ma), base_name);
3421                 }
3422
3423                 protected static string Error722 {
3424                         get {
3425                                 return "`{0}': static types cannot be used as return types";
3426                         }
3427                 }
3428
3429                 /// <summary>
3430                 /// For custom member duplication search in a container
3431                 /// </summary>
3432                 protected abstract bool CheckForDuplications ();
3433
3434                 /// <summary>
3435                 /// Gets base method and its return type
3436                 /// </summary>
3437                 protected abstract MethodInfo FindOutBaseMethod (ref Type base_ret_type);
3438
3439                 protected bool DoDefineParameters ()
3440                 {
3441                         IResolveContext rc = GenericMethod == null ? this : (IResolveContext)ds;
3442
3443                         // Check if arguments were correct
3444                         if (!Parameters.Resolve (rc))
3445                                 return false;
3446
3447                         return CheckParameters (ParameterTypes);
3448                 }
3449
3450                 bool CheckParameters (Type [] parameters)
3451                 {
3452                         bool error = false;
3453
3454                         foreach (Type partype in parameters){
3455                                 if (partype == TypeManager.void_type) {
3456                                         Report.Error (
3457                                                 1547, Location, "Keyword 'void' cannot " +
3458                                                 "be used in this context");
3459                                         return false;
3460                                 }
3461
3462                                 if (partype.IsPointer){
3463                                         if (!TypeManager.VerifyUnManaged (TypeManager.GetElementType (partype), Location))
3464                                                 error = true;
3465                                 }
3466
3467                                 if (ds.AsAccessible (partype, ModFlags))
3468                                         continue;
3469
3470                                 Report.SymbolRelatedToPreviousError (partype);
3471                                 if (this is Indexer)
3472                                         Report.Error (55, Location,
3473                                                 "Inconsistent accessibility: parameter type `" +
3474                                                 TypeManager.CSharpName (partype) + "' is less " +
3475                                                 "accessible than indexer `" + GetSignatureForError () + "'");
3476                                 else if (this is Operator)
3477                                         Report.Error (57, Location,
3478                                                 "Inconsistent accessibility: parameter type `" +
3479                                                 TypeManager.CSharpName (partype) + "' is less " +
3480                                                 "accessible than operator `" + GetSignatureForError () + "'");
3481                                 else
3482                                         Report.Error (51, Location,
3483                                                 "Inconsistent accessibility: parameter type `" +
3484                                                 TypeManager.CSharpName (partype) + "' is less " +
3485                                                 "accessible than method `" + GetSignatureForError () + "'");
3486                                 error = true;
3487                         }
3488
3489                         return !error;
3490                 }
3491
3492                 protected override bool VerifyClsCompliance ()
3493                 {
3494                         if (!base.VerifyClsCompliance ()) {
3495                                 if ((ModFlags & Modifiers.ABSTRACT) != 0 && IsExposedFromAssembly () && Parent.IsClsComplianceRequired ()) {
3496                                         Report.Error (3011, Location, "`{0}': only CLS-compliant members can be abstract", GetSignatureForError ());
3497                                 }
3498                                 return false;
3499                         }
3500
3501                         if (Parameters.HasArglist) {
3502                                 Report.Error (3000, Location, "Methods with variable arguments are not CLS-compliant");
3503                         }
3504
3505                         if (!AttributeTester.IsClsCompliant (MemberType)) {
3506                                 if (this is PropertyBase)
3507                                         Report.Error (3003, Location, "Type of `{0}' is not CLS-compliant",
3508                                                       GetSignatureForError ());
3509                                 else
3510                                         Report.Error (3002, Location, "Return type of `{0}' is not CLS-compliant",
3511                                                       GetSignatureForError ());
3512                         }
3513
3514                         Parameters.VerifyClsCompliance ();
3515
3516                         return true;
3517                 }
3518
3519                 protected bool IsDuplicateImplementation (MethodCore method)
3520                 {
3521                         if (method == this || !(method.MemberName.Equals (MemberName)))
3522                                 return false;
3523
3524                         Type[] param_types = method.ParameterTypes;
3525                         // This never happen. Rewrite this as Equal
3526                         if (param_types == null && ParameterTypes == null)
3527                                 return true;
3528                         if (param_types == null || ParameterTypes == null)
3529                                 return false;
3530
3531                         if (param_types.Length != ParameterTypes.Length)
3532                                 return false;
3533
3534                         if (method.Parameters.HasArglist != Parameters.HasArglist)
3535                                 return false;
3536                         
3537                         bool equal = true;
3538
3539                         for (int i = 0; i < param_types.Length; i++) {
3540                                 if (param_types [i] != ParameterTypes [i])
3541                                         equal = false;
3542                         }
3543
3544                         if (IsExplicitImpl && (method.InterfaceType != InterfaceType))
3545                                 equal = false;
3546
3547                         // TODO: make operator compatible with MethodCore to avoid this
3548                         if (this is Operator && method is Operator) {
3549                                 if (MemberType != method.MemberType)
3550                                         equal = false;
3551                         }
3552
3553                         if (equal) {
3554                                 //
3555                                 // Try to report 663: method only differs on out/ref
3556                                 //
3557                                 Parameters info = ParameterInfo;
3558                                 Parameters other_info = method.ParameterInfo;
3559                                 for (int i = 0; i < info.Count; i++){
3560                                         try {
3561                                         if (info.ParameterModifier (i) != other_info.ParameterModifier (i)){
3562                                                 Report.SymbolRelatedToPreviousError (method);
3563                                                 Report.Error (663, Location, "`{0}': Methods cannot differ only on their use of ref and out on a parameters",
3564                                                               GetSignatureForError ());
3565                                                 return false;
3566                                         }} catch {
3567                                                 Console.WriteLine ("Method is: {0} {1}", method.Location, method);
3568                                                 Console.WriteLine ("this is: {0} {1}", Location, this);
3569                                         }
3570                                 }
3571
3572                                 Report.SymbolRelatedToPreviousError (method);
3573                                 if (this is Operator && method is Operator)
3574                                         Report.Error (557, Location, "Duplicate user-defined conversion in type `{0}'", Parent.Name);
3575                                 else
3576                                         Report.Error (111, Location, TypeContainer.Error111, GetSignatureForError ());
3577
3578                                 return true;
3579                         }
3580
3581                         return false;
3582                 }
3583
3584                 public override bool IsUsed {
3585                         get { return IsExplicitImpl || base.IsUsed; }
3586                 }
3587
3588                 //
3589                 // Returns a string that represents the signature for this 
3590                 // member which should be used in XML documentation.
3591                 //
3592                 public override string GetDocCommentName (DeclSpace ds)
3593                 {
3594                         return DocUtil.GetMethodDocCommentName (this, ds);
3595                 }
3596
3597                 //
3598                 // Raised (and passed an XmlElement that contains the comment)
3599                 // when GenerateDocComment is writing documentation expectedly.
3600                 //
3601                 // FIXME: with a few effort, it could be done with XmlReader,
3602                 // that means removal of DOM use.
3603                 //
3604                 internal override void OnGenerateDocComment (XmlElement el)
3605                 {
3606                         DocUtil.OnMethodGenerateDocComment (this, el);
3607                 }
3608
3609                 //
3610                 //   Represents header string for documentation comment.
3611                 //
3612                 public override string DocCommentHeader {
3613                         get { return "M:"; }
3614                 }
3615
3616         }
3617
3618         public abstract class MethodOrOperator : MethodCore, IMethodData
3619         {
3620                 public MethodBuilder MethodBuilder;
3621                 ReturnParameter return_attributes;
3622                 ListDictionary declarative_security;
3623                 protected MethodData MethodData;
3624
3625                 static string[] attribute_targets = new string [] { "method", "return" };
3626
3627                 protected MethodOrOperator (DeclSpace parent, GenericMethod generic, Expression type, int mod,
3628                                 int allowed_mod, bool is_interface, MemberName name,
3629                                 Attributes attrs, Parameters parameters)
3630                         : base (parent, generic, type, mod, allowed_mod, is_interface, name,
3631                                         attrs, parameters)
3632                 {
3633                 }
3634
3635                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
3636                 {
3637                         if (a.Target == AttributeTargets.ReturnValue) {
3638                                 if (return_attributes == null)
3639                                         return_attributes = new ReturnParameter (MethodBuilder, Location);
3640
3641                                 return_attributes.ApplyAttributeBuilder (a, cb);
3642                                 return;
3643                         }
3644
3645                         if (a.Type == TypeManager.methodimpl_attr_type &&
3646                                 (a.GetMethodImplOptions () & MethodImplOptions.InternalCall) != 0) {
3647                                 MethodBuilder.SetImplementationFlags (MethodImplAttributes.InternalCall | MethodImplAttributes.Runtime);
3648                         }
3649
3650                         if (a.Type == TypeManager.dllimport_type) {
3651                                 const int extern_static = Modifiers.EXTERN | Modifiers.STATIC;
3652                                 if ((ModFlags & extern_static) != extern_static) {
3653                                         Report.Error (601, a.Location, "The DllImport attribute must be specified on a method marked `static' and `extern'");
3654                                 }
3655
3656                                 return;
3657                         }
3658
3659                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
3660                                 if (declarative_security == null)
3661                                         declarative_security = new ListDictionary ();
3662                                 a.ExtractSecurityPermissionSet (declarative_security);
3663                                 return;
3664                         }
3665
3666                         MethodBuilder.SetCustomAttribute (cb);
3667                 }
3668
3669                 public override AttributeTargets AttributeTargets {
3670                         get {
3671                                 return AttributeTargets.Method; 
3672                         }
3673                 }
3674
3675                 public EmitContext CreateEmitContext (DeclSpace tc, ILGenerator ig)
3676                 {
3677                         EmitContext ec = new EmitContext (this,
3678                                 tc, this.ds, Location, ig, MemberType, ModFlags, false);
3679
3680                         Iterator iterator = tc as Iterator;
3681                         if (iterator != null)
3682                                 ec.CurrentAnonymousMethod = iterator.Host;
3683
3684                         return ec;
3685                 }
3686
3687                 public override bool Define ()
3688                 {
3689                         if (!DoDefineBase ())
3690                                 return false;
3691
3692                         MethodBuilder mb = null;
3693                         if (GenericMethod != null) {
3694                                 string method_name = MemberName.Name;
3695
3696                                 if (IsExplicitImpl) {
3697                                         method_name = TypeManager.CSharpName (InterfaceType) +
3698                                                 '.' + method_name;
3699                                 }
3700
3701                                 mb = Parent.TypeBuilder.DefineMethod (method_name, flags);
3702
3703                                 if (!GenericMethod.Define (mb))
3704                                         return false;
3705                         }
3706
3707                         if (!DoDefine ())
3708                                 return false;
3709
3710                         if (!CheckAbstractAndExtern (block != null))
3711                                 return false;
3712
3713                         if (!CheckBase ())
3714                                 return false;
3715
3716                         MethodData = new MethodData (this, ModFlags, flags, this, mb, GenericMethod, base_method);
3717
3718                         if (!MethodData.Define (ParentContainer))
3719                                 return false;
3720
3721                         MethodBuilder = MethodData.MethodBuilder;
3722
3723                         if (MemberType.IsAbstract && MemberType.IsSealed) {
3724                                 Report.Error (722, Location, Error722, TypeManager.CSharpName (MemberType));
3725                                 return false;
3726                         }
3727
3728                         return true;
3729                 }
3730
3731                 public override void Emit ()
3732                 {
3733                         if (OptAttributes != null)
3734                                 OptAttributes.Emit ();
3735
3736                         if (declarative_security != null) {
3737                                 foreach (DictionaryEntry de in declarative_security) {
3738                                         MethodBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
3739                                 }
3740                         }
3741
3742                         base.Emit ();
3743                 }
3744
3745                 protected void Error_ConditionalAttributeIsNotValid ()
3746                 {
3747                         Report.Error (577, Location,
3748                                 "Conditional not valid on `{0}' because it is a constructor, destructor, operator or explicit interface implementation",
3749                                 GetSignatureForError ());
3750                 }
3751
3752                 public override bool MarkForDuplicationCheck ()
3753                 {
3754                         caching_flags |= Flags.TestMethodDuplication;
3755                         return true;
3756                 }
3757
3758                 public override string[] ValidAttributeTargets {
3759                         get {
3760                                 return attribute_targets;
3761                         }
3762                 }
3763
3764                 #region IMethodData Members
3765
3766                 public CallingConventions CallingConventions {
3767                         get {
3768                                 CallingConventions cc = Parameters.CallingConvention;
3769                                 if (Parameters.HasArglist)
3770                                         block.HasVarargs = true;
3771
3772                                 if (!IsInterface)
3773                                         if ((ModFlags & Modifiers.STATIC) == 0)
3774                                                 cc |= CallingConventions.HasThis;
3775
3776                                 // FIXME: How is `ExplicitThis' used in C#?
3777                         
3778                                 return cc;
3779                         }
3780                 }
3781
3782                 public Type ReturnType {
3783                         get {
3784                                 return MemberType;
3785                         }
3786                 }
3787
3788                 public MemberName MethodName {
3789                         get {
3790                                 return MemberName;
3791                         }
3792                 }
3793
3794                 public new Location Location {
3795                         get {
3796                                 return base.Location;
3797                         }
3798                 }
3799
3800                 protected override bool CheckBase() {
3801                         if (!base.CheckBase ())
3802                                 return false;
3803
3804                         // TODO: Destructor should derive from MethodCore
3805                         if (base_method != null && (ModFlags & Modifiers.OVERRIDE) != 0 && Name == "Finalize" &&
3806                                 base_method.DeclaringType == TypeManager.object_type && !(this is Destructor)) {
3807                                 Report.Error (249, Location, "Do not override object.Finalize. Instead, provide a destructor");
3808                                 return false;
3809                         }
3810
3811                         return true;
3812                 }
3813
3814                 /// <summary>
3815                 /// Returns true if method has conditional attribute and the conditions is not defined (method is excluded).
3816                 /// </summary>
3817                 public bool IsExcluded () {
3818                         if ((caching_flags & Flags.Excluded_Undetected) == 0)
3819                                 return (caching_flags & Flags.Excluded) != 0;
3820
3821                         caching_flags &= ~Flags.Excluded_Undetected;
3822
3823                         if (base_method == null) {
3824                                 if (OptAttributes == null)
3825                                         return false;
3826
3827                                 Attribute[] attrs = OptAttributes.SearchMulti (TypeManager.conditional_attribute_type);
3828
3829                                 if (attrs == null)
3830                                         return false;
3831
3832                                 foreach (Attribute a in attrs) {
3833                                         string condition = a.GetConditionalAttributeValue ();
3834                                         if (condition == null)
3835                                                 return false;
3836
3837                                         if (RootContext.AllDefines.Contains (condition))
3838                                                 return false;
3839                                 }
3840
3841                                 caching_flags |= Flags.Excluded;
3842                                 return true;
3843                         }
3844
3845                         IMethodData md = TypeManager.GetMethod (base_method);
3846                         if (md == null) {
3847                                 if (AttributeTester.IsConditionalMethodExcluded (base_method)) {
3848                                         caching_flags |= Flags.Excluded;
3849                                         return true;
3850                                 }
3851                                 return false;
3852                         }
3853
3854                         if (md.IsExcluded ()) {
3855                                 caching_flags |= Flags.Excluded;
3856                                 return true;
3857                         }
3858                         return false;
3859                 }
3860
3861                 GenericMethod IMethodData.GenericMethod {
3862                         get {
3863                                 return GenericMethod;
3864                         }
3865                 }
3866
3867                 #endregion
3868
3869         }
3870
3871         public class SourceMethod : ISourceMethod
3872         {
3873                 DeclSpace parent;
3874                 MethodBase builder;
3875
3876                 protected SourceMethod (DeclSpace parent, MethodBase builder,
3877                                         ISourceFile file, Location start, Location end)
3878                 {
3879                         this.parent = parent;
3880                         this.builder = builder;
3881                         
3882                         CodeGen.SymbolWriter.OpenMethod (file, this, start.Row, start.Column, end.Row, start.Column);
3883                 }
3884
3885                 public string Name {
3886                         get { return builder.Name; }
3887                 }
3888
3889                 public int NamespaceID {
3890                         get { return parent.NamespaceEntry.SymbolFileID; }
3891                 }
3892
3893                 public int Token {
3894                         get {
3895                                 if (builder is MethodBuilder)
3896                                         return ((MethodBuilder) builder).GetToken ().Token;
3897                                 else if (builder is ConstructorBuilder)
3898                                         return ((ConstructorBuilder) builder).GetToken ().Token;
3899                                 else
3900                                         throw new NotSupportedException ();
3901                         }
3902                 }
3903
3904                 public void CloseMethod ()
3905                 {
3906                         if (CodeGen.SymbolWriter != null)
3907                                 CodeGen.SymbolWriter.CloseMethod ();
3908                 }
3909
3910                 public static SourceMethod Create (DeclSpace parent, MethodBase builder, Block block)
3911                 {
3912                         if (CodeGen.SymbolWriter == null)
3913                                 return null;
3914                         if (block == null)
3915                                 return null;
3916
3917                         Location start_loc = block.StartLocation;
3918                         if (start_loc.IsNull)
3919                                 return null;
3920
3921                         Location end_loc = block.EndLocation;
3922                         if (end_loc.IsNull)
3923                                 return null;
3924
3925                         ISourceFile file = start_loc.SourceFile;
3926                         if (file == null)
3927                                 return null;
3928
3929                         return new SourceMethod (
3930                                 parent, builder, file, start_loc, end_loc);
3931                 }
3932         }
3933
3934         public class Method : MethodOrOperator, IIteratorContainer {
3935
3936                 /// <summary>
3937                 ///   Modifiers allowed in a class declaration
3938                 /// </summary>
3939                 const int AllowedModifiers =
3940                         Modifiers.NEW |
3941                         Modifiers.PUBLIC |
3942                         Modifiers.PROTECTED |
3943                         Modifiers.INTERNAL |
3944                         Modifiers.PRIVATE |
3945                         Modifiers.STATIC |
3946                         Modifiers.VIRTUAL |
3947                         Modifiers.SEALED |
3948                         Modifiers.OVERRIDE |
3949                         Modifiers.ABSTRACT |
3950                         Modifiers.UNSAFE |
3951                         Modifiers.METHOD_YIELDS | 
3952                         Modifiers.EXTERN;
3953
3954                 const int AllowedInterfaceModifiers =
3955                         Modifiers.NEW | Modifiers.UNSAFE;
3956
3957                 //
3958                 // return_type can be "null" for VOID values.
3959                 //
3960                 public Method (DeclSpace parent, GenericMethod generic,
3961                                Expression return_type, int mod, bool is_iface,
3962                                MemberName name, Parameters parameters, Attributes attrs)
3963                         : base (parent, generic, return_type, mod,
3964                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
3965                                 is_iface, name, attrs, parameters)
3966                 {
3967                 }
3968                 
3969                 public override string GetSignatureForError()
3970                 {
3971                         return base.GetSignatureForError () + Parameters.GetSignatureForError ();
3972                 }
3973
3974                 void Error_DuplicateEntryPoint (MethodInfo b, Location location)
3975                 {
3976                         Report.Error (17, location,
3977                                 "Program `{0}' has more than one entry point defined: `{1}'",
3978                                 CodeGen.FileName, TypeManager.CSharpSignature(b));
3979                 }
3980
3981                 bool IsEntryPoint (MethodBuilder b, Parameters pinfo)
3982                 {
3983                         if (b.ReturnType != TypeManager.void_type &&
3984                             b.ReturnType != TypeManager.int32_type)
3985                                 return false;
3986
3987                         if (pinfo.Count == 0)
3988                                 return true;
3989
3990                         if (pinfo.Count > 1)
3991                                 return false;
3992
3993                         Type t = pinfo.ParameterType(0);
3994                         if (t.IsArray &&
3995                             (t.GetArrayRank() == 1) &&
3996                             (TypeManager.GetElementType(t) == TypeManager.string_type) &&
3997                             (pinfo.ParameterModifier(0) == Parameter.Modifier.NONE))
3998                                 return true;
3999                         else
4000                                 return false;
4001                 }
4002
4003                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
4004                 {
4005                         if (a.Type == TypeManager.conditional_attribute_type) {
4006                                 if (IsExplicitImpl) {
4007                                         Error_ConditionalAttributeIsNotValid ();
4008                                         return;
4009                                 }
4010
4011                                 if (ReturnType != TypeManager.void_type) {
4012                                         Report.Error (578, Location, "Conditional not valid on `{0}' because its return type is not void", GetSignatureForError ());
4013                                         return;
4014                                 }
4015
4016                                 if ((ModFlags & Modifiers.OVERRIDE) != 0) {
4017                                         Report.Error (243, Location, "Conditional not valid on `{0}' because it is an override method", GetSignatureForError ());
4018                                         return;
4019                                 }
4020
4021                                 if (IsInterface) {
4022                                         Report.Error (582, Location, "Conditional not valid on interface members");
4023                                         return;
4024                                 }
4025
4026                                 if (MethodData.implementing != null) {
4027                                         Report.Error (629, Location, "Conditional member `{0}' cannot implement interface member `{1}'",
4028                                                 GetSignatureForError (), TypeManager.CSharpSignature (MethodData.implementing));
4029                                         return;
4030                                 }
4031
4032                                 for (int i = 0; i < ParameterInfo.Count; ++i) {
4033                                         if ((ParameterInfo.ParameterModifier (i) & Parameter.Modifier.OUTMASK) != 0) {
4034                                                 Report.Error (685, Location, "Conditional method `{0}' cannot have an out parameter", GetSignatureForError ());
4035                                                 return;
4036                                         }
4037                                 }
4038                         }
4039
4040                         base.ApplyAttributeBuilder (a, cb);
4041                 }
4042
4043                 protected override bool CheckForDuplications ()
4044                 {
4045                         ArrayList ar = ParentContainer.Methods;
4046                         if (ar != null) {
4047                                 int arLen = ar.Count;
4048                                         
4049                                 for (int i = 0; i < arLen; i++) {
4050                                         Method m = (Method) ar [i];
4051                                         if (IsDuplicateImplementation (m))
4052                                                 return false;
4053                                 }
4054                         }
4055
4056                         ar = ParentContainer.Properties;
4057                         if (ar != null) {
4058                                 for (int i = 0; i < ar.Count; ++i) {
4059                                         PropertyBase pb = (PropertyBase) ar [i];
4060                                         if (pb.AreAccessorsDuplicateImplementation (this))
4061                                                 return false;
4062                                 }
4063                         }
4064
4065                         ar = ParentContainer.Indexers;
4066                         if (ar != null) {
4067                                 for (int i = 0; i < ar.Count; ++i) {
4068                                         PropertyBase pb = (PropertyBase) ar [i];
4069                                         if (pb.AreAccessorsDuplicateImplementation (this))
4070                                                 return false;
4071                                 }
4072                         }
4073
4074                         ar = ParentContainer.Events;
4075                         if (ar != null) {
4076                                 for (int i = 0; i < ar.Count; ++i) {
4077                                         Event ev = (Event) ar [i];
4078                                         if (ev.AreAccessorsDuplicateImplementation (this))
4079                                                 return false;
4080                                 }
4081                         }
4082
4083                         return true;
4084                 }
4085
4086                 //
4087                 // Creates the type
4088                 //
4089                 public override bool Define ()
4090                 {
4091                         if (!base.Define ())
4092                                 return false;
4093
4094                         if (RootContext.StdLib && (ReturnType == TypeManager.arg_iterator_type || ReturnType == TypeManager.typed_reference_type)) {
4095                                 Error1599 (Location, ReturnType);
4096                                 return false;
4097                         }
4098
4099                         if (ReturnType == TypeManager.void_type && ParameterTypes.Length == 0 && 
4100                                 Name == "Finalize" && !(this is Destructor)) {
4101                                 Report.Warning (465, 1, Location, "Introducing a 'Finalize' method can interfere with destructor invocation. Did you intend to declare a destructor?");
4102                         }
4103
4104                         //
4105                         // Setup iterator if we are one
4106                         //
4107                         if ((ModFlags & Modifiers.METHOD_YIELDS) != 0){
4108                                 Iterator iterator = new Iterator (
4109                                         this, Parent, GenericMethod, ModFlags);
4110
4111                                 if (!iterator.DefineIterator ())
4112                                         return false;
4113                         }
4114
4115                         //
4116                         // This is used to track the Entry Point,
4117                         //
4118                         if (Name == "Main" &&
4119                                 ((ModFlags & Modifiers.STATIC) != 0) && RootContext.NeedsEntryPoint && 
4120                                 (RootContext.MainClass == null ||
4121                                 RootContext.MainClass == Parent.TypeBuilder.FullName)){
4122                                 if (IsEntryPoint (MethodBuilder, ParameterInfo)) {
4123                                         IMethodData md = TypeManager.GetMethod (MethodBuilder);
4124                                         md.SetMemberIsUsed ();
4125
4126                                         if (RootContext.EntryPoint == null) {
4127                                                 if (Parent.IsGeneric){
4128                                                         Report.Error (-201, Location,
4129                                                                       "Entry point can not be defined in a generic class");
4130                                                 }
4131
4132                                                 RootContext.EntryPoint = MethodBuilder;
4133                                                 RootContext.EntryPointLocation = Location;
4134                                         } else {
4135                                                 Error_DuplicateEntryPoint (RootContext.EntryPoint, RootContext.EntryPointLocation);
4136                                                 Error_DuplicateEntryPoint (MethodBuilder, Location);
4137                                         }
4138                                 } else {
4139                                         if (RootContext.WarningLevel >= 4)
4140                                                 Report.Warning (28, 4, Location, "`{0}' has the wrong signature to be an entry point", TypeManager.CSharpSignature(MethodBuilder));
4141                                 }
4142                         }
4143
4144                         return true;
4145                 }
4146
4147                 //
4148                 // Emits the code
4149                 // 
4150                 public override void Emit ()
4151                 {
4152                         MethodData.Emit (Parent);
4153                         base.Emit ();
4154
4155                         Block = null;
4156                         MethodData = null;
4157                 }
4158
4159                 public static void Error1599 (Location loc, Type t)
4160                 {
4161                         Report.Error (1599, loc, "Method or delegate cannot return type `{0}'", TypeManager.CSharpName (t));
4162                 }
4163
4164                 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
4165                 {
4166                         MethodInfo mi = (MethodInfo) ParentContainer.BaseCache.FindMemberToOverride (
4167                                 Parent.TypeBuilder, Name, ParameterTypes, GenericMethod, false);
4168
4169                         if (mi == null)
4170                                 return null;
4171
4172                         base_ret_type = mi.ReturnType;
4173                         return mi;
4174                 }
4175
4176                 protected override bool VerifyClsCompliance ()
4177                 {
4178                         if (!base.VerifyClsCompliance ())
4179                                 return false;
4180
4181                         if (ParameterInfo.Count > 0) {
4182                                 ArrayList al = (ArrayList)ParentContainer.MemberCache.Members [Name];
4183                                 if (al.Count > 1)
4184                                         MemberCache.VerifyClsParameterConflict (al, this, MethodBuilder);
4185                         }
4186
4187                         return true;
4188                 }
4189         }
4190
4191         public abstract class ConstructorInitializer {
4192                 ArrayList argument_list;
4193                 protected ConstructorInfo base_constructor;
4194                 Location loc;
4195                 
4196                 public ConstructorInitializer (ArrayList argument_list, Location loc)
4197                 {
4198                         this.argument_list = argument_list;
4199                         this.loc = loc;
4200                 }
4201
4202                 public ArrayList Arguments {
4203                         get {
4204                                 return argument_list;
4205                         }
4206                 }
4207
4208                 public bool Resolve (ConstructorBuilder caller_builder, Block block, EmitContext ec)
4209                 {
4210                         Expression base_constructor_group;
4211                         Type t;
4212                         bool error = false;
4213
4214                         ec.CurrentBlock = block;
4215
4216                         if (argument_list != null){
4217                                 foreach (Argument a in argument_list){
4218                                         if (!a.Resolve (ec, loc))
4219                                                 return false;
4220                                 }
4221                         }
4222                         ec.CurrentBlock = null;
4223
4224                         if (this is ConstructorBaseInitializer) {
4225                                 if (ec.ContainerType.BaseType == null)
4226                                         return true;
4227
4228                                 t = ec.ContainerType.BaseType;
4229                                 if (ec.ContainerType.IsValueType) {
4230                                         Report.Error (522, loc,
4231                                                 "`{0}': Struct constructors cannot call base constructors", TypeManager.CSharpSignature (caller_builder));
4232                                         return false;
4233                                 }
4234                         } else
4235                                 t = ec.ContainerType;
4236
4237                         base_constructor_group = Expression.MemberLookup (
4238                                 ec.ContainerType, t, ".ctor", MemberTypes.Constructor,
4239                                 BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
4240                                 loc);
4241                         
4242                         if (base_constructor_group == null){
4243                                 error = true;
4244                                 base_constructor_group = Expression.MemberLookup (
4245                                         t, null, t, ".ctor", MemberTypes.Constructor,
4246                                         BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly,
4247                                         loc);
4248                         }
4249
4250                         int errors = Report.Errors;
4251                         if (base_constructor_group != null)
4252                                 base_constructor = (ConstructorInfo) Invocation.OverloadResolve (
4253                                         ec, (MethodGroupExpr) base_constructor_group, argument_list,
4254                                         false, loc);
4255                         
4256                         if (base_constructor == null) {
4257                                 if (errors == Report.Errors)
4258                                         Invocation.Error_WrongNumArguments (loc, TypeManager.CSharpSignature (caller_builder),
4259                                                 argument_list == null ? 0 : argument_list.Count);
4260                                 return false;
4261                         }
4262
4263                         if (error) {
4264                                 Expression.ErrorIsInaccesible (loc, TypeManager.CSharpSignature (base_constructor));
4265                                 base_constructor = null;
4266                                 return false;
4267                         }
4268                         
4269                         if (base_constructor == caller_builder){
4270                                 Report.Error (516, loc, "Constructor `{0}' cannot call itself", TypeManager.CSharpSignature (caller_builder));
4271                                 return false;
4272                         }
4273                         
4274                         return true;
4275                 }
4276
4277                 public virtual void Emit (EmitContext ec)
4278                 {
4279                         if (base_constructor != null){
4280                                 ec.Mark (loc, false);
4281                                 if (ec.IsStatic)
4282                                         Invocation.EmitCall (ec, true, true, null, base_constructor, argument_list, loc);
4283                                 else
4284                                         Invocation.EmitCall (ec, true, false, ec.GetThis (loc), base_constructor, argument_list, loc);
4285                         }
4286                 }
4287         }
4288
4289         public class ConstructorBaseInitializer : ConstructorInitializer {
4290                 public ConstructorBaseInitializer (ArrayList argument_list, Location l) :
4291                         base (argument_list, l)
4292                 {
4293                 }
4294         }
4295
4296         class GeneratedBaseInitializer: ConstructorBaseInitializer {
4297                 public GeneratedBaseInitializer (Location loc):
4298                         base (null, loc)
4299                 {
4300                 }
4301         }
4302
4303         public class ConstructorThisInitializer : ConstructorInitializer {
4304                 public ConstructorThisInitializer (ArrayList argument_list, Location l) :
4305                         base (argument_list, l)
4306                 {
4307                 }
4308         }
4309         
4310         public class Constructor : MethodCore, IMethodData {
4311                 public ConstructorBuilder ConstructorBuilder;
4312                 public ConstructorInitializer Initializer;
4313                 ListDictionary declarative_security;
4314
4315                 // <summary>
4316                 //   Modifiers allowed for a constructor.
4317                 // </summary>
4318                 public const int AllowedModifiers =
4319                         Modifiers.PUBLIC |
4320                         Modifiers.PROTECTED |
4321                         Modifiers.INTERNAL |
4322                         Modifiers.STATIC |
4323                         Modifiers.UNSAFE |
4324                         Modifiers.EXTERN |              
4325                         Modifiers.PRIVATE;
4326
4327                 static string[] attribute_targets = new string [] { "method" };
4328
4329                 bool has_compliant_args = false;
4330                 //
4331                 // The spec claims that static is not permitted, but
4332                 // my very own code has static constructors.
4333                 //
4334                 public Constructor (DeclSpace parent, string name, int mod, Parameters args,
4335                                     ConstructorInitializer init, Location loc)
4336                         : base (parent, null, null, mod, AllowedModifiers, false,
4337                                 new MemberName (name, loc), null, args)
4338                 {
4339                         Initializer = init;
4340                 }
4341
4342                 public bool HasCompliantArgs {
4343                         get { return has_compliant_args; }
4344                 }
4345
4346                 public override AttributeTargets AttributeTargets {
4347                         get { return AttributeTargets.Constructor; }
4348                 }
4349
4350
4351                 //
4352                 // Returns true if this is a default constructor
4353                 //
4354                 public bool IsDefault ()
4355                 {
4356                         if ((ModFlags & Modifiers.STATIC) != 0)
4357                                 return Parameters.Empty;
4358                         
4359                         return Parameters.Empty &&
4360                                         (Initializer is ConstructorBaseInitializer) &&
4361                                         (Initializer.Arguments == null);
4362                 }
4363
4364                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
4365                 {
4366                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
4367                                 if (declarative_security == null) {
4368                                         declarative_security = new ListDictionary ();
4369                                 }
4370                                 a.ExtractSecurityPermissionSet (declarative_security);
4371                                 return;
4372                         }
4373
4374                         if (a.Type == TypeManager.methodimpl_attr_type &&
4375                                 (a.GetMethodImplOptions () & MethodImplOptions.InternalCall) != 0) {
4376                                 ConstructorBuilder.SetImplementationFlags (MethodImplAttributes.InternalCall | MethodImplAttributes.Runtime);
4377                         }
4378
4379                         ConstructorBuilder.SetCustomAttribute (cb);
4380                 }
4381
4382                 protected override bool CheckForDuplications ()
4383                 {
4384                         ArrayList ar = ParentContainer.InstanceConstructors;
4385                         if (ar != null) {
4386                                 int arLen = ar.Count;
4387                                         
4388                                 for (int i = 0; i < arLen; i++) {
4389                                         Constructor m = (Constructor) ar [i];
4390                                         if (IsDuplicateImplementation (m))
4391                                                 return false;
4392                                 }
4393                         }
4394                         return true;
4395                 }
4396                         
4397                 protected override bool CheckBase ()
4398                 {
4399                         if ((ModFlags & Modifiers.STATIC) != 0) {
4400                                 if (!Parameters.Empty) {
4401                                         Report.Error (132, Location, "`{0}': The static constructor must be parameterless",
4402                                                 GetSignatureForError ());
4403                                         return false;
4404                                 }
4405
4406                                 // the rest can be ignored
4407                                 return true;
4408                         }
4409
4410                         // Check whether arguments were correct.
4411                         if (!DoDefineParameters ())
4412                                 return false;
4413                         
4414                         if (!CheckForDuplications ())
4415                                 return false;
4416
4417                         if (ParentContainer.Kind == Kind.Struct) {
4418                                 if (ParameterTypes.Length == 0) {
4419                                         Report.Error (568, Location, 
4420                                                 "Structs cannot contain explicit parameterless constructors");
4421                                         return false;
4422                                 }
4423
4424                                 if ((ModFlags & Modifiers.PROTECTED) != 0) {
4425                                         Report.Error (666, Location, "`{0}': new protected member declared in struct", GetSignatureForError ());
4426                                                 return false;
4427                                 }
4428                         }
4429                         
4430                         if ((RootContext.WarningLevel >= 4) && ((Parent.ModFlags & Modifiers.SEALED) != 0 && (ModFlags & Modifiers.PROTECTED) != 0)) {
4431                                 Report.Warning (628, 4, Location, "`{0}': new protected member declared in sealed class", GetSignatureForError ());
4432                         }
4433
4434                         return true;
4435                 }
4436                 
4437                 //
4438                 // Creates the ConstructorBuilder
4439                 //
4440                 public override bool Define ()
4441                 {
4442                         if (ConstructorBuilder != null)
4443                                 return true;
4444
4445                         MethodAttributes ca = (MethodAttributes.RTSpecialName |
4446                                                MethodAttributes.SpecialName);
4447
4448                         if ((ModFlags & Modifiers.STATIC) != 0){
4449                                 ca |= MethodAttributes.Static | MethodAttributes.Private;
4450                         } else {
4451                                 ca |= MethodAttributes.HideBySig;
4452
4453                                 if ((ModFlags & Modifiers.PUBLIC) != 0)
4454                                         ca |= MethodAttributes.Public;
4455                                 else if ((ModFlags & Modifiers.PROTECTED) != 0){
4456                                         if ((ModFlags & Modifiers.INTERNAL) != 0)
4457                                                 ca |= MethodAttributes.FamORAssem;
4458                                         else 
4459                                                 ca |= MethodAttributes.Family;
4460                                 } else if ((ModFlags & Modifiers.INTERNAL) != 0)
4461                                         ca |= MethodAttributes.Assembly;
4462                                 else
4463                                         ca |= MethodAttributes.Private;
4464                         }
4465
4466                         if (!CheckAbstractAndExtern (block != null))
4467                                 return false;
4468                         
4469                         // Check if arguments were correct.
4470                         if (!CheckBase ())
4471                                 return false;
4472
4473                         ConstructorBuilder = Parent.TypeBuilder.DefineConstructor (
4474                                 ca, CallingConventions,
4475                                 ParameterTypes);
4476
4477                         if ((ModFlags & Modifiers.UNSAFE) != 0)
4478                                 ConstructorBuilder.InitLocals = false;
4479
4480                         if (ParentContainer.IsComImport) {
4481                                 if (!IsDefault ()) {
4482                                         Report.Error (669, Location, "`{0}': A class with the ComImport attribute cannot have a user-defined constructor",
4483                                                 Parent.GetSignatureForError ());
4484                                         return false;
4485                                 }
4486                                 ConstructorBuilder.SetImplementationFlags (MethodImplAttributes.InternalCall);
4487                         }
4488
4489                         TypeManager.AddMethod (ConstructorBuilder, this);
4490
4491                         return true;
4492                 }
4493
4494                 //
4495                 // Emits the code
4496                 //
4497                 public override void Emit ()
4498                 {
4499                         if (OptAttributes != null)
4500                                 OptAttributes.Emit ();
4501
4502                         EmitContext ec = CreateEmitContext (null, null);
4503
4504                         if (block != null) {
4505                                 // If this is a non-static `struct' constructor and doesn't have any
4506                                 // initializer, it must initialize all of the struct's fields.
4507                                 if ((ParentContainer.Kind == Kind.Struct) &&
4508                                         ((ModFlags & Modifiers.STATIC) == 0) && (Initializer == null))
4509                                         block.AddThisVariable (Parent, Location);
4510
4511                                 if (!block.ResolveMeta (ec, ParameterInfo))
4512                                         block = null;
4513                         }
4514
4515                         if ((ModFlags & Modifiers.STATIC) == 0){
4516                                 if (ParentContainer.Kind == Kind.Class && Initializer == null)
4517                                         Initializer = new GeneratedBaseInitializer (Location);
4518
4519
4520                                 //
4521                                 // Spec mandates that Initializers will not have
4522                                 // `this' access
4523                                 //
4524                                 ec.IsStatic = true;
4525                                 if ((Initializer != null) &&
4526                                     !Initializer.Resolve (ConstructorBuilder, block, ec))
4527                                         return;
4528                                 ec.IsStatic = false;
4529                         }
4530
4531                         Parameters.ApplyAttributes (ConstructorBuilder);
4532                         
4533                         SourceMethod source = SourceMethod.Create (
4534                                 Parent, ConstructorBuilder, block);
4535
4536                         //
4537                         // Classes can have base initializers and instance field initializers.
4538                         //
4539                         if (ParentContainer.Kind == Kind.Class){
4540                                 if ((ModFlags & Modifiers.STATIC) == 0){
4541
4542                                         //
4543                                         // If we use a "this (...)" constructor initializer, then
4544                                         // do not emit field initializers, they are initialized in the other constructor
4545                                         //
4546                                         if (!(Initializer != null && Initializer is ConstructorThisInitializer))
4547                                                 ParentContainer.EmitFieldInitializers (ec);
4548                                 }
4549                         }
4550                         if (Initializer != null) {
4551                                 Initializer.Emit (ec);
4552                         }
4553                         
4554                         if ((ModFlags & Modifiers.STATIC) != 0)
4555                                 ParentContainer.EmitFieldInitializers (ec);
4556
4557                         ec.EmitTopBlock (this, block);
4558
4559                         if (source != null)
4560                                 source.CloseMethod ();
4561
4562                         base.Emit ();
4563
4564                         if (declarative_security != null) {
4565                                 foreach (DictionaryEntry de in declarative_security) {
4566                                         ConstructorBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
4567                                 }
4568                         }
4569
4570                         block = null;
4571                 }
4572
4573                 // Is never override
4574                 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
4575                 {
4576                         return null;
4577                 }
4578
4579                 public override string GetSignatureForError()
4580                 {
4581                         return base.GetSignatureForError () + Parameters.GetSignatureForError ();
4582                 }
4583
4584                 public override string[] ValidAttributeTargets {
4585                         get {
4586                                 return attribute_targets;
4587                         }
4588                 }
4589
4590                 protected override bool VerifyClsCompliance ()
4591                 {
4592                         if (!base.VerifyClsCompliance () || !IsExposedFromAssembly ()) {
4593                                 return false;
4594                         }
4595                         
4596                         if (ParameterInfo.Count > 0) {
4597                                 ArrayList al = (ArrayList)Parent.MemberCache.Members [".ctor"];
4598                                 if (al.Count > 3)
4599                                         MemberCache.VerifyClsParameterConflict (al, this, ConstructorBuilder);
4600  
4601                                 if (Parent.TypeBuilder.IsSubclassOf (TypeManager.attribute_type)) {
4602                                         foreach (Type param in ParameterTypes) {
4603                                                 if (param.IsArray) {
4604                                                         return true;
4605                                                 }
4606                                         }
4607                                 }
4608                         }
4609                         has_compliant_args = true;
4610                         return true;
4611                 }
4612
4613                 #region IMethodData Members
4614
4615                 public System.Reflection.CallingConventions CallingConventions {
4616                         get {
4617                                 CallingConventions cc = Parameters.CallingConvention;
4618
4619                                 if (ParentContainer.Kind == Kind.Class)
4620                                         if ((ModFlags & Modifiers.STATIC) == 0)
4621                                                 cc |= CallingConventions.HasThis;
4622
4623                                 // FIXME: How is `ExplicitThis' used in C#?
4624                         
4625                                 return cc;
4626                                 }
4627                         }
4628                         
4629                 public new Location Location {
4630                         get {
4631                                 return base.Location;
4632                         }
4633                 }
4634
4635                 public MemberName MethodName {
4636                         get {
4637                                 return MemberName;
4638                         }
4639                 }
4640                         
4641                 public Type ReturnType {
4642                         get {
4643                                 return MemberType;
4644                         }
4645                 }
4646
4647                 public EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig)
4648                 {
4649                         ILGenerator ig_ = ConstructorBuilder.GetILGenerator ();
4650                         return new EmitContext (this, Parent, Location, ig_, null, ModFlags, true);
4651                 }
4652
4653                 public bool IsExcluded()
4654                 {
4655                         return false;
4656                 }
4657
4658                 GenericMethod IMethodData.GenericMethod {
4659                         get {
4660                                 return null;
4661                         }
4662                 }
4663
4664                 #endregion
4665         }
4666
4667         /// <summary>
4668         /// Interface for MethodData class. Holds links to parent members to avoid member duplication.
4669         /// </summary>
4670         public interface IMethodData
4671         {
4672                 CallingConventions CallingConventions { get; }
4673                 Location Location { get; }
4674                 MemberName MethodName { get; }
4675                 Type ReturnType { get; }
4676                 GenericMethod GenericMethod { get; }
4677                 Parameters ParameterInfo { get; }
4678
4679                 Attributes OptAttributes { get; }
4680                 ToplevelBlock Block { get; set; }
4681
4682                 EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig);
4683                 ObsoleteAttribute GetObsoleteAttribute ();
4684                 string GetSignatureForError ();
4685                 bool IsExcluded ();
4686                 bool IsClsComplianceRequired ();
4687                 void SetMemberIsUsed ();
4688         }
4689
4690         //
4691         // Encapsulates most of the Method's state
4692         //
4693         public class MethodData {
4694
4695                 readonly IMethodData method;
4696
4697                 public readonly GenericMethod GenericMethod;
4698
4699                 //
4700                 // Are we implementing an interface ?
4701                 //
4702                 public MethodInfo implementing;
4703
4704                 //
4705                 // Protected data.
4706                 //
4707                 protected MemberBase member;
4708                 protected int modifiers;
4709                 protected MethodAttributes flags;
4710                 protected Type declaring_type;
4711                 protected MethodInfo parent_method;
4712
4713                 MethodBuilder builder = null;
4714                 public MethodBuilder MethodBuilder {
4715                         get {
4716                                 return builder;
4717                         }
4718                 }
4719
4720                 public Type DeclaringType {
4721                         get {
4722                                 return declaring_type;
4723                         }
4724                 }
4725
4726                 public MethodData (MemberBase member,
4727                                    int modifiers, MethodAttributes flags, IMethodData method)
4728                 {
4729                         this.member = member;
4730                         this.modifiers = modifiers;
4731                         this.flags = flags;
4732
4733                         this.method = method;
4734                 }
4735
4736                 public MethodData (MemberBase member, 
4737                                    int modifiers, MethodAttributes flags, 
4738                                    IMethodData method, MethodBuilder builder,
4739                                    GenericMethod generic, MethodInfo parent_method)
4740                         : this (member, modifiers, flags, method)
4741                 {
4742                         this.builder = builder;
4743                         this.GenericMethod = generic;
4744                         this.parent_method = parent_method;
4745                 }
4746
4747                 public bool Define (DeclSpace parent)
4748                 {
4749                         string name = method.MethodName.Basename;
4750                         string method_name = method.MethodName.FullName;
4751
4752                         TypeContainer container = ((TypeContainer) parent).PartialContainer;
4753
4754                         PendingImplementation pending = container.PendingImplementations;
4755                         if (pending != null){
4756                                 if (member is Indexer) // TODO: test it, but it should work without this IF
4757                                         implementing = pending.IsInterfaceIndexer (
4758                                                 member.InterfaceType, method.ReturnType, method.ParameterInfo);
4759                                 else
4760                                         implementing = pending.IsInterfaceMethod (
4761                                                 member.InterfaceType, name, method.ReturnType, method.ParameterInfo);
4762
4763                                 if (member.InterfaceType != null){
4764                                         if (implementing == null){
4765                                                 if (member is PropertyBase) {
4766                                                         Report.Error (550, method.Location, "`{0}' is an accessor not found in interface member `{1}{2}'",
4767                                                                       method.GetSignatureForError (), TypeManager.CSharpName (member.InterfaceType),
4768                                                                       member.GetSignatureForError ().Substring (member.GetSignatureForError ().LastIndexOf ('.')));
4769
4770                                                 } else {
4771                                                         Report.Error (539, method.Location,
4772                                                                       "`{0}.{1}' in explicit interface declaration is not a member of interface",
4773                                                                       TypeManager.CSharpName (member.InterfaceType), member.ShortName);
4774                                                 }
4775                                                 return false;
4776                                         }
4777                                         if (implementing.IsSpecialName && !(method is AbstractPropertyEventMethod)) {
4778                                                 Report.SymbolRelatedToPreviousError (implementing);
4779                                                 Report.Error (683, method.Location, "`{0}' explicit method implementation cannot implement `{1}' because it is an accessor",
4780                                                         member.GetSignatureForError (), TypeManager.CSharpSignature (implementing));
4781                                                 return false;
4782                                         }
4783
4784                                         method_name = TypeManager.GetFullName (member.InterfaceType) +
4785                                                 '.' + method_name;
4786                                 } else {
4787                                         if (implementing != null) {
4788                                                 AbstractPropertyEventMethod prop_method = method as AbstractPropertyEventMethod;
4789                                                 if (prop_method != null) {
4790                                                         if (!implementing.IsSpecialName) {
4791                                                                 Report.SymbolRelatedToPreviousError (implementing);
4792                                                                 Report.Error (686, method.Location, "Accessor `{0}' cannot implement interface member `{1}' for type `{2}'. Use an explicit interface implementation",
4793                                                                         method.GetSignatureForError (), TypeManager.CSharpSignature (implementing), container.GetSignatureForError ());
4794                                                                 return false;
4795                                                         }
4796                                                         PropertyBase.PropertyMethod pm = prop_method as PropertyBase.PropertyMethod;
4797                                                         if (pm != null && pm.HasCustomAccessModifier && (pm.ModFlags & Modifiers.PUBLIC) == 0) {
4798                                                                 Report.SymbolRelatedToPreviousError (implementing);
4799                                                                 Report.Error (277, method.Location, "Accessor `{0}' must be declared public to implement interface member `{1}'",
4800                                                                         method.GetSignatureForError (), TypeManager.CSharpSignature (implementing, true));
4801                                                                 return false;
4802                                                         }
4803                                                 }
4804                                         }
4805                                 }
4806                         }
4807
4808                         //
4809                         // For implicit implementations, make sure we are public, for
4810                         // explicit implementations, make sure we are private.
4811                         //
4812                         if (implementing != null){
4813                                 //
4814                                 // Setting null inside this block will trigger a more
4815                                 // verbose error reporting for missing interface implementations
4816                                 //
4817                                 // The "candidate" function has been flagged already
4818                                 // but it wont get cleared
4819                                 //
4820                                 if (member.IsExplicitImpl){
4821                                         if ((modifiers & (Modifiers.PUBLIC | Modifiers.ABSTRACT | Modifiers.VIRTUAL)) != 0){
4822                                                 Modifiers.Error_InvalidModifier (method.Location, "public, virtual or abstract");
4823                                                 implementing = null;
4824                                         }
4825                                 } else if ((flags & MethodAttributes.MemberAccessMask) != MethodAttributes.Public){
4826                                         if (TypeManager.IsInterfaceType (implementing.DeclaringType)){
4827                                                 //
4828                                                 // If this is an interface method implementation,
4829                                                 // check for public accessibility
4830                                                 //
4831                                                 implementing = null;
4832                                         } else if ((flags & MethodAttributes.MemberAccessMask) == MethodAttributes.Private){
4833                                                 // We may never be private.
4834                                                 implementing = null;
4835                                         } else if ((modifiers & Modifiers.OVERRIDE) == 0){
4836                                                 //
4837                                                 // We may be protected if we're overriding something.
4838                                                 //
4839                                                 implementing = null;
4840                                         }
4841                                 } 
4842                                         
4843                                 //
4844                                 // Static is not allowed
4845                                 //
4846                                 if ((modifiers & Modifiers.STATIC) != 0){
4847                                         implementing = null;
4848                                 }
4849                         }
4850                         
4851                         //
4852                         // If implementing is still valid, set flags
4853                         //
4854                         if (implementing != null){
4855                                 //
4856                                 // When implementing interface methods, set NewSlot
4857                                 // unless, we are overwriting a method.
4858                                 //
4859                                 if (implementing.DeclaringType.IsInterface){
4860                                         if ((modifiers & Modifiers.OVERRIDE) == 0)
4861                                                 flags |= MethodAttributes.NewSlot;
4862                                 }
4863                                 flags |=
4864                                         MethodAttributes.Virtual |
4865                                         MethodAttributes.HideBySig;
4866
4867                                 // Set Final unless we're virtual, abstract or already overriding a method.
4868                                 if ((modifiers & (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE)) == 0)
4869                                         flags |= MethodAttributes.Final;
4870                         }
4871
4872                         EmitContext ec = method.CreateEmitContext (container, null);
4873
4874                         DefineMethodBuilder (container, method_name, method.ParameterInfo.Types);
4875
4876                         if (builder == null)
4877                                 return false;
4878
4879                         if (container.CurrentType != null)
4880                                 declaring_type = container.CurrentType;
4881                         else
4882                                 declaring_type = container.TypeBuilder;
4883
4884                         if ((modifiers & Modifiers.UNSAFE) != 0)
4885                                 builder.InitLocals = false;
4886
4887                         if (implementing != null){
4888                                 //
4889                                 // clear the pending implemntation flag
4890                                 //
4891                                 if (member is Indexer) {
4892                                         pending.ImplementIndexer (
4893                                                 member.InterfaceType, builder, method.ReturnType,
4894                                                 method.ParameterInfo, member.IsExplicitImpl);
4895                                 } else
4896                                         pending.ImplementMethod (
4897                                                 member.InterfaceType, name, method.ReturnType,
4898                                                 method.ParameterInfo, member.IsExplicitImpl);
4899
4900                                 if (member.IsExplicitImpl)
4901                                         container.TypeBuilder.DefineMethodOverride (
4902                                                 builder, implementing);
4903
4904                         }
4905
4906                         TypeManager.AddMethod (builder, method);
4907
4908                         if (GenericMethod != null) {
4909                                 bool is_override = member.IsExplicitImpl |
4910                                         ((modifiers & Modifiers.OVERRIDE) != 0);
4911
4912                                 if (implementing != null)
4913                                         parent_method = implementing;
4914
4915                                 if (!GenericMethod.DefineType (ec, builder, parent_method, is_override))
4916                                         return false;
4917                         }
4918
4919                         return true;
4920                 }
4921
4922
4923                 /// <summary>
4924                 /// Create the MethodBuilder for the method 
4925                 /// </summary>
4926                 void DefineMethodBuilder (TypeContainer container, string method_name, Type[] ParameterTypes)
4927                 {
4928                         const int extern_static = Modifiers.EXTERN | Modifiers.STATIC;
4929
4930                         if ((modifiers & extern_static) == extern_static) {
4931
4932                                 if (method.OptAttributes != null) {
4933                                         Attribute dllimport_attribute = method.OptAttributes.Search (TypeManager.dllimport_type);
4934                                         if (dllimport_attribute != null) {
4935                                                 flags |= MethodAttributes.PinvokeImpl;
4936                                                 builder = dllimport_attribute.DefinePInvokeMethod (
4937                                                         container.TypeBuilder, method_name, flags,
4938                                                         method.ReturnType, ParameterTypes);
4939
4940                                                 return;
4941                                         }
4942                                 }
4943
4944                                 // for extern static method must be specified either DllImport attribute or MethodImplAttribute.
4945                                 // We are more strict than Microsoft and report CS0626 like error
4946                                 if (method.OptAttributes == null ||
4947                                         !method.OptAttributes.Contains (TypeManager.methodimpl_attr_type)) {
4948                                         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",
4949                                                 method.GetSignatureForError ());
4950                                         return;
4951                                 }
4952                         }
4953
4954                         if (builder == null) {
4955                                 builder = container.TypeBuilder.DefineMethod (
4956                                         method_name, flags, method.CallingConventions,
4957                                         method.ReturnType, ParameterTypes);
4958                                 return;
4959                         }
4960 #if !MS_COMPATIBLE
4961                                 builder.SetGenericMethodSignature (
4962                                         flags, method.CallingConventions,
4963                                         method.ReturnType, ParameterTypes);
4964 #endif
4965                 }
4966
4967                 //
4968                 // Emits the code
4969                 // 
4970                 public void Emit (DeclSpace parent)
4971                 {
4972                         EmitContext ec;
4973                         if ((flags & MethodAttributes.PinvokeImpl) == 0)
4974                                 ec = method.CreateEmitContext (parent, builder.GetILGenerator ());
4975                         else
4976                                 ec = method.CreateEmitContext (parent, null);
4977
4978                         method.ParameterInfo.ApplyAttributes (MethodBuilder);
4979
4980                         if (GenericMethod != null)
4981                                 GenericMethod.EmitAttributes ();
4982
4983                         ToplevelBlock block = method.Block;
4984                         
4985                         SourceMethod source = SourceMethod.Create (parent, MethodBuilder, method.Block);
4986
4987                         //
4988                         // Handle destructors specially
4989                         //
4990                         // FIXME: This code generates buggy code
4991                         //
4992                         if (member is Destructor)
4993                                 EmitDestructor (ec, block);
4994                         else
4995                                 ec.EmitTopBlock (method, block);
4996
4997                         if (source != null)
4998                                 source.CloseMethod ();
4999                 }
5000
5001                 void EmitDestructor (EmitContext ec, ToplevelBlock block)
5002                 {
5003                         ILGenerator ig = ec.ig;
5004                         
5005                         Label finish = ig.DefineLabel ();
5006
5007                         block.SetDestructor ();
5008                         
5009                         ig.BeginExceptionBlock ();
5010                         ec.ReturnLabel = finish;
5011                         ec.HasReturnLabel = true;
5012                         ec.EmitTopBlock (method, block);
5013                         
5014                         // ig.MarkLabel (finish);
5015                         ig.BeginFinallyBlock ();
5016                         
5017                         if (ec.ContainerType.BaseType != null) {
5018                                 Expression member_lookup = Expression.MemberLookup (
5019                                         ec.ContainerType.BaseType, null, ec.ContainerType.BaseType,
5020                                         "Finalize", MemberTypes.Method, Expression.AllBindingFlags, method.Location);
5021
5022                                 if (member_lookup != null){
5023                                         MethodGroupExpr base_destructor = ((MethodGroupExpr) member_lookup);
5024                                 
5025                                         ig.Emit (OpCodes.Ldarg_0);
5026                                         ig.Emit (OpCodes.Call, (MethodInfo) base_destructor.Methods [0]);
5027                                 }
5028                         }
5029                         
5030                         ig.EndExceptionBlock ();
5031                         //ig.MarkLabel (ec.ReturnLabel);
5032                         ig.Emit (OpCodes.Ret);
5033                 }
5034         }
5035
5036         // TODO: Should derive from MethodCore
5037         public class Destructor : Method {
5038
5039                 static string[] attribute_targets = new string [] { "method" };
5040
5041                 public Destructor (DeclSpace parent, Expression return_type, int mod,
5042                                    string name, Parameters parameters, Attributes attrs,
5043                                    Location l)
5044                         : base (parent, null, return_type, mod, false, new MemberName (name, l),
5045                                 parameters, attrs)
5046                 { }
5047
5048                 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
5049                 {
5050                         if (a.Type == TypeManager.conditional_attribute_type) {
5051                                 Error_ConditionalAttributeIsNotValid ();
5052                                 return;
5053                         }
5054
5055                         base.ApplyAttributeBuilder (a, cb);
5056                 }
5057
5058                 public override string GetSignatureForError ()
5059                 {
5060                         return Parent.GetSignatureForError () + ".~" + Parent.MemberName.Name + "()";
5061                 }
5062
5063                 public override string[] ValidAttributeTargets {
5064                         get {
5065                                 return attribute_targets;
5066                         }
5067                 }
5068         }
5069         
5070         abstract public class MemberBase : MemberCore {
5071                 public Expression Type;
5072
5073                 public MethodAttributes flags;
5074                 public readonly DeclSpace ds;
5075                 public readonly GenericMethod GenericMethod;
5076
5077                 protected readonly int explicit_mod_flags;
5078
5079                 //
5080                 // The "short" name of this property / indexer / event.  This is the
5081                 // name without the explicit interface.
5082                 //
5083                 public string ShortName {
5084                         get { return MemberName.Name; }
5085                         set { SetMemberName (new MemberName (MemberName.Left, value, Location)); }
5086                 }
5087
5088                 public TypeContainer ParentContainer {
5089                         get { return ((TypeContainer) Parent).PartialContainer; }
5090                 }
5091
5092                 //
5093                 // The type of this property / indexer / event
5094                 //
5095                 protected Type member_type;
5096                 public Type MemberType {
5097                         get {
5098                                 if (member_type == null && Type != null) {
5099                                         IResolveContext rc = GenericMethod == null ? this : (IResolveContext)ds;
5100                                         Type = Type.ResolveAsTypeTerminal (rc, false);
5101                                         if (Type != null) {
5102                                                 member_type = Type.Type;
5103                                         }
5104                                 }
5105                                 return member_type;
5106                         }
5107                 }
5108
5109                 //
5110                 // Whether this is an interface member.
5111                 //
5112                 public bool IsInterface;
5113
5114                 //
5115                 // If true, this is an explicit interface implementation
5116                 //
5117                 public bool IsExplicitImpl;
5118
5119                 //
5120                 // The interface type we are explicitly implementing
5121                 //
5122                 public Type InterfaceType = null;
5123
5124                 //
5125                 // The constructor is only exposed to our children
5126                 //
5127                 protected MemberBase (DeclSpace parent, GenericMethod generic,
5128                                       Expression type, int mod, int allowed_mod, int def_mod,
5129                                       MemberName name, Attributes attrs)
5130                         : base (parent, name, attrs)
5131                 {
5132                         this.ds = generic != null ? generic : (DeclSpace) parent;
5133                         explicit_mod_flags = mod;
5134                         Type = type;
5135                         ModFlags = Modifiers.Check (allowed_mod, mod, def_mod, Location);
5136                         IsExplicitImpl = (MemberName.Left != null);
5137                         GenericMethod = generic;
5138                         if (GenericMethod != null)
5139                                 GenericMethod.ModFlags = ModFlags;
5140                 }
5141
5142                 protected virtual bool CheckBase ()
5143                 {
5144                         if ((ModFlags & Modifiers.PROTECTED) != 0 && ParentContainer.Kind == Kind.Struct) {
5145                                 Report.Error (666, Location, "`{0}': new protected member declared in struct", GetSignatureForError ());
5146                                 return false;
5147                         }
5148    
5149                         if ((RootContext.WarningLevel >= 4) &&
5150                             ((Parent.ModFlags & Modifiers.SEALED) != 0) &&
5151                             ((ModFlags & Modifiers.PROTECTED) != 0) &&
5152                             ((ModFlags & Modifiers.OVERRIDE) == 0) && (Name != "Finalize")) {
5153                                 Report.Warning (628, 4, Location, "`{0}': new protected member declared in sealed class", GetSignatureForError ());
5154                         }
5155                         return true;
5156                 }
5157
5158                 protected virtual bool DoDefineBase ()
5159                 {
5160                         if (Name == null)
5161                                 throw new InternalErrorException ();
5162
5163                         if (IsInterface) {
5164                                 ModFlags = Modifiers.PUBLIC |
5165                                         Modifiers.ABSTRACT |
5166                                         Modifiers.VIRTUAL | (ModFlags & Modifiers.UNSAFE) | (ModFlags & Modifiers.NEW);
5167
5168                                 flags = MethodAttributes.Public |
5169                                         MethodAttributes.Abstract |
5170                                         MethodAttributes.HideBySig |
5171                                         MethodAttributes.NewSlot |
5172                                         MethodAttributes.Virtual;
5173                         } else {
5174                                 if (!ParentContainer.MethodModifiersValid (this))
5175                                         return false;
5176
5177                                 flags = Modifiers.MethodAttr (ModFlags);
5178                         }
5179
5180                         if (IsExplicitImpl) {
5181                                 Expression expr = MemberName.Left.GetTypeExpression ();
5182                                 TypeExpr iface_texpr = expr.ResolveAsTypeTerminal (this, false);
5183                                 if (iface_texpr == null)
5184                                         return false;
5185
5186                                 InterfaceType = iface_texpr.Type;
5187
5188                                 if (!InterfaceType.IsInterface) {
5189                                         Report.Error (538, Location, "'{0}' in explicit interface declaration is not an interface", TypeManager.CSharpName (InterfaceType));
5190                                         return false;
5191                                 }
5192
5193                                 if (!ParentContainer.VerifyImplements (this))
5194                                         return false;
5195                                 
5196                                 Modifiers.Check (Modifiers.AllowedExplicitImplFlags, explicit_mod_flags, 0, Location);
5197                         }
5198
5199                         return true;
5200                 }
5201
5202                 protected virtual bool DoDefine ()
5203                 {
5204                         if (MemberType == null)
5205                                 return false;
5206
5207                         if ((Parent.ModFlags & Modifiers.SEALED) != 0 && 
5208                                 (ModFlags & (Modifiers.VIRTUAL|Modifiers.ABSTRACT)) != 0) {
5209                                         Report.Error (549, Location, "New virtual member `{0}' is declared in a sealed class `{1}'",
5210                                                 GetSignatureForError (), Parent.GetSignatureForError ());
5211                                         return false;
5212                         }
5213                         
5214                         // verify accessibility
5215                         if (!Parent.AsAccessible (MemberType, ModFlags)) {
5216                                 Report.SymbolRelatedToPreviousError (MemberType);
5217                                 if (this is Property)
5218                                         Report.Error (53, Location,
5219                                                       "Inconsistent accessibility: property type `" +
5220                                                       TypeManager.CSharpName (MemberType) + "' is less " +
5221                                                       "accessible than property `" + GetSignatureForError () + "'");
5222                                 else if (this is Indexer)
5223                                         Report.Error (54, Location,
5224                                                       "Inconsistent accessibility: indexer return type `" +
5225                                                       TypeManager.CSharpName (MemberType) + "' is less " +
5226                                                       "accessible than indexer `" + GetSignatureForError () + "'");
5227                                 else if (this is MethodCore) {
5228                                         if (this is Operator)
5229                                                 Report.Error (56, Location,
5230                                                               "Inconsistent accessibility: return type `" +
5231                                                               TypeManager.CSharpName (MemberType) + "' is less " +
5232                                                               "accessible than operator `" + GetSignatureForError () + "'");
5233                                         else
5234                                                 Report.Error (50, Location,
5235                                                               "Inconsistent accessibility: return type `" +
5236                                                               TypeManager.CSharpName (MemberType) + "' is less " +
5237                                                               "accessible than method `" + GetSignatureForError () + "'");
5238                                 } else {
5239                                         Report.Error (52, Location,
5240                                                       "Inconsistent accessibility: field type `" +
5241                                                       TypeManager.CSharpName (MemberType) + "' is less " +
5242                                                       "accessible than field `" + GetSignatureForError () + "'");
5243                                 }
5244                                 return false;
5245                         }
5246
5247                         if (IsExplicitImpl) {
5248                                 Expression expr = MemberName.Left.GetTypeExpression ();
5249                                 TypeExpr texpr = expr.ResolveAsTypeTerminal (this, false);
5250                                 if (texpr == null)
5251                                         return false;
5252
5253                                 InterfaceType = texpr.Type;
5254
5255                                 if (!InterfaceType.IsInterface) {
5256                                         Report.Error (538, Location, "`{0}' in explicit interface declaration is not an interface", TypeManager.CSharpName (InterfaceType));
5257                                         return false;
5258                                 }
5259                                 
5260                                 if (!ParentContainer.VerifyImplements (this))
5261                                         return false;
5262                                 
5263                                 Modifiers.Check (Modifiers.AllowedExplicitImplFlags, explicit_mod_flags, 0, Location);
5264                                 
5265                         }
5266                         return true;
5267                 }
5268
5269                 protected bool IsTypePermitted ()
5270                 {
5271                         if (MemberType == TypeManager.arg_iterator_type || MemberType == TypeManager.typed_reference_type) {
5272                                 Report.Error (610, Location, "Field or property cannot be of type `{0}'", TypeManager.CSharpName (MemberType));
5273                                 return false;
5274                         }
5275                         return true;
5276                 }
5277
5278                 protected override bool VerifyClsCompliance()
5279                 {
5280                         if (base.VerifyClsCompliance ()) {
5281                                 return true;
5282                         }
5283
5284                         if (IsInterface && HasClsCompliantAttribute && Parent.IsClsComplianceRequired ()) {
5285                                 Report.Error (3010, Location, "`{0}': CLS-compliant interfaces must have only CLS-compliant members", GetSignatureForError ());
5286                         }
5287                         return false;
5288                 }
5289
5290         }
5291
5292         //
5293         // Fields and Events both generate FieldBuilders, we use this to share 
5294         // their common bits.  This is also used to flag usage of the field
5295         //
5296         abstract public class FieldBase : MemberBase {
5297                 public FieldBuilder  FieldBuilder;
5298                 public Status status;
5299                 protected Expression initializer;
5300                 ExpressionStatement initializerStatement;
5301
5302                 [Flags]
5303                 public enum Status : byte {
5304                         HAS_OFFSET = 4          // Used by FieldMember.
5305                 }
5306
5307                 static string[] attribute_targets = new string [] { "field" };
5308
5309                 /// <summary>
5310                 ///  Symbol with same name in base class/struct
5311                 /// </summary>
5312                 public MemberInfo conflict_symbol;
5313
5314                 protected FieldBase (DeclSpace parent, Expression type, int mod,
5315                                      int allowed_mod, MemberName name, Attributes attrs)
5316                         : base (parent, null, type, mod, allowed_mod, Modifiers.PRIVATE,
5317                                 name, attrs)
5318                 {
5319                 }
5320
5321                 public override AttributeTargets AttributeTargets {
5322                         get {
5323                                 return AttributeTargets.Field;
5324                         }
5325                 }
5326
5327                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
5328                 {
5329                         if (a.Type == TypeManager.marshal_as_attr_type) {
5330                                 UnmanagedMarshal marshal = a.GetMarshal (this);
5331                                 if (marshal != null) {
5332                                         FieldBuilder.SetMarshal (marshal);
5333                                 }
5334                                 return;
5335                         }
5336
5337                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
5338                                 a.Error_InvalidSecurityParent ();
5339                                 return;
5340                         }
5341
5342                         FieldBuilder.SetCustomAttribute (cb);
5343                 }
5344
5345                 public void EmitInitializer (EmitContext ec)
5346                 {
5347                         initializerStatement.EmitStatement (ec);
5348                 }
5349
5350                 protected override bool CheckBase ()
5351                 {
5352                         if (!base.CheckBase ())
5353                                 return false;
5354
5355                         // TODO: Implement
5356                         if (IsInterface)
5357                                 return true;
5358
5359                         conflict_symbol = ParentContainer.FindBaseMemberWithSameName (Name, false);
5360                         if (conflict_symbol == null) {
5361                                 if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0)) {
5362                                         Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
5363                                 }
5364                                 return true;
5365                         }
5366
5367                         if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE)) == 0) {
5368                                 Report.SymbolRelatedToPreviousError (conflict_symbol);
5369                                 Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
5370                                         GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
5371                         }
5372
5373                         return true;
5374                 }
5375
5376                 public Expression Initializer {
5377                         set {
5378                                 if (value != null) {
5379                                         this.initializer = value;
5380                                         ParentContainer.RegisterFieldForInitialization (this);
5381                                 }
5382                         }
5383                 }
5384
5385                 protected virtual bool IsFieldClsCompliant {
5386                         get {
5387                                 if (FieldBuilder == null)
5388                                         return true;
5389
5390                                 return AttributeTester.IsClsCompliant (FieldBuilder.FieldType);
5391                         }
5392                 }
5393
5394                 public Expression ResolveInitializer ()
5395                 {
5396                         // TODO: again it's too heavy-weight
5397                         EmitContext ec = new EmitContext (this, Parent, Location, null, null, ModFlags);
5398                         ec.IsFieldInitializer = true;
5399                         initializer = initializer.Resolve (ec);
5400                         if (initializer == null)
5401                                 return null;
5402
5403                         FieldExpr fe = new FieldExpr (FieldBuilder, Location, true);
5404                         if ((ModFlags & Modifiers.STATIC) == 0) 
5405                         {
5406                                 fe.InstanceExpression = CompilerGeneratedThis.Instance;
5407                         }
5408
5409                         initializerStatement = new Assign (fe, initializer, Location).ResolveStatement (ec);
5410                         return initializer;
5411                 }
5412
5413                 public bool HasDefaultInitializer
5414                 {
5415                         get
5416                         {
5417                                 Constant c = initializer as Constant;
5418                                 if (c == null)
5419                                         return false;
5420
5421                                 return c.IsDefaultInitializer (MemberType);
5422                         }
5423                 }
5424
5425                 public override string[] ValidAttributeTargets 
5426                 {
5427                         get {
5428                                 return attribute_targets;
5429                         }
5430                 }
5431
5432                 protected override bool VerifyClsCompliance ()
5433                 {
5434                         if (!base.VerifyClsCompliance ())
5435                                 return false;
5436
5437                         if (!IsFieldClsCompliant) {
5438                                 Report.Error (3003, Location, "Type of `{0}' is not CLS-compliant", GetSignatureForError ());
5439                         }
5440                         return true;
5441                 }
5442
5443
5444                 public void SetAssigned ()
5445                 {
5446                         caching_flags |= Flags.IsAssigned;
5447                 }
5448         }
5449
5450         public abstract class FieldMember : FieldBase
5451         {
5452                 protected FieldMember (DeclSpace parent, Expression type, int mod,
5453                         int allowed_mod, MemberName name, Attributes attrs)
5454                         : base (parent, type, mod, allowed_mod | Modifiers.ABSTRACT, name, attrs)
5455                 {
5456                         if ((mod & Modifiers.ABSTRACT) != 0)
5457                                 Report.Error (681, Location, "The modifier 'abstract' is not valid on fields. Try using a property instead");
5458                 }
5459
5460                 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
5461                 {
5462                         if (a.Type == TypeManager.field_offset_attribute_type)
5463                         {
5464                                 status |= Status.HAS_OFFSET;
5465
5466                                 if (!ParentContainer.HasExplicitLayout) {
5467                                         Report.Error (636, Location, "The FieldOffset attribute can only be placed on members of types marked with the StructLayout(LayoutKind.Explicit)");
5468                                         return;
5469                                 }
5470
5471                                 if ((ModFlags & Modifiers.STATIC) != 0 || this is Const) {
5472                                         Report.Error (637, Location, "The FieldOffset attribute is not allowed on static or const fields");
5473                                         return;
5474                                 }
5475                         }
5476
5477                         if (a.Type == TypeManager.fixed_buffer_attr_type) {
5478                                 Report.Error (1716, Location, "Do not use 'System.Runtime.CompilerServices.FixedBuffer' attribute. Use the 'fixed' field modifier instead");
5479                                 return;
5480                         }
5481
5482                         base.ApplyAttributeBuilder (a, cb);
5483                 }
5484
5485                 public override bool Define()
5486                 {
5487                         if (MemberType == null || Type == null)
5488                                 return false;
5489                         
5490                         if (MemberType == TypeManager.void_type) {
5491                                 Report.Error (1547, Location, "Keyword 'void' cannot be used in this context");
5492                                 return false;
5493                         }
5494
5495                         if (!CheckBase ())
5496                                 return false;
5497                         
5498                         if (!Parent.AsAccessible (MemberType, ModFlags)) {
5499                                 Report.Error (52, Location,
5500                                         "Inconsistent accessibility: field type `" +
5501                                         TypeManager.CSharpName (MemberType) + "' is less " +
5502                                         "accessible than field `" + GetSignatureForError () + "'");
5503                                 return false;
5504                         }
5505
5506                         if (!IsTypePermitted ())
5507                                 return false;
5508
5509                         return true;
5510                 }
5511
5512                 public override void Emit ()
5513                 {
5514                         if (OptAttributes != null) {
5515                                 OptAttributes.Emit ();
5516                         }
5517
5518                         if (((status & Status.HAS_OFFSET) == 0) && (ModFlags & Modifiers.STATIC) == 0 && ParentContainer.HasExplicitLayout) {
5519                                 Report.Error (625, Location, "`{0}': Instance field types marked with StructLayout(LayoutKind.Explicit) must have a FieldOffset attribute.", GetSignatureForError ());
5520                         }
5521
5522                         base.Emit ();
5523                 }
5524
5525                 //
5526                 //   Represents header string for documentation comment.
5527                 //
5528                 public override string DocCommentHeader {
5529                         get { return "F:"; }
5530                 }
5531         }
5532
5533         interface IFixedBuffer
5534         {
5535                 FieldInfo Element { get; }
5536                 Type ElementType { get; }
5537         }
5538
5539         public class FixedFieldExternal: IFixedBuffer
5540         {
5541                 FieldInfo element_field;
5542
5543                 public FixedFieldExternal (FieldInfo fi)
5544                 {
5545                         element_field = fi.FieldType.GetField (FixedField.FixedElementName);
5546                 }
5547
5548                 #region IFixedField Members
5549
5550                 public FieldInfo Element {
5551                         get {
5552                                 return element_field;
5553                         }
5554                 }
5555
5556                 public Type ElementType {
5557                         get {
5558                                 return element_field.FieldType;
5559                         }
5560                 }
5561
5562                 #endregion
5563         }
5564
5565         /// <summary>
5566         /// Fixed buffer implementation
5567         /// </summary>
5568         public class FixedField : FieldMember, IFixedBuffer
5569         {
5570                 public const string FixedElementName = "FixedElementField";
5571                 static int GlobalCounter = 0;
5572                 static object[] ctor_args = new object[] { (short)LayoutKind.Sequential };
5573                 static FieldInfo[] fi;
5574
5575                 TypeBuilder fixed_buffer_type;
5576                 FieldBuilder element;
5577                 Expression size_expr;
5578                 int buffer_size;
5579
5580                 const int AllowedModifiers =
5581                         Modifiers.NEW |
5582                         Modifiers.PUBLIC |
5583                         Modifiers.PROTECTED |
5584                         Modifiers.INTERNAL |
5585                         Modifiers.PRIVATE;
5586
5587                 public FixedField (DeclSpace parent, Expression type, int mod, string name,
5588                         Expression size_expr, Attributes attrs, Location loc):
5589                         base (parent, type, mod, AllowedModifiers, new MemberName (name, loc), attrs)
5590                 {
5591                         if (RootContext.Version == LanguageVersion.ISO_1)
5592                                 Report.FeatureIsNotStandardized (loc, "fixed size buffers");
5593
5594                         this.size_expr = size_expr;
5595                 }
5596
5597                 public override bool Define()
5598                 {
5599 #if !NET_2_0
5600                         if ((ModFlags & (Modifiers.PUBLIC | Modifiers.PROTECTED)) != 0)
5601                                 Report.Warning (-23, 1, Location, "Only private or internal fixed sized buffers are supported by .NET 1.x");
5602 #endif
5603
5604                         if (ParentContainer.Kind != Kind.Struct) {
5605                                 Report.Error (1642, Location, "`{0}': Fixed size buffer fields may only be members of structs",
5606                                         GetSignatureForError ());
5607                                 return false;
5608                         }
5609
5610                         if (!base.Define ())
5611                                 return false;
5612
5613                         if (!TypeManager.IsPrimitiveType (MemberType)) {
5614                                 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",
5615                                         GetSignatureForError ());
5616                                 return false;
5617                         }
5618
5619                         EmitContext ec = new EmitContext (this, Parent, Location, null, null, ModFlags);
5620                         Constant c = size_expr.ResolveAsConstant (ec, this);
5621                         if (c == null)
5622                                 return false;
5623
5624                         IntConstant buffer_size_const = c.ToInt (Location);
5625                         if (buffer_size_const == null)
5626                                 return false;
5627
5628                         buffer_size = buffer_size_const.Value;
5629
5630                         if (buffer_size <= 0) {
5631                                 Report.Error (1665, Location, "`{0}': Fixed size buffers must have a length greater than zero", GetSignatureForError ());
5632                                 return false;
5633                         }
5634
5635                         int type_size = Expression.GetTypeSize (MemberType);
5636
5637                         if (buffer_size > int.MaxValue / type_size) {
5638                                 Report.Error (1664, Location, "Fixed size buffer `{0}' of length `{1}' and type `{2}' exceeded 2^31 limit",
5639                                         GetSignatureForError (), buffer_size.ToString (), TypeManager.CSharpName (MemberType));
5640                                 return false;
5641                         }
5642
5643                         buffer_size *= type_size;
5644
5645                         // Define nested
5646                         string name = String.Format ("<{0}>__FixedBuffer{1}", Name, GlobalCounter++);
5647
5648                         fixed_buffer_type = Parent.TypeBuilder.DefineNestedType (name,
5649                                 TypeAttributes.NestedPublic | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit, TypeManager.value_type);
5650                         element = fixed_buffer_type.DefineField (FixedElementName, MemberType, FieldAttributes.Public);
5651                         RootContext.RegisterCompilerGeneratedType (fixed_buffer_type);
5652
5653                         FieldBuilder = Parent.TypeBuilder.DefineField (Name, fixed_buffer_type, Modifiers.FieldAttr (ModFlags));
5654                         TypeManager.RegisterFieldBase (FieldBuilder, this);
5655
5656                         return true;
5657                 }
5658
5659                 public override void Emit()
5660                 {
5661                         if (fi == null)
5662                                 fi = new FieldInfo [] { TypeManager.struct_layout_attribute_type.GetField ("Size") };
5663
5664                         object[] fi_val = new object[1];
5665                         fi_val [0] = buffer_size;
5666
5667                         CustomAttributeBuilder cab = new CustomAttributeBuilder (TypeManager.struct_layout_attribute_ctor, 
5668                                 ctor_args, fi, fi_val);
5669                         fixed_buffer_type.SetCustomAttribute (cab);
5670
5671                         cab = new CustomAttributeBuilder (TypeManager.fixed_buffer_attr_ctor, new object[] { MemberType, buffer_size } );
5672                         FieldBuilder.SetCustomAttribute (cab);
5673                         base.Emit ();
5674                 }
5675
5676                 protected override bool IsFieldClsCompliant {
5677                         get {
5678                                 return false;
5679                         }
5680                 }
5681
5682                 #region IFixedField Members
5683
5684                 public FieldInfo Element {
5685                         get {
5686                                 return element;
5687                         }
5688                 }
5689
5690                 public Type ElementType {
5691                         get {
5692                                 return MemberType;
5693                         }
5694                 }
5695
5696                 #endregion
5697         }
5698
5699         //
5700         // The Field class is used to represents class/struct fields during parsing.
5701         //
5702         public class Field : FieldMember {
5703                 // <summary>
5704                 //   Modifiers allowed in a class declaration
5705                 // </summary>
5706                 const int AllowedModifiers =
5707                         Modifiers.NEW |
5708                         Modifiers.PUBLIC |
5709                         Modifiers.PROTECTED |
5710                         Modifiers.INTERNAL |
5711                         Modifiers.PRIVATE |
5712                         Modifiers.STATIC |
5713                         Modifiers.VOLATILE |
5714                         Modifiers.UNSAFE |
5715                         Modifiers.READONLY;
5716
5717                 public Field (DeclSpace parent, Expression type, int mod, string name,
5718                               Attributes attrs, Location loc)
5719                         : base (parent, type, mod, AllowedModifiers, new MemberName (name, loc),
5720                                 attrs)
5721                 {
5722                 }
5723
5724                 public override bool Define ()
5725                 {
5726                         if (!base.Define ())
5727                                 return false;
5728
5729                         if (RootContext.WarningLevel > 1){
5730                                 Type ptype = Parent.TypeBuilder.BaseType;
5731
5732                                 // ptype is only null for System.Object while compiling corlib.
5733                                 if (ptype != null){
5734                                         TypeContainer.FindMembers (
5735                                                 ptype, MemberTypes.Method,
5736                                                 BindingFlags.Public |
5737                                                 BindingFlags.Static | BindingFlags.Instance,
5738                                                 System.Type.FilterName, Name);
5739                                 }
5740                         }
5741
5742                         if ((ModFlags & Modifiers.VOLATILE) != 0){
5743                                 if (!MemberType.IsClass){
5744                                         Type vt = MemberType;
5745                                         
5746                                         if (TypeManager.IsEnumType (vt))
5747                                                 vt = TypeManager.EnumToUnderlying (MemberType);
5748
5749                                         if (!((vt == TypeManager.bool_type) ||
5750                                               (vt == TypeManager.sbyte_type) ||
5751                                               (vt == TypeManager.byte_type) ||
5752                                               (vt == TypeManager.short_type) ||
5753                                               (vt == TypeManager.ushort_type) ||
5754                                               (vt == TypeManager.int32_type) ||
5755                                               (vt == TypeManager.uint32_type) ||    
5756                                               (vt == TypeManager.char_type) ||
5757                                               (vt == TypeManager.float_type) ||
5758                                               (!vt.IsValueType))){
5759                                                 Report.Error (677, Location, "`{0}': A volatile field cannot be of the type `{1}'",
5760                                                         GetSignatureForError (), TypeManager.CSharpName (vt));
5761                                                 return false;
5762                                         }
5763                                 }
5764
5765                                 if ((ModFlags & Modifiers.READONLY) != 0){
5766                                         Report.Error (678, Location, "`{0}': A field cannot be both volatile and readonly",
5767                                                 GetSignatureForError ());
5768                                         return false;
5769                                 }
5770                         }
5771
5772                         FieldAttributes fa = Modifiers.FieldAttr (ModFlags);
5773
5774                         if (ParentContainer.Kind == Kind.Struct && 
5775                             ((fa & FieldAttributes.Static) == 0) &&
5776                             MemberType == Parent.TypeBuilder &&
5777                             !TypeManager.IsBuiltinType (MemberType)){
5778                                 Report.Error (523, Location, "Struct member `" + Parent.Name + "." + Name + 
5779                                               "' causes a cycle in the structure layout");
5780                                 return false;
5781                         }
5782
5783                         try {
5784                                 FieldBuilder = Parent.TypeBuilder.DefineField (
5785                                         Name, MemberType, Modifiers.FieldAttr (ModFlags));
5786
5787                         TypeManager.RegisterFieldBase (FieldBuilder, this);
5788                         }
5789                         catch (ArgumentException) {
5790                                 Report.Warning (-24, 1, Location, "The Microsoft runtime is unable to use [void|void*] as a field type, try using the Mono runtime.");
5791                                 return false;
5792                         }
5793
5794                         return true;
5795                 }
5796
5797                 protected override bool VerifyClsCompliance ()
5798                 {
5799                         if (!base.VerifyClsCompliance ())
5800                                 return false;
5801
5802                         if ((ModFlags & Modifiers.VOLATILE) != 0) {
5803                                 Report.Warning (3026, 1, Location, "CLS-compliant field `{0}' cannot be volatile", GetSignatureForError ());
5804                         }
5805
5806                         return true;
5807                 }
5808         }
5809
5810         //
5811         // `set' and `get' accessors are represented with an Accessor.
5812         // 
5813         public class Accessor : IIteratorContainer {
5814                 //
5815                 // Null if the accessor is empty, or a Block if not
5816                 //
5817                 public const int AllowedModifiers = 
5818                         Modifiers.PUBLIC |
5819                         Modifiers.PROTECTED |
5820                         Modifiers.INTERNAL |
5821                         Modifiers.PRIVATE;
5822                 
5823                 public ToplevelBlock Block;
5824                 public Attributes Attributes;
5825                 public Location Location;
5826                 public int ModFlags;
5827                 public bool Yields;
5828                 
5829                 public Accessor (ToplevelBlock b, int mod, Attributes attrs, Location loc)
5830                 {
5831                         Block = b;
5832                         Attributes = attrs;
5833                         Location = loc;
5834                         ModFlags = Modifiers.Check (AllowedModifiers, mod, 0, loc);
5835                 }
5836
5837                 public void SetYields ()
5838                 {
5839                         Yields = true;
5840                 }
5841         }
5842
5843         // Ooouh Martin, templates are missing here.
5844         // When it will be possible move here a lot of child code and template method type.
5845         public abstract class AbstractPropertyEventMethod : MemberCore, IMethodData {
5846                 protected MethodData method_data;
5847                 protected ToplevelBlock block;
5848                 protected ListDictionary declarative_security;
5849
5850                 // The accessor are created event if they are not wanted.
5851                 // But we need them because their names are reserved.
5852                 // Field says whether accessor will be emited or not
5853                 public readonly bool IsDummy;
5854
5855                 protected readonly string prefix;
5856
5857                 ReturnParameter return_attributes;
5858
5859                 public AbstractPropertyEventMethod (MemberBase member, string prefix)
5860                         : base (member.Parent, SetupName (prefix, member, member.Location), null)
5861                 {
5862                         this.prefix = prefix;
5863                         IsDummy = true;
5864                 }
5865
5866                 public AbstractPropertyEventMethod (MemberBase member, Accessor accessor,
5867                                                     string prefix)
5868                         : base (member.Parent, SetupName (prefix, member, accessor.Location),
5869                                 accessor.Attributes)
5870                 {
5871                         this.prefix = prefix;
5872                         this.block = accessor.Block;
5873                 }
5874
5875                 static MemberName SetupName (string prefix, MemberBase member, Location loc)
5876                 {
5877                         return new MemberName (member.MemberName.Left, prefix + member.ShortName, loc);
5878                 }
5879
5880                 public void UpdateName (MemberBase member)
5881                 {
5882                         SetMemberName (SetupName (prefix, member, Location));
5883                 }
5884
5885                 #region IMethodData Members
5886
5887                 public ToplevelBlock Block {
5888                         get {
5889                                 return block;
5890                         }
5891
5892                         set {
5893                                 block = value;
5894                         }
5895                 }
5896
5897                 public CallingConventions CallingConventions {
5898                         get {
5899                                 return CallingConventions.Standard;
5900                         }
5901                 }
5902
5903                 public bool IsExcluded ()
5904                 {
5905                         return false;
5906                 }
5907
5908                 GenericMethod IMethodData.GenericMethod {
5909                         get {
5910                                 return null;
5911                         }
5912                 }
5913
5914                 public MemberName MethodName {
5915                         get {
5916                                 return MemberName;
5917                         }
5918                 }
5919
5920                 public Type[] ParameterTypes { 
5921                         get {
5922                                 return ParameterInfo.Types;
5923                         }
5924                 }
5925
5926                 public abstract Parameters ParameterInfo { get ; }
5927                 public abstract Type ReturnType { get; }
5928                 public abstract EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig);
5929
5930                 #endregion
5931
5932                 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
5933                 {
5934                         if (a.Type == TypeManager.cls_compliant_attribute_type || a.Type == TypeManager.obsolete_attribute_type ||
5935                                         a.Type == TypeManager.conditional_attribute_type) {
5936                                 Report.Error (1667, a.Location,
5937                                         "Attribute `{0}' is not valid on property or event accessors. It is valid on `{1}' declarations only",
5938                                         TypeManager.CSharpName (a.Type), a.GetValidTargets ());
5939                                 return;
5940                         }
5941
5942                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
5943                                 if (declarative_security == null)
5944                                         declarative_security = new ListDictionary ();
5945                                 a.ExtractSecurityPermissionSet (declarative_security);
5946                                 return;
5947                         }
5948
5949                         if (a.Target == AttributeTargets.Method) {
5950                                 method_data.MethodBuilder.SetCustomAttribute (cb);
5951                                 return;
5952                         }
5953
5954                         if (a.Target == AttributeTargets.ReturnValue) {
5955                                 if (return_attributes == null)
5956                                         return_attributes = new ReturnParameter (method_data.MethodBuilder, Location);
5957
5958                                 return_attributes.ApplyAttributeBuilder (a, cb);
5959                                 return;
5960                         }
5961
5962                         ApplyToExtraTarget (a, cb);
5963                 }
5964
5965                 virtual protected void ApplyToExtraTarget (Attribute a, CustomAttributeBuilder cb)
5966                 {
5967                         System.Diagnostics.Debug.Fail ("You forgot to define special attribute target handling");
5968                 }
5969
5970                 public override bool Define()
5971                 {
5972                         throw new NotSupportedException ();
5973                 }
5974
5975                 public void Emit (DeclSpace parent)
5976                 {
5977                         EmitMethod (parent);
5978
5979                         if (OptAttributes != null)
5980                                 OptAttributes.Emit ();
5981
5982                         if (declarative_security != null) {
5983                                 foreach (DictionaryEntry de in declarative_security) {
5984                                         method_data.MethodBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
5985                                 }
5986                         }
5987
5988                         block = null;
5989                 }
5990
5991                 protected virtual void EmitMethod (DeclSpace parent)
5992                 {
5993                         method_data.Emit (parent);
5994                 }
5995
5996                 public override bool IsClsComplianceRequired()
5997                 {
5998                         return false;
5999                 }
6000
6001                 public bool IsDuplicateImplementation (MethodCore method)
6002                 {
6003                         if (!MemberName.Equals (method.MemberName))
6004                                 return false;
6005
6006                         Type[] param_types = method.ParameterTypes;
6007
6008                         if (param_types.Length != ParameterTypes.Length)
6009                                 return false;
6010
6011                         for (int i = 0; i < param_types.Length; i++)
6012                                 if (param_types [i] != ParameterTypes [i])
6013                                         return false;
6014
6015                         Report.SymbolRelatedToPreviousError (method);
6016                         Report.Error (111, Location, TypeContainer.Error111, method.GetSignatureForError ());
6017                         return true;
6018                 }
6019
6020                 public override bool IsUsed
6021                 {
6022                         get {
6023                                 if (IsDummy)
6024                                         return false;
6025
6026                                 return base.IsUsed;
6027                         }
6028                 }
6029
6030                 public new Location Location { 
6031                         get {
6032                                 return base.Location;
6033                         }
6034                 }
6035
6036                 //
6037                 //   Represents header string for documentation comment.
6038                 //
6039                 public override string DocCommentHeader {
6040                         get { throw new InvalidOperationException ("Unexpected attempt to get doc comment from " + this.GetType () + "."); }
6041                 }
6042
6043         }
6044
6045         //
6046         // Properties and Indexers both generate PropertyBuilders, we use this to share 
6047         // their common bits.
6048         //
6049         abstract public class PropertyBase : MethodCore {
6050
6051                 public class GetMethod : PropertyMethod
6052                 {
6053                         static string[] attribute_targets = new string [] { "method", "return" };
6054
6055                         public GetMethod (MethodCore method):
6056                                 base (method, "get_")
6057                         {
6058                         }
6059
6060                         public GetMethod (MethodCore method, Accessor accessor):
6061                                 base (method, accessor, "get_")
6062                         {
6063                         }
6064
6065                         public override MethodBuilder Define (DeclSpace parent)
6066                         {
6067                                 base.Define (parent);
6068                                 
6069                                 method_data = new MethodData (method, ModFlags, flags, this);
6070
6071                                 if (!method_data.Define (parent))
6072                                         return null;
6073
6074                                 return method_data.MethodBuilder;
6075                         }
6076
6077                         public override Type ReturnType {
6078                                 get {
6079                                         return method.MemberType;
6080                                 }
6081                         }
6082
6083                         public override Parameters ParameterInfo {
6084                                 get {
6085                                         return Parameters.EmptyReadOnlyParameters;
6086                                 }
6087                         }
6088
6089                         public override string[] ValidAttributeTargets {
6090                                 get {
6091                                         return attribute_targets;
6092                                 }
6093                         }
6094                 }
6095
6096                 public class SetMethod : PropertyMethod {
6097
6098                         static string[] attribute_targets = new string [] { "method", "param", "return" };
6099                         ImplicitParameter param_attr;
6100                         protected Parameters parameters;
6101
6102                         public SetMethod (MethodCore method):
6103                                 base (method, "set_")
6104                         {
6105                         }
6106
6107                         public SetMethod (MethodCore method, Accessor accessor):
6108                                 base (method, accessor, "set_")
6109                         {
6110                         }
6111
6112                         protected override void ApplyToExtraTarget(Attribute a, CustomAttributeBuilder cb)
6113                         {
6114                                 if (a.Target == AttributeTargets.Parameter) {
6115                                         if (param_attr == null)
6116                                                 param_attr = new ImplicitParameter (method_data.MethodBuilder);
6117
6118                                         param_attr.ApplyAttributeBuilder (a, cb);
6119                                         return;
6120                                 }
6121
6122                                 base.ApplyAttributeBuilder (a, cb);
6123                         }
6124
6125                         public override Parameters ParameterInfo {
6126                                 get {
6127                                         return parameters;
6128                                 }
6129                         }
6130
6131                         protected virtual void DefineParameters ()
6132                         {
6133                                 parameters = new Parameters (
6134                                         new Parameter[] { new Parameter (method.MemberType, "value", Parameter.Modifier.NONE, null, Location) },
6135                                         new Type[] { method.MemberType });
6136                         }
6137
6138                         public override MethodBuilder Define (DeclSpace parent)
6139                         {
6140                                 DefineParameters ();
6141                                 if (IsDummy)
6142                                         return null;
6143
6144                                 base.Define (parent);
6145
6146                                 method_data = new MethodData (method, ModFlags, flags, this);
6147
6148                                 if (!method_data.Define (parent))
6149                                         return null;
6150
6151                                 return method_data.MethodBuilder;
6152                         }
6153
6154                         public override Type ReturnType {
6155                                 get {
6156                                         return TypeManager.void_type;
6157                                 }
6158                         }
6159
6160                         public override string[] ValidAttributeTargets {
6161                                 get {
6162                                         return attribute_targets;
6163                                 }
6164                         }
6165                 }
6166
6167                 static string[] attribute_targets = new string [] { "property" };
6168
6169                 public abstract class PropertyMethod : AbstractPropertyEventMethod
6170                 {
6171                         protected readonly MethodCore method;
6172                         protected MethodAttributes flags;
6173                         bool yields;
6174
6175                         public PropertyMethod (MethodCore method, string prefix)
6176                                 : base (method, prefix)
6177                         {
6178                                 this.method = method;
6179                         }
6180
6181                         public PropertyMethod (MethodCore method, Accessor accessor,
6182                                                string prefix)
6183                                 : base (method, accessor, prefix)
6184                         {
6185                                 this.method = method;
6186                                 this.ModFlags = accessor.ModFlags;
6187                                 yields = accessor.Yields;
6188
6189                                 if (accessor.ModFlags != 0 && RootContext.Version == LanguageVersion.ISO_1) {
6190                                         Report.FeatureIsNotStandardized (Location, "access modifiers on properties");
6191                                 }
6192                         }
6193
6194                         public override AttributeTargets AttributeTargets {
6195                                 get {
6196                                         return AttributeTargets.Method;
6197                                 }
6198                         }
6199
6200                         public override bool IsClsComplianceRequired ()
6201                         {
6202                                 return method.IsClsComplianceRequired ();
6203                         }
6204
6205                         public virtual MethodBuilder Define (DeclSpace parent)
6206                         {
6207                                 if (!method.CheckAbstractAndExtern (block != null))
6208                                         return null;
6209
6210                                 TypeContainer container = ((TypeContainer) parent).PartialContainer;
6211
6212                                 //
6213                                 // Check for custom access modifier
6214                                 //
6215                                 if (ModFlags == 0) {
6216                                         ModFlags = method.ModFlags;
6217                                         flags = method.flags;
6218                                 } else {
6219                                         if (container.Kind == Kind.Interface)
6220                                                 Report.Error (275, Location, "`{0}': accessibility modifiers may not be used on accessors in an interface",
6221                                                         GetSignatureForError ());
6222
6223                                         if ((method.ModFlags & Modifiers.ABSTRACT) != 0 && (ModFlags & Modifiers.PRIVATE) != 0) {
6224                                                 Report.Error (442, Location, "`{0}': abstract properties cannot have private accessors", GetSignatureForError ());
6225                                         }
6226
6227                                         CheckModifiers (ModFlags);
6228                                         ModFlags |= (method.ModFlags & (~Modifiers.Accessibility));
6229                                         ModFlags |= Modifiers.PROPERTY_CUSTOM;
6230                                         flags = Modifiers.MethodAttr (ModFlags);
6231                                         flags |= (method.flags & (~MethodAttributes.MemberAccessMask));
6232                                 }
6233
6234                                 //
6235                                 // Setup iterator if we are one
6236                                 //
6237                                 if (yields) {
6238                                         Iterator iterator = new Iterator (this, Parent as TypeContainer, null, ModFlags);
6239                                         
6240                                         if (!iterator.DefineIterator ())
6241                                                 return null;
6242                                 }
6243
6244                                 return null;
6245                         }
6246
6247                         public bool HasCustomAccessModifier
6248                         {
6249                                 get {
6250                                         return (ModFlags & Modifiers.PROPERTY_CUSTOM) != 0;
6251                                 }
6252                         }
6253
6254                         public override EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig)
6255                         {
6256                                 return new EmitContext (method,
6257                                         ds, method.ds, method.Location, ig, ReturnType,
6258                                         method.ModFlags, false);
6259                         }
6260
6261                         public override ObsoleteAttribute GetObsoleteAttribute ()
6262                         {
6263                                 return method.GetObsoleteAttribute ();
6264                         }
6265
6266                         public override string GetSignatureForError()
6267                         {
6268                                 return method.GetSignatureForError () + '.' + prefix.Substring (0, 3);
6269                         }
6270
6271                         void CheckModifiers (int modflags)
6272                         {
6273                                 int flags = 0;
6274                                 int mflags = method.ModFlags & Modifiers.Accessibility;
6275
6276                                 if ((mflags & Modifiers.PUBLIC) != 0) {
6277                                         flags |= Modifiers.PROTECTED | Modifiers.INTERNAL | Modifiers.PRIVATE;
6278                                 }
6279                                 else if ((mflags & Modifiers.PROTECTED) != 0) {
6280                                         if ((mflags & Modifiers.INTERNAL) != 0)
6281                                                 flags |= Modifiers.PROTECTED | Modifiers.INTERNAL;
6282
6283                                         flags |= Modifiers.PRIVATE;
6284                                 }
6285                                 else if ((mflags & Modifiers.INTERNAL) != 0)
6286                                         flags |= Modifiers.PRIVATE;
6287
6288                                 if ((mflags == modflags) || (modflags & (~flags)) != 0) {
6289                                         Report.Error (273, Location,
6290                                                 "The accessibility modifier of the `{0}' accessor must be more restrictive than the modifier of the property or indexer `{1}'",
6291                                                 GetSignatureForError (), method.GetSignatureForError ());
6292                                 }
6293                         }
6294
6295                         public override bool MarkForDuplicationCheck ()
6296                         {
6297                                 caching_flags |= Flags.TestMethodDuplication;
6298                                 return true;
6299                         }
6300                 }
6301
6302                 public PropertyMethod Get, Set;
6303                 public PropertyBuilder PropertyBuilder;
6304                 public MethodBuilder GetBuilder, SetBuilder;
6305
6306                 protected EmitContext ec;
6307
6308                 public PropertyBase (DeclSpace parent, Expression type, int mod_flags,
6309                                      int allowed_mod, bool is_iface, MemberName name,
6310                                      Parameters parameters, Attributes attrs)
6311                         : base (parent, null, type, mod_flags, allowed_mod, is_iface, name,
6312                                 attrs, parameters)
6313                 {
6314                 }
6315
6316                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
6317                 {
6318                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
6319                                 a.Error_InvalidSecurityParent ();
6320                                 return;
6321                         }
6322
6323                         PropertyBuilder.SetCustomAttribute (cb);
6324                 }
6325
6326                 public override AttributeTargets AttributeTargets {
6327                         get {
6328                                 return AttributeTargets.Property;
6329                         }
6330                 }
6331
6332                 public override bool Define ()
6333                 {
6334                         if (!DoDefine ())
6335                                 return false;
6336
6337                         if (!IsTypePermitted ())
6338                                 return false;
6339
6340                         return true;
6341                 }
6342
6343                 protected override bool DoDefine ()
6344                 {
6345                         if (!base.DoDefine ())
6346                                 return false;
6347
6348                         //
6349                         // Accessors modifiers check
6350                         //
6351                         if (Get.ModFlags != 0 && Set.ModFlags != 0) {
6352                                 Report.Error (274, Location, "`{0}': Cannot specify accessibility modifiers for both accessors of the property or indexer",
6353                                                 GetSignatureForError ());
6354                                 return false;
6355                         }
6356
6357                         if ((Get.IsDummy || Set.IsDummy)
6358                                         && (Get.ModFlags != 0 || Set.ModFlags != 0) && (ModFlags & Modifiers.OVERRIDE) == 0) {
6359                                 Report.Error (276, Location, 
6360                                         "`{0}': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor",
6361                                         GetSignatureForError ());
6362                                 return false;
6363                         }
6364
6365                         if (MemberType.IsAbstract && MemberType.IsSealed) {
6366                                 Report.Error (722, Location, Error722, TypeManager.CSharpName (MemberType));
6367                                 return false;
6368                         }
6369
6370                         ec = new EmitContext (this, Parent, Location, null, MemberType, ModFlags);
6371                         return true;
6372                 }
6373
6374                 protected override bool CheckForDuplications ()
6375                 {
6376                         ArrayList ar = ParentContainer.Indexers;
6377                         if (ar != null) {
6378                                 int arLen = ar.Count;
6379                                         
6380                                 for (int i = 0; i < arLen; i++) {
6381                                         Indexer m = (Indexer) ar [i];
6382                                         if (IsDuplicateImplementation (m))
6383                                                 return false;
6384                                 }
6385                         }
6386
6387                         ar = ParentContainer.Properties;
6388                         if (ar != null) {
6389                                 int arLen = ar.Count;
6390                                         
6391                                 for (int i = 0; i < arLen; i++) {
6392                                         Property m = (Property) ar [i];
6393                                         if (IsDuplicateImplementation (m))
6394                                                 return false;
6395                                 }
6396                         }
6397
6398                         return true;
6399                 }
6400
6401                 // TODO: rename to Resolve......
6402                 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
6403                 {
6404                         PropertyInfo base_property = ParentContainer.BaseCache.FindMemberToOverride (
6405                                 Parent.TypeBuilder, Name, ParameterTypes, null, true) as PropertyInfo;
6406
6407                         if (base_property == null)
6408                                 return null;
6409
6410                         base_ret_type = base_property.PropertyType;
6411                         MethodInfo get_accessor = base_property.GetGetMethod (true);
6412                         MethodInfo set_accessor = base_property.GetSetMethod (true);
6413                         MethodAttributes get_accessor_access, set_accessor_access;
6414
6415                         if ((ModFlags & Modifiers.OVERRIDE) != 0) {
6416                                 if (Get != null && !Get.IsDummy && get_accessor == null) {
6417                                         Report.SymbolRelatedToPreviousError (base_property);
6418                                         Report.Error (545, Location, "`{0}.get': cannot override because `{1}' does not have an overridable get accessor", GetSignatureForError (), TypeManager.GetFullNameSignature (base_property));
6419                                 }
6420
6421                                 if (Set != null && !Set.IsDummy && set_accessor == null) {
6422                                         Report.SymbolRelatedToPreviousError (base_property);
6423                                         Report.Error (546, Location, "`{0}.set': cannot override because `{1}' does not have an overridable set accessor", GetSignatureForError (), TypeManager.GetFullNameSignature (base_property));
6424                                 }
6425                         }
6426                         
6427                         //
6428                         // Check base class accessors access
6429                         //
6430
6431                         // TODO: rewrite to reuse Get|Set.CheckAccessModifiers and share code there
6432                         get_accessor_access = set_accessor_access = 0;
6433                         if ((ModFlags & Modifiers.NEW) == 0) {
6434                                 if (get_accessor != null) {
6435                                         MethodAttributes get_flags = Modifiers.MethodAttr (Get.ModFlags != 0 ? Get.ModFlags : ModFlags);
6436                                         get_accessor_access = (get_accessor.Attributes & MethodAttributes.MemberAccessMask);
6437
6438                                         if (!Get.IsDummy && !CheckAccessModifiers (get_flags & MethodAttributes.MemberAccessMask, get_accessor_access, get_accessor))
6439                                                 Error_CannotChangeAccessModifiers (get_accessor, get_accessor_access,  ".get");
6440                                 }
6441
6442                                 if (set_accessor != null)  {
6443                                         MethodAttributes set_flags = Modifiers.MethodAttr (Set.ModFlags != 0 ? Set.ModFlags : ModFlags);
6444                                         set_accessor_access = (set_accessor.Attributes & MethodAttributes.MemberAccessMask);
6445
6446                                         if (!Set.IsDummy && !CheckAccessModifiers (set_flags & MethodAttributes.MemberAccessMask, set_accessor_access, set_accessor))
6447                                                 Error_CannotChangeAccessModifiers (set_accessor, set_accessor_access, ".set");
6448                                 }
6449                         }
6450
6451                         //
6452                         // Get the less restrictive access
6453                         //
6454                         return get_accessor_access > set_accessor_access ? get_accessor : set_accessor;
6455                 }
6456
6457                 public override void Emit ()
6458                 {
6459                         //
6460                         // The PropertyBuilder can be null for explicit implementations, in that
6461                         // case, we do not actually emit the ".property", so there is nowhere to
6462                         // put the attribute
6463                         //
6464                         if (PropertyBuilder != null && OptAttributes != null)
6465                                 OptAttributes.Emit ();
6466
6467                         if (!Get.IsDummy)
6468                                 Get.Emit (Parent);
6469
6470                         if (!Set.IsDummy)
6471                                 Set.Emit (Parent);
6472
6473                         base.Emit ();
6474                 }
6475
6476                 /// <summary>
6477                 /// Tests whether accessors are not in collision with some method (CS0111)
6478                 /// </summary>
6479                 public bool AreAccessorsDuplicateImplementation (MethodCore mc)
6480                 {
6481                         return Get.IsDuplicateImplementation (mc) || Set.IsDuplicateImplementation (mc);
6482                 }
6483
6484                 public override bool IsUsed
6485                 {
6486                         get {
6487                                 if (IsExplicitImpl)
6488                                         return true;
6489
6490                                 return Get.IsUsed | Set.IsUsed;
6491                         }
6492                 }
6493
6494                 protected override void SetMemberName (MemberName new_name)
6495                 {
6496                         base.SetMemberName (new_name);
6497
6498                         Get.UpdateName (this);
6499                         Set.UpdateName (this);
6500                 }
6501
6502                 public override string[] ValidAttributeTargets {
6503                         get {
6504                                 return attribute_targets;
6505                         }
6506                 }
6507
6508                 //
6509                 //   Represents header string for documentation comment.
6510                 //
6511                 public override string DocCommentHeader {
6512                         get { return "P:"; }
6513                 }
6514         }
6515                         
6516         public class Property : PropertyBase {
6517                 const int AllowedModifiers =
6518                         Modifiers.NEW |
6519                         Modifiers.PUBLIC |
6520                         Modifiers.PROTECTED |
6521                         Modifiers.INTERNAL |
6522                         Modifiers.PRIVATE |
6523                         Modifiers.STATIC |
6524                         Modifiers.SEALED |
6525                         Modifiers.OVERRIDE |
6526                         Modifiers.ABSTRACT |
6527                         Modifiers.UNSAFE |
6528                         Modifiers.EXTERN |
6529                         Modifiers.METHOD_YIELDS |
6530                         Modifiers.VIRTUAL;
6531
6532                 const int AllowedInterfaceModifiers =
6533                         Modifiers.NEW;
6534
6535                 public Property (DeclSpace parent, Expression type, int mod, bool is_iface,
6536                                  MemberName name, Attributes attrs, Accessor get_block,
6537                                  Accessor set_block)
6538                         : base (parent, type, mod,
6539                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
6540                                 is_iface, name, Parameters.EmptyReadOnlyParameters, attrs)
6541                 {
6542                         if (get_block == null)
6543                                 Get = new GetMethod (this);
6544                         else
6545                                 Get = new GetMethod (this, get_block);
6546
6547                         if (set_block == null)
6548                                 Set = new SetMethod (this);
6549                         else
6550                                 Set = new SetMethod (this, set_block);
6551                 }
6552
6553                 public override bool Define ()
6554                 {
6555                         if (!DoDefineBase ())
6556                                 return false;
6557
6558                         if (!base.Define ())
6559                                 return false;
6560
6561                         if (!CheckBase ())
6562                                 return false;
6563
6564                         flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
6565
6566                         if (!Get.IsDummy) {
6567                                 GetBuilder = Get.Define (Parent);
6568                                 if (GetBuilder == null)
6569                                         return false;
6570                         }
6571
6572                         SetBuilder = Set.Define (Parent);
6573                         if (!Set.IsDummy) {
6574                                 if (SetBuilder == null)
6575                                         return false;
6576                         }
6577
6578                         // FIXME - PropertyAttributes.HasDefault ?
6579
6580                         PropertyBuilder = Parent.TypeBuilder.DefineProperty (
6581                                 MemberName.ToString (), PropertyAttributes.None, MemberType, null);
6582
6583                         if (!Get.IsDummy)
6584                                 PropertyBuilder.SetGetMethod (GetBuilder);
6585
6586                         if (!Set.IsDummy)
6587                                 PropertyBuilder.SetSetMethod (SetBuilder);
6588
6589                         TypeManager.RegisterProperty (PropertyBuilder, this);
6590                         return true;
6591                 }
6592         }
6593
6594         /// </summary>
6595         ///  Gigantic workaround  for lameness in SRE follows :
6596         ///  This class derives from EventInfo and attempts to basically
6597         ///  wrap around the EventBuilder so that FindMembers can quickly
6598         ///  return this in it search for members
6599         /// </summary>
6600         public class MyEventBuilder : EventInfo {
6601                 
6602                 //
6603                 // We use this to "point" to our Builder which is
6604                 // not really a MemberInfo
6605                 //
6606                 EventBuilder MyBuilder;
6607                 
6608                 //
6609                 // We "catch" and wrap these methods
6610                 //
6611                 MethodInfo raise, remove, add;
6612
6613                 EventAttributes attributes;
6614                 Type declaring_type, reflected_type, event_type;
6615                 string name;
6616
6617                 Event my_event;
6618
6619                 public MyEventBuilder (Event ev, TypeBuilder type_builder, string name, EventAttributes event_attr, Type event_type)
6620                 {
6621                         MyBuilder = type_builder.DefineEvent (name, event_attr, event_type);
6622
6623                         // And now store the values in our own fields.
6624                         
6625                         declaring_type = type_builder;
6626
6627                         reflected_type = type_builder;
6628                         
6629                         attributes = event_attr;
6630                         this.name = name;
6631                         my_event = ev;
6632                         this.event_type = event_type;
6633                 }
6634                 
6635                 //
6636                 // Methods that you have to override.  Note that you only need 
6637                 // to "implement" the variants that take the argument (those are
6638                 // the "abstract" methods, the others (GetAddMethod()) are 
6639                 // regular.
6640                 //
6641                 public override MethodInfo GetAddMethod (bool nonPublic)
6642                 {
6643                         return add;
6644                 }
6645                 
6646                 public override MethodInfo GetRemoveMethod (bool nonPublic)
6647                 {
6648                         return remove;
6649                 }
6650                 
6651                 public override MethodInfo GetRaiseMethod (bool nonPublic)
6652                 {
6653                         return raise;
6654                 }
6655                 
6656                 //
6657                 // These methods make "MyEventInfo" look like a Builder
6658                 //
6659                 public void SetRaiseMethod (MethodBuilder raiseMethod)
6660                 {
6661                         raise = raiseMethod;
6662                         MyBuilder.SetRaiseMethod (raiseMethod);
6663                 }
6664
6665                 public void SetRemoveOnMethod (MethodBuilder removeMethod)
6666                 {
6667                         remove = removeMethod;
6668                         MyBuilder.SetRemoveOnMethod (removeMethod);
6669                 }
6670
6671                 public void SetAddOnMethod (MethodBuilder addMethod)
6672                 {
6673                         add = addMethod;
6674                         MyBuilder.SetAddOnMethod (addMethod);
6675                 }
6676
6677                 public void SetCustomAttribute (CustomAttributeBuilder cb)
6678                 {
6679                         MyBuilder.SetCustomAttribute (cb);
6680                 }
6681                 
6682                 public override object [] GetCustomAttributes (bool inherit)
6683                 {
6684                         // FIXME : There's nothing which can be seemingly done here because
6685                         // we have no way of getting at the custom attribute objects of the
6686                         // EventBuilder !
6687                         return null;
6688                 }
6689
6690                 public override object [] GetCustomAttributes (Type t, bool inherit)
6691                 {
6692                         // FIXME : Same here !
6693                         return null;
6694                 }
6695
6696                 public override bool IsDefined (Type t, bool b)
6697                 {
6698                         return true;
6699                 }
6700
6701                 public override EventAttributes Attributes {
6702                         get {
6703                                 return attributes;
6704                         }
6705                 }
6706
6707                 public override string Name {
6708                         get {
6709                                 return name;
6710                         }
6711                 }
6712
6713                 public override Type DeclaringType {
6714                         get {
6715                                 return declaring_type;
6716                         }
6717                 }
6718
6719                 public override Type ReflectedType {
6720                         get {
6721                                 return reflected_type;
6722                         }
6723                 }
6724
6725                 public Type EventType {
6726                         get {
6727                                 return event_type;
6728                         }
6729                 }
6730                 
6731                 public void SetUsed ()
6732                 {
6733                         if (my_event != null) {
6734                                 my_event.SetAssigned ();
6735                                 my_event.SetMemberIsUsed ();
6736                         }
6737                 }
6738         }
6739         
6740         /// <summary>
6741         /// For case when event is declared like property (with add and remove accessors).
6742         /// </summary>
6743         public class EventProperty: Event {
6744
6745                 static string[] attribute_targets = new string [] { "event" }; // "property" target was disabled for 2.0 version
6746
6747                 public EventProperty (DeclSpace parent, Expression type, int mod_flags,
6748                                       bool is_iface, MemberName name,
6749                                       Attributes attrs, Accessor add, Accessor remove)
6750                         : base (parent, type, mod_flags, is_iface, name, attrs)
6751                 {
6752                         Add = new AddDelegateMethod (this, add);
6753                         Remove = new RemoveDelegateMethod (this, remove);
6754
6755                         // For this event syntax we don't report error CS0067
6756                         // because it is hard to do it.
6757                         SetAssigned ();
6758                 }
6759
6760                 public override string[] ValidAttributeTargets {
6761                         get {
6762                                 return attribute_targets;
6763                         }
6764                 }
6765         }
6766
6767         /// <summary>
6768         /// Event is declared like field.
6769         /// </summary>
6770         public class EventField : Event {
6771
6772                 static string[] attribute_targets = new string [] { "event", "field", "method" };
6773                 static string[] attribute_targets_interface = new string[] { "event", "method" };
6774
6775                 public EventField (DeclSpace parent, Expression type, int mod_flags,
6776                                    bool is_iface, MemberName name,
6777                                    Attributes attrs)
6778                         : base (parent, type, mod_flags, is_iface, name, attrs)
6779                 {
6780                         Add = new AddDelegateMethod (this);
6781                         Remove = new RemoveDelegateMethod (this);
6782                 }
6783
6784                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
6785                 {
6786                         if (a.Target == AttributeTargets.Field) {
6787                                 FieldBuilder.SetCustomAttribute (cb);
6788                                 return;
6789                         }
6790
6791                         if (a.Target == AttributeTargets.Method) {
6792                                 Add.ApplyAttributeBuilder (a, cb);
6793                                 Remove.ApplyAttributeBuilder (a, cb);
6794                                 return;
6795                         }
6796
6797                         base.ApplyAttributeBuilder (a, cb);
6798                 }
6799
6800                 public override bool Define()
6801                 {
6802                         if (!base.Define ())
6803                                 return false;
6804
6805                         if (initializer != null) {
6806                                 if (((ModFlags & Modifiers.ABSTRACT) != 0)) {
6807                                         Report.Error (74, Location, "`{0}': abstract event cannot have an initializer",
6808                                                 GetSignatureForError ());
6809                                         return false;
6810                                 }
6811                         }
6812
6813                         return true;
6814                 }
6815
6816                 public override string[] ValidAttributeTargets {
6817                         get {
6818                                 return IsInterface ? attribute_targets_interface : attribute_targets;
6819                         }
6820                 }
6821         }
6822
6823         public abstract class Event : FieldBase {
6824
6825                 protected sealed class AddDelegateMethod: DelegateMethod
6826                 {
6827
6828                         public AddDelegateMethod (Event method):
6829                                 base (method, "add_")
6830                         {
6831                         }
6832
6833                         public AddDelegateMethod (Event method, Accessor accessor):
6834                                 base (method, accessor, "add_")
6835                         {
6836                         }
6837
6838                         protected override MethodInfo DelegateMethodInfo {
6839                                 get {
6840                                         return TypeManager.delegate_combine_delegate_delegate;
6841                                 }
6842                         }
6843
6844                 }
6845
6846                 protected sealed class RemoveDelegateMethod: DelegateMethod
6847                 {
6848                         public RemoveDelegateMethod (Event method):
6849                                 base (method, "remove_")
6850                         {
6851                         }
6852
6853                         public RemoveDelegateMethod (Event method, Accessor accessor):
6854                                 base (method, accessor, "remove_")
6855                         {
6856                         }
6857
6858                         protected override MethodInfo DelegateMethodInfo {
6859                                 get {
6860                                         return TypeManager.delegate_remove_delegate_delegate;
6861                                 }
6862                         }
6863
6864                 }
6865
6866                 public abstract class DelegateMethod : AbstractPropertyEventMethod
6867                 {
6868                         protected readonly Event method;
6869                         ImplicitParameter param_attr;
6870
6871                         static string[] attribute_targets = new string [] { "method", "param", "return" };
6872
6873                         public DelegateMethod (Event method, string prefix)
6874                                 : base (method, prefix)
6875                         {
6876                                 this.method = method;
6877                         }
6878
6879                         public DelegateMethod (Event method, Accessor accessor, string prefix)
6880                                 : base (method, accessor, prefix)
6881                         {
6882                                 this.method = method;
6883                         }
6884
6885                         protected override void ApplyToExtraTarget(Attribute a, CustomAttributeBuilder cb)
6886                         {
6887                                 if (a.Target == AttributeTargets.Parameter) {
6888                                         if (param_attr == null)
6889                                                 param_attr = new ImplicitParameter (method_data.MethodBuilder);
6890
6891                                         param_attr.ApplyAttributeBuilder (a, cb);
6892                                         return;
6893                                 }
6894
6895                                 base.ApplyAttributeBuilder (a, cb);
6896                         }
6897
6898                         public override AttributeTargets AttributeTargets {
6899                                 get {
6900                                         return AttributeTargets.Method;
6901                                 }
6902                         }
6903
6904                         public override bool IsClsComplianceRequired ()
6905                         {
6906                                 return method.IsClsComplianceRequired ();
6907                         }
6908
6909                         public MethodBuilder Define (DeclSpace parent)
6910                         {
6911                                 method_data = new MethodData (method, method.ModFlags,
6912                                         method.flags | MethodAttributes.HideBySig | MethodAttributes.SpecialName, this);
6913
6914                                 if (!method_data.Define (parent))
6915                                         return null;
6916
6917                                 MethodBuilder mb = method_data.MethodBuilder;
6918                                 ParameterInfo.ApplyAttributes (mb);
6919                                 return mb;
6920                         }
6921
6922
6923                         protected override void EmitMethod (DeclSpace parent)
6924                         {
6925                                 if (block != null) {
6926                                         base.EmitMethod (parent);
6927                                         return;
6928                                 }
6929
6930                                 if ((method.ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
6931                                         return;
6932
6933                                 ILGenerator ig = method_data.MethodBuilder.GetILGenerator ();
6934                                 FieldInfo field_info = (FieldInfo)method.FieldBuilder;
6935
6936                                 method_data.MethodBuilder.SetImplementationFlags (MethodImplAttributes.Synchronized);
6937                                 if ((method.ModFlags & Modifiers.STATIC) != 0) {
6938                                         ig.Emit (OpCodes.Ldsfld, field_info);
6939                                         ig.Emit (OpCodes.Ldarg_0);
6940                                         ig.Emit (OpCodes.Call, DelegateMethodInfo);
6941                                         ig.Emit (OpCodes.Castclass, method.MemberType);
6942                                         ig.Emit (OpCodes.Stsfld, field_info);
6943                                 } else {
6944                                         ig.Emit (OpCodes.Ldarg_0);
6945                                         ig.Emit (OpCodes.Ldarg_0);
6946                                         ig.Emit (OpCodes.Ldfld, field_info);
6947                                         ig.Emit (OpCodes.Ldarg_1);
6948                                         ig.Emit (OpCodes.Call, DelegateMethodInfo);
6949                                         ig.Emit (OpCodes.Castclass, method.MemberType);
6950                                         ig.Emit (OpCodes.Stfld, field_info);
6951                                 }
6952                                 ig.Emit (OpCodes.Ret);
6953                         }
6954
6955                         protected abstract MethodInfo DelegateMethodInfo { get; }
6956
6957                         public override Type ReturnType {
6958                                 get {
6959                                         return TypeManager.void_type;
6960                                 }
6961                         }
6962
6963                         public override EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig)
6964                         {
6965                                 return new EmitContext (
6966                                         ds, method.Parent, Location, ig, ReturnType,
6967                                         method.ModFlags, false);
6968                         }
6969
6970                         public override ObsoleteAttribute GetObsoleteAttribute ()
6971                         {
6972                                 return method.GetObsoleteAttribute ();
6973                         }
6974
6975                         public override string[] ValidAttributeTargets {
6976                                 get {
6977                                         return attribute_targets;
6978                                 }
6979                         }
6980
6981                         public override Parameters ParameterInfo {
6982                                 get {
6983                                         return method.parameters;
6984                                 }
6985                         }
6986
6987                 }
6988
6989
6990                 const int AllowedModifiers =
6991                         Modifiers.NEW |
6992                         Modifiers.PUBLIC |
6993                         Modifiers.PROTECTED |
6994                         Modifiers.INTERNAL |
6995                         Modifiers.PRIVATE |
6996                         Modifiers.STATIC |
6997                         Modifiers.VIRTUAL |
6998                         Modifiers.SEALED |
6999                         Modifiers.OVERRIDE |
7000                         Modifiers.UNSAFE |
7001                         Modifiers.ABSTRACT;
7002
7003                 const int AllowedInterfaceModifiers =
7004                         Modifiers.NEW;
7005
7006                 public DelegateMethod Add, Remove;
7007                 public MyEventBuilder     EventBuilder;
7008                 public MethodBuilder AddBuilder, RemoveBuilder;
7009                 Parameters parameters;
7010
7011                 protected Event (DeclSpace parent, Expression type, int mod_flags,
7012                               bool is_iface, MemberName name, Attributes attrs)
7013                         : base (parent, type, mod_flags,
7014                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
7015                                 name, attrs)
7016                 {
7017                         IsInterface = is_iface;
7018                 }
7019
7020                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
7021                 {
7022                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
7023                                 a.Error_InvalidSecurityParent ();
7024                                 return;
7025                         }
7026                         
7027                         EventBuilder.SetCustomAttribute (cb);
7028                 }
7029
7030                 public bool AreAccessorsDuplicateImplementation (MethodCore mc)
7031                 {
7032                         return Add.IsDuplicateImplementation (mc) || Remove.IsDuplicateImplementation (mc);
7033                 }
7034
7035                 public override AttributeTargets AttributeTargets {
7036                         get {
7037                                 return AttributeTargets.Event;
7038                         }
7039                 }
7040   
7041                 public override bool Define ()
7042                 {
7043                         EventAttributes e_attr;
7044                         e_attr = EventAttributes.None;
7045
7046                         if (!DoDefineBase ())
7047                                 return false;
7048
7049                         if (!DoDefine ())
7050                                 return false;
7051
7052                         if (!TypeManager.IsDelegateType (MemberType)) {
7053                                 Report.Error (66, Location, "`{0}': event must be of a delegate type", GetSignatureForError ());
7054                                 return false;
7055                         }
7056
7057                         parameters = new Parameters (
7058                                 new Parameter[] { new Parameter (MemberType, "value", Parameter.Modifier.NONE, null, Location) },
7059                                 new Type[] { MemberType } );
7060
7061                         if (!CheckBase ())
7062                                 return false;
7063
7064                         //
7065                         // Now define the accessors
7066                         //
7067
7068                         AddBuilder = Add.Define (Parent);
7069                         if (AddBuilder == null)
7070                                 return false;
7071
7072                         RemoveBuilder = Remove.Define (Parent);
7073                         if (RemoveBuilder == null)
7074                                 return false;
7075
7076                         EventBuilder = new MyEventBuilder (this, Parent.TypeBuilder, Name, e_attr, MemberType);
7077                         
7078                         if (Add.Block == null && Remove.Block == null && !IsInterface) {
7079                                 FieldBuilder = Parent.TypeBuilder.DefineField (
7080                                         Name, MemberType,
7081                                         FieldAttributes.Private | ((ModFlags & Modifiers.STATIC) != 0 ? FieldAttributes.Static : 0));
7082                                 TypeManager.RegisterPrivateFieldOfEvent (
7083                                         (EventInfo) EventBuilder, FieldBuilder);
7084                                 TypeManager.RegisterFieldBase (FieldBuilder, this);
7085                         }
7086                         
7087                         EventBuilder.SetAddOnMethod (AddBuilder);
7088                         EventBuilder.SetRemoveOnMethod (RemoveBuilder);
7089
7090                         TypeManager.RegisterEvent (EventBuilder, AddBuilder, RemoveBuilder);
7091                         return true;
7092                 }
7093
7094                 protected override bool CheckBase ()
7095                 {
7096                         if (!base.CheckBase ())
7097                                 return false;
7098  
7099                         if (conflict_symbol != null && (ModFlags & Modifiers.NEW) == 0) {
7100                                 if (!(conflict_symbol is EventInfo)) {
7101                                         Report.SymbolRelatedToPreviousError (conflict_symbol);
7102                                         Report.Error (72, Location, "Event `{0}' can override only event", GetSignatureForError ());
7103                                         return false;
7104                                 }
7105                         }
7106  
7107                         return true;
7108                 }
7109
7110                 public override void Emit ()
7111                 {
7112                         if (OptAttributes != null) {
7113                                 OptAttributes.Emit ();
7114                         }
7115
7116                         Add.Emit (Parent);
7117                         Remove.Emit (Parent);
7118
7119                         base.Emit ();
7120                 }
7121
7122                 public override string GetSignatureForError ()
7123                 {
7124                         return base.GetSignatureForError ();
7125                 }
7126
7127                 //
7128                 //   Represents header string for documentation comment.
7129                 //
7130                 public override string DocCommentHeader {
7131                         get { return "E:"; }
7132                 }
7133         }
7134
7135  
7136         public class Indexer : PropertyBase, IIteratorContainer {
7137
7138                 class GetIndexerMethod : GetMethod
7139                 {
7140                         public GetIndexerMethod (MethodCore method):
7141                                 base (method)
7142                         {
7143                         }
7144
7145                         public GetIndexerMethod (MethodCore method, Accessor accessor):
7146                                 base (method, accessor)
7147                         {
7148                         }
7149
7150                         public override Parameters ParameterInfo {
7151                                 get {
7152                                         return method.ParameterInfo;
7153                                 }
7154                         }
7155                 }
7156
7157                 class SetIndexerMethod: SetMethod
7158                 {
7159                         public SetIndexerMethod (MethodCore method):
7160                                 base (method)
7161                         {
7162                         }
7163
7164                         public SetIndexerMethod (MethodCore method, Accessor accessor):
7165                                 base (method, accessor)
7166                         {
7167                         }
7168
7169                         protected override void DefineParameters ()
7170                         {
7171                                 parameters = Parameters.MergeGenerated (method.Parameters,
7172                                         new Parameter (method.MemberType, "value", Parameter.Modifier.NONE, null, method.Location));
7173                         }
7174                 }
7175
7176                 const int AllowedModifiers =
7177                         Modifiers.NEW |
7178                         Modifiers.PUBLIC |
7179                         Modifiers.PROTECTED |
7180                         Modifiers.INTERNAL |
7181                         Modifiers.PRIVATE |
7182                         Modifiers.VIRTUAL |
7183                         Modifiers.SEALED |
7184                         Modifiers.OVERRIDE |
7185                         Modifiers.UNSAFE |
7186                         Modifiers.EXTERN |
7187                         Modifiers.ABSTRACT;
7188
7189                 const int AllowedInterfaceModifiers =
7190                         Modifiers.NEW;
7191
7192                 //
7193                 // Are we implementing an interface ?
7194                 //
7195                 public Indexer (DeclSpace parent, Expression type, MemberName name, int mod,
7196                                 bool is_iface, Parameters parameters, Attributes attrs,
7197                                 Accessor get_block, Accessor set_block)
7198                         : base (parent, type, mod,
7199                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
7200                                 is_iface, name, parameters, attrs)
7201                 {
7202                         if (get_block == null)
7203                                 Get = new GetIndexerMethod (this);
7204                         else
7205                                 Get = new GetIndexerMethod (this, get_block);
7206
7207                         if (set_block == null)
7208                                 Set = new SetIndexerMethod (this);
7209                         else
7210                                 Set = new SetIndexerMethod (this, set_block);
7211                 }
7212                        
7213                 public override bool Define ()
7214                 {
7215                         if (!DoDefineBase ())
7216                                 return false;
7217
7218                         if (!base.Define ())
7219                                 return false;
7220
7221                         if (MemberType == TypeManager.void_type) {
7222                                 Report.Error (620, Location, "Indexers cannot have void type");
7223                                 return false;
7224                         }
7225
7226                         if (OptAttributes != null) {
7227                                 Attribute indexer_attr = OptAttributes.Search (TypeManager.indexer_name_type);
7228                                 if (indexer_attr != null) {
7229                                         // Remove the attribute from the list because it is not emitted
7230                                         OptAttributes.Attrs.Remove (indexer_attr);
7231
7232                                         string name = indexer_attr.GetIndexerAttributeValue ();
7233                                         if (name == null)
7234                                                 return false;
7235
7236                                         ShortName = name;
7237
7238                                         if (IsExplicitImpl) {
7239                                                 Report.Error (415, indexer_attr.Location,
7240                                                               "The `IndexerName' attribute is valid only on an " +
7241                                                               "indexer that is not an explicit interface member declaration");
7242                                                 return false;
7243                                         }
7244
7245                                         if ((ModFlags & Modifiers.OVERRIDE) != 0) {
7246                                                 Report.Error (609, indexer_attr.Location,
7247                                                               "Cannot set the `IndexerName' attribute on an indexer marked override");
7248                                                 return false;
7249                                         }
7250                                 }
7251                         }
7252
7253                         if (InterfaceType != null) {
7254                                 string base_IndexerName = TypeManager.IndexerPropertyName (InterfaceType);
7255                                 if (base_IndexerName != Name)
7256                                         ShortName = base_IndexerName;
7257                         }
7258
7259                         if (!ParentContainer.AddToMemberContainer (this) ||
7260                                 !ParentContainer.AddToMemberContainer (Get) || !ParentContainer.AddToMemberContainer (Set))
7261                                 return false;
7262
7263                         if (!CheckBase ())
7264                                 return false;
7265
7266                         flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
7267                         if (!Get.IsDummy){
7268                                 GetBuilder = Get.Define (Parent);
7269                                 if (GetBuilder == null)
7270                                         return false;
7271
7272                                 //
7273                                 // Setup iterator if we are one
7274                                 //
7275                                 if ((ModFlags & Modifiers.METHOD_YIELDS) != 0){
7276                                         Iterator iterator = new Iterator (
7277                                                 Get, Parent, null, ModFlags);
7278
7279                                         if (!iterator.DefineIterator ())
7280                                                 return false;
7281                                 }
7282                         }
7283                         
7284                         SetBuilder = Set.Define (Parent);
7285                         if (!Set.IsDummy){
7286                                 if (SetBuilder == null)
7287                                         return false;
7288                         }
7289
7290                         //
7291                         // Now name the parameters
7292                         //
7293                         Parameter [] p = Parameters.FixedParameters;
7294                         if (p != null) {
7295                                 // TODO: should be done in parser and it needs to do cycle
7296                                 if ((p [0].ModFlags & Parameter.Modifier.ISBYREF) != 0) {
7297                                         Report.Error (631, Location, "ref and out are not valid in this context");
7298                                         return false;
7299                                 }
7300                         }
7301
7302                         PropertyBuilder = Parent.TypeBuilder.DefineProperty (
7303                                 Name, PropertyAttributes.None, MemberType, ParameterTypes);
7304                         
7305                         if (!Get.IsDummy)
7306                                 PropertyBuilder.SetGetMethod (GetBuilder);
7307
7308                         if (!Set.IsDummy)
7309                                 PropertyBuilder.SetSetMethod (SetBuilder);
7310                                 
7311                         TypeManager.RegisterIndexer (PropertyBuilder, GetBuilder, SetBuilder, ParameterTypes);
7312
7313                         return true;
7314                 }
7315
7316                 public override string GetSignatureForError ()
7317                 {
7318                         StringBuilder sb = new StringBuilder (Parent.GetSignatureForError ());
7319                         if (MemberName.Left != null) {
7320                                 sb.Append ('.');
7321                                 sb.Append (MemberName.Left);
7322                         }
7323
7324                         sb.Append (".this");
7325                         sb.Append (Parameters.GetSignatureForError ().Replace ('(', '[').Replace (')', ']'));
7326                         return sb.ToString ();
7327                 }
7328
7329                 public override bool MarkForDuplicationCheck ()
7330                 {
7331                         caching_flags |= Flags.TestMethodDuplication;
7332                         return true;
7333                 }
7334         }
7335
7336         public class Operator : MethodOrOperator, IIteratorContainer {
7337
7338                 const int AllowedModifiers =
7339                         Modifiers.PUBLIC |
7340                         Modifiers.UNSAFE |
7341                         Modifiers.EXTERN |
7342                         Modifiers.STATIC;
7343
7344                 public enum OpType : byte {
7345
7346                         // Unary operators
7347                         LogicalNot,
7348                         OnesComplement,
7349                         Increment,
7350                         Decrement,
7351                         True,
7352                         False,
7353
7354                         // Unary and Binary operators
7355                         Addition,
7356                         Subtraction,
7357
7358                         UnaryPlus,
7359                         UnaryNegation,
7360                         
7361                         // Binary operators
7362                         Multiply,
7363                         Division,
7364                         Modulus,
7365                         BitwiseAnd,
7366                         BitwiseOr,
7367                         ExclusiveOr,
7368                         LeftShift,
7369                         RightShift,
7370                         Equality,
7371                         Inequality,
7372                         GreaterThan,
7373                         LessThan,
7374                         GreaterThanOrEqual,
7375                         LessThanOrEqual,
7376
7377                         // Implicit and Explicit
7378                         Implicit,
7379                         Explicit,
7380
7381                         // Just because of enum
7382                         TOP
7383                 };
7384
7385                 public readonly OpType OperatorType;
7386                 
7387                 public Operator (DeclSpace parent, OpType type, Expression ret_type,
7388                                  int mod_flags, Parameters parameters,
7389                                  ToplevelBlock block, Attributes attrs, Location loc)
7390                         : base (parent, null, ret_type, mod_flags, AllowedModifiers, false,
7391                                 new MemberName ("op_" + type, loc), attrs, parameters)
7392                 {
7393                         OperatorType = type;
7394                         Block = block;
7395                 }
7396
7397                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb) 
7398                 {
7399                         if (a.Type == TypeManager.conditional_attribute_type) {
7400                                 Error_ConditionalAttributeIsNotValid ();
7401                                 return;
7402                         }
7403
7404                         base.ApplyAttributeBuilder (a, cb);
7405                 }
7406                 
7407                 protected override bool CheckForDuplications ()
7408                 {
7409                         ArrayList ar = ParentContainer.Operators;
7410                         if (ar != null) {
7411                                 int arLen = ar.Count;
7412
7413                                 for (int i = 0; i < arLen; i++) {
7414                                         Operator o = (Operator) ar [i];
7415                                         if (IsDuplicateImplementation (o))
7416                                                 return false;
7417                                 }
7418                         }
7419
7420                         ar = ParentContainer.Methods;
7421                         if (ar != null) {
7422                                 int arLen = ar.Count;
7423
7424                                 for (int i = 0; i < arLen; i++) {
7425                                         Method m = (Method) ar [i];
7426                                         if (IsDuplicateImplementation (m))
7427                                                 return false;
7428                                 }
7429                         }
7430
7431                         return true;
7432                 }
7433
7434                 public override bool Define ()
7435                 {
7436                         const int RequiredModifiers = Modifiers.PUBLIC | Modifiers.STATIC;
7437                         if ((ModFlags & RequiredModifiers) != RequiredModifiers){
7438                                 Report.Error (558, Location, "User-defined operator `{0}' must be declared static and public", GetSignatureForError ());
7439                                 return false;
7440                         }
7441
7442                         if (!base.Define ())
7443                                 return false;
7444
7445                         if (MemberType == TypeManager.void_type) {
7446                                 Report.Error (590, Location, "User-defined operators cannot return void");
7447                                 return false;
7448                         }
7449
7450                         Type declaring_type = MethodData.DeclaringType;
7451                         Type return_type = MemberType;
7452                         Type first_arg_type = ParameterTypes [0];
7453
7454                         // Rules for conversion operators
7455                         
7456                         if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
7457                                 if (first_arg_type == return_type && first_arg_type == declaring_type){
7458                                         Report.Error (555, Location,
7459                                                 "User-defined operator cannot take an object of the enclosing type and convert to an object of the enclosing type");
7460                                         return false;
7461                                 }
7462                                 
7463                                 if (first_arg_type != declaring_type && return_type != declaring_type){
7464                                         Report.Error (
7465                                                 556, Location, 
7466                                                 "User-defined conversion must convert to or from the " +
7467                                                 "enclosing type");
7468                                         return false;
7469                                 }
7470
7471                                 if (first_arg_type.IsInterface || return_type.IsInterface){
7472                                         Report.Error (552, Location, "User-defined conversion `{0}' cannot convert to or from an interface type",
7473                                                 GetSignatureForError ());
7474                                         return false;
7475                                 }
7476                                 
7477                                 if (first_arg_type.IsSubclassOf (return_type) || return_type.IsSubclassOf (first_arg_type)) {
7478                                         if (declaring_type.IsSubclassOf (return_type) || declaring_type.IsSubclassOf (first_arg_type)) {
7479                                                 Report.Error (553, Location, "User-defined conversion `{0}' cannot convert to or from base class",
7480                                                         GetSignatureForError ());
7481                                                 return false;
7482                                         }
7483                                         Report.Error (554, Location, "User-defined conversion `{0}' cannot convert to or from derived class",
7484                                                 GetSignatureForError ());
7485                                         return false;
7486                                 }
7487                         } else if (OperatorType == OpType.LeftShift || OperatorType == OpType.RightShift) {
7488                                 if (first_arg_type != declaring_type || ParameterTypes [1] != TypeManager.int32_type) {
7489                                         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");
7490                                         return false;
7491                                 }
7492                         } else if (Parameters.Count == 1) {
7493                                 // Checks for Unary operators
7494
7495                                 if (OperatorType == OpType.Increment || OperatorType == OpType.Decrement) {
7496                                         if (return_type != declaring_type && !TypeManager.IsSubclassOf (return_type, declaring_type)) {
7497                                                 Report.Error (448, Location,
7498                                                         "The return type for ++ or -- operator must be the containing type or derived from the containing type");
7499                                                 return false;
7500                                         }
7501                                         if (first_arg_type != declaring_type) {
7502                                                 Report.Error (
7503                                                         559, Location, "The parameter type for ++ or -- operator must be the containing type");
7504                                                 return false;
7505                                         }
7506                                 }
7507                                 
7508                                 if (first_arg_type != declaring_type){
7509                                         Report.Error (
7510                                                 562, Location,
7511                                                 "The parameter of a unary operator must be the " +
7512                                                 "containing type");
7513                                         return false;
7514                                 }
7515                                 
7516                                 if (OperatorType == OpType.True || OperatorType == OpType.False) {
7517                                         if (return_type != TypeManager.bool_type){
7518                                                 Report.Error (
7519                                                         215, Location,
7520                                                         "The return type of operator True or False " +
7521                                                         "must be bool");
7522                                                 return false;
7523                                         }
7524                                 }
7525                                 
7526                         } else {
7527                                 // Checks for Binary operators
7528                                 
7529                                 if (first_arg_type != declaring_type &&
7530                                     ParameterTypes [1] != declaring_type){
7531                                         Report.Error (
7532                                                 563, Location,
7533                                                 "One of the parameters of a binary operator must " +
7534                                                 "be the containing type");
7535                                         return false;
7536                                 }
7537                         }
7538
7539                         return true;
7540                 }
7541
7542                 protected override bool DoDefine ()
7543                 {
7544                         if (!base.DoDefine ())
7545                                 return false;
7546
7547                         flags |= MethodAttributes.SpecialName | MethodAttributes.HideBySig;
7548                         return true;
7549                 }
7550                 
7551                 public override void Emit ()
7552                 {
7553                         base.Emit ();
7554
7555                         Parameters.ApplyAttributes (MethodBuilder);
7556
7557                         //
7558                         // abstract or extern methods have no bodies
7559                         //
7560                         if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
7561                                 return;
7562                         
7563                         EmitContext ec;
7564                         if ((flags & MethodAttributes.PinvokeImpl) == 0)
7565                                 ec = CreateEmitContext (Parent, MethodBuilder.GetILGenerator ());
7566                         else
7567                                 ec = CreateEmitContext (Parent, null);
7568                         
7569                         SourceMethod source = SourceMethod.Create (Parent, MethodBuilder, Block);
7570                         ec.EmitTopBlock (this, Block);
7571
7572                         if (source != null)
7573                                 source.CloseMethod ();
7574
7575                         Block = null;
7576                 }
7577
7578                 // Operator cannot be override
7579                 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
7580                 {
7581                         return null;
7582                 }
7583
7584                 public static string GetName (OpType ot)
7585                 {
7586                         switch (ot){
7587                         case OpType.LogicalNot:
7588                                 return "!";
7589                         case OpType.OnesComplement:
7590                                 return "~";
7591                         case OpType.Increment:
7592                                 return "++";
7593                         case OpType.Decrement:
7594                                 return "--";
7595                         case OpType.True:
7596                                 return "true";
7597                         case OpType.False:
7598                                 return "false";
7599                         case OpType.Addition:
7600                                 return "+";
7601                         case OpType.Subtraction:
7602                                 return "-";
7603                         case OpType.UnaryPlus:
7604                                 return "+";
7605                         case OpType.UnaryNegation:
7606                                 return "-";
7607                         case OpType.Multiply:
7608                                 return "*";
7609                         case OpType.Division:
7610                                 return "/";
7611                         case OpType.Modulus:
7612                                 return "%";
7613                         case OpType.BitwiseAnd:
7614                                 return "&";
7615                         case OpType.BitwiseOr:
7616                                 return "|";
7617                         case OpType.ExclusiveOr:
7618                                 return "^";
7619                         case OpType.LeftShift:
7620                                 return "<<";
7621                         case OpType.RightShift:
7622                                 return ">>";
7623                         case OpType.Equality:
7624                                 return "==";
7625                         case OpType.Inequality:
7626                                 return "!=";
7627                         case OpType.GreaterThan:
7628                                 return ">";
7629                         case OpType.LessThan:
7630                                 return "<";
7631                         case OpType.GreaterThanOrEqual:
7632                                 return ">=";
7633                         case OpType.LessThanOrEqual:
7634                                 return "<=";
7635                         case OpType.Implicit:
7636                                 return "implicit";
7637                         case OpType.Explicit:
7638                                 return "explicit";
7639                         default: return "";
7640                         }
7641                 }
7642
7643                 public static OpType GetOperatorType (string name)
7644                 {
7645                         if (name.StartsWith ("op_")){
7646                                 for (int i = 0; i < Unary.oper_names.Length; ++i) {
7647                                         if (Unary.oper_names [i] == name)
7648                                                 return (OpType)i;
7649                                 }
7650
7651                                 for (int i = 0; i < Binary.oper_names.Length; ++i) {
7652                                         if (Binary.oper_names [i] == name)
7653                                                 return (OpType)i;
7654                                 }
7655                         }
7656                         return OpType.TOP;
7657                 }
7658
7659                 public override string GetSignatureForError ()
7660                 {
7661                         StringBuilder sb = new StringBuilder ();
7662                         if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
7663                                 sb.AppendFormat ("{0}.{1} operator {2}", Parent.GetSignatureForError (), GetName (OperatorType), Type.Type == null ? Type.ToString () : TypeManager.CSharpName (Type.Type));
7664                         }
7665                         else {
7666                                 sb.AppendFormat ("{0}.operator {1}", Parent.GetSignatureForError (), GetName (OperatorType));
7667                         }
7668
7669                         sb.Append (Parameters.GetSignatureForError ());
7670                         return sb.ToString ();
7671                 }
7672         }
7673
7674         //
7675         // This is used to compare method signatures
7676         //
7677         struct MethodSignature {
7678                 public string Name;
7679                 public Type RetType;
7680                 public Type [] Parameters;
7681                 
7682                 /// <summary>
7683                 ///    This delegate is used to extract methods which have the
7684                 ///    same signature as the argument
7685                 /// </summary>
7686                 public static MemberFilter method_signature_filter = new MemberFilter (MemberSignatureCompare);
7687                 
7688                 public MethodSignature (string name, Type ret_type, Type [] parameters)
7689                 {
7690                         Name = name;
7691                         RetType = ret_type;
7692
7693                         if (parameters == null)
7694                                 Parameters = Type.EmptyTypes;
7695                         else
7696                                 Parameters = parameters;
7697                 }
7698
7699                 public override string ToString ()
7700                 {
7701                         string pars = "";
7702                         if (Parameters.Length != 0){
7703                                 System.Text.StringBuilder sb = new System.Text.StringBuilder ();
7704                                 for (int i = 0; i < Parameters.Length; i++){
7705                                         sb.Append (Parameters [i]);
7706                                         if (i+1 < Parameters.Length)
7707                                                 sb.Append (", ");
7708                                 }
7709                                 pars = sb.ToString ();
7710                         }
7711
7712                         return String.Format ("{0} {1} ({2})", RetType, Name, pars);
7713                 }
7714                 
7715                 public override int GetHashCode ()
7716                 {
7717                         return Name.GetHashCode ();
7718                 }
7719
7720                 public override bool Equals (Object o)
7721                 {
7722                         MethodSignature other = (MethodSignature) o;
7723
7724                         if (other.Name != Name)
7725                                 return false;
7726
7727                         if (other.RetType != RetType)
7728                                 return false;
7729                         
7730                         if (Parameters == null){
7731                                 if (other.Parameters == null)
7732                                         return true;
7733                                 return false;
7734                         }
7735
7736                         if (other.Parameters == null)
7737                                 return false;
7738                         
7739                         int c = Parameters.Length;
7740                         if (other.Parameters.Length != c)
7741                                 return false;
7742
7743                         for (int i = 0; i < c; i++)
7744                                 if (other.Parameters [i] != Parameters [i])
7745                                         return false;
7746
7747                         return true;
7748                 }
7749
7750                 static bool MemberSignatureCompare (MemberInfo m, object filter_criteria)
7751                 {
7752                         MethodSignature sig = (MethodSignature) filter_criteria;
7753
7754                         if (m.Name != sig.Name)
7755                                 return false;
7756
7757                         Type ReturnType;
7758                         MethodInfo mi = m as MethodInfo;
7759                         PropertyInfo pi = m as PropertyInfo;
7760
7761                         if (mi != null)
7762                                 ReturnType = mi.ReturnType;
7763                         else if (pi != null)
7764                                 ReturnType = pi.PropertyType;
7765                         else
7766                                 return false;
7767                         
7768                         //
7769                         // we use sig.RetType == null to mean `do not check the
7770                         // method return value.  
7771                         //
7772                         if (sig.RetType != null)
7773                                 if (ReturnType != sig.RetType)
7774                                         return false;
7775
7776                         Type [] args;
7777                         if (mi != null)
7778                                 args = TypeManager.GetParameterData (mi).Types;
7779                         else
7780                                 args = TypeManager.GetArgumentTypes (pi);
7781                         Type [] sigp = sig.Parameters;
7782
7783                         if (args.Length != sigp.Length)
7784                                 return false;
7785
7786                         for (int i = args.Length; i > 0; ){
7787                                 i--;
7788                                 if (args [i] != sigp [i])
7789                                         return false;
7790                         }
7791                         return true;
7792                 }
7793         }
7794 }