In mcs:
[mono.git] / mcs / gmcs / class.cs
1 //
2 // class.cs: Class and Struct handlers
3 //
4 // Authors: Miguel de Icaza (miguel@gnu.org)
5 //          Martin Baulig (martin@ximian.com)
6 //          Marek Safar (marek.safar@seznam.cz)
7 //
8 // Licensed under the terms of the GNU GPL
9 //
10 // (C) 2001, 2002, 2003 Ximian, Inc (http://www.ximian.com)
11 // (C) 2004 Novell, Inc
12 //
13 //
14 //  2002-10-11  Miguel de Icaza  <miguel@ximian.com>
15 //
16 //      * class.cs: Following the comment from 2002-09-26 to AddMethod, I
17 //      have fixed a remaining problem: not every AddXXXX was adding a
18 //      fully qualified name.  
19 //
20 //      Now everyone registers a fully qualified name in the DeclSpace as
21 //      being defined instead of the partial name.  
22 //
23 //      Downsides: we are slower than we need to be due to the excess
24 //      copies and the names being registered this way.  
25 //
26 //      The reason for this is that we currently depend (on the corlib
27 //      bootstrap for instance) that types are fully qualified, because
28 //      we dump all the types in the namespace, and we should really have
29 //      types inserted into the proper namespace, so we can only store the
30 //      basenames in the defined_names array.
31 //
32 //
33 #define CACHE
34 using System;
35 using System.Collections;
36 using System.Collections.Specialized;
37 using System.Reflection;
38 using System.Reflection.Emit;
39 using System.Runtime.CompilerServices;
40 using System.Runtime.InteropServices;
41 using System.Security;
42 using System.Security.Permissions;
43 using System.Text;
44 using System.Xml;
45
46 using Mono.CompilerServices.SymbolWriter;
47
48 namespace Mono.CSharp {
49
50         public enum Kind {
51                 Root,
52                 Struct,
53                 Class,
54                 Interface
55         }
56
57         /// <summary>
58         ///   This is the base class for structs and classes.  
59         /// </summary>
60         public abstract class TypeContainer : DeclSpace, IMemberContainer {
61
62                 public class MemberCoreArrayList: ArrayList
63                 {
64                         /// <summary>
65                         ///   Defines the MemberCore objects that are in this array
66                         /// </summary>
67                         public virtual void DefineContainerMembers ()
68                         {
69                                 foreach (MemberCore mc in this) {
70                                         try {
71                                                 mc.Define ();
72                                         }
73                                         catch (Exception e) {
74                                                 throw new InternalErrorException (mc.Location, mc.GetSignatureForError (), e);
75                                         }
76                                 }
77                         }
78
79                         public virtual void Emit ()
80                         {
81                                 foreach (MemberCore mc in this)
82                                         mc.Emit ();
83                         }
84                 }
85
86                 public class MethodArrayList : MemberCoreArrayList
87                 {
88                         [Flags]
89                         enum CachedMethods {
90                                 Equals                  = 1,
91                                 GetHashCode             = 1 << 1
92                         }
93  
94                         CachedMethods cached_method;
95                         TypeContainer container;
96
97                         public MethodArrayList (TypeContainer container)
98                         {
99                                 this.container = container;
100                         }
101  
102                         /// <summary>
103                         /// Method container contains Equals method
104                         /// </summary>
105                         public bool HasEquals {
106                                 set {
107                                         cached_method |= CachedMethods.Equals;
108                                 }
109  
110                                 get {
111                                         return (cached_method & CachedMethods.Equals) != 0;
112                                 }
113                         }
114  
115                         /// <summary>
116                         /// Method container contains GetHashCode method
117                         /// </summary>
118                         public bool HasGetHashCode {
119                                 set {
120                                         cached_method |= CachedMethods.GetHashCode;
121                                 }
122  
123                                 get {
124                                         return (cached_method & CachedMethods.GetHashCode) != 0;
125                                 }
126                         }
127  
128                         public override void DefineContainerMembers ()
129                         {
130                                 base.DefineContainerMembers ();
131  
132                                 if (HasEquals && !HasGetHashCode) {
133                                         Report.Warning (659, 3, container.Location, "`{0}' overrides Object.Equals(object) but does not override Object.GetHashCode()", container.GetSignatureForError ());
134                                 }
135                         }
136  
137                 }
138
139                 public sealed class IndexerArrayList : MemberCoreArrayList
140                 {
141                         /// <summary>
142                         /// The indexer name for this container
143                         /// </summary>
144                         public string IndexerName = DefaultIndexerName;
145
146                         bool seen_normal_indexers = false;
147
148                         TypeContainer container;
149
150                         public IndexerArrayList (TypeContainer container)
151                         {
152                                 this.container = container;
153                         }
154
155                         /// <summary>
156                         /// Defines the indexers, and also verifies that the IndexerNameAttribute in the
157                         /// class is consistent.  Either it is `Item' or it is the name defined by all the
158                         /// indexers with the `IndexerName' attribute.
159                         ///
160                         /// Turns out that the IndexerNameAttribute is applied to each indexer,
161                         /// but it is never emitted, instead a DefaultMember attribute is attached
162                         /// to the class.
163                         /// </summary>
164                         public override void DefineContainerMembers()
165                         {
166                                 base.DefineContainerMembers ();
167
168                                 string class_indexer_name = null;
169
170                                 //
171                                 // If there's both an explicit and an implicit interface implementation, the
172                                 // explicit one actually implements the interface while the other one is just
173                                 // a normal indexer.  See bug #37714.
174                                 //
175
176                                 // Invariant maintained by AddIndexer(): All explicit interface indexers precede normal indexers
177                                 foreach (Indexer i in this) {
178                                         if (i.InterfaceType != null) {
179                                                 if (seen_normal_indexers)
180                                                         throw new Exception ("Internal Error: 'Indexers' array not sorted properly.");
181                                                 continue;
182                                         }
183
184                                         seen_normal_indexers = true;
185
186                                         if (class_indexer_name == null) {
187                                                 class_indexer_name = i.ShortName;
188                                                 continue;
189                                         }
190
191                                         if (i.ShortName != class_indexer_name)
192                                                 Report.Error (668, i.Location, "Two indexers have different names; the IndexerName attribute must be used with the same name on every indexer within a type");
193                                 }
194
195                                 if (class_indexer_name != null)
196                                         IndexerName = class_indexer_name;
197                         }
198
199                         public override void Emit ()
200                         {
201                                 base.Emit ();
202
203                                 if (!seen_normal_indexers)
204                                         return;
205
206                                 CustomAttributeBuilder cb = new CustomAttributeBuilder (TypeManager.default_member_ctor, new string [] { IndexerName });
207                                 container.TypeBuilder.SetCustomAttribute (cb);
208                         }
209                 }
210
211                 public class OperatorArrayList: MemberCoreArrayList
212                 {
213                         TypeContainer container;
214
215                         public OperatorArrayList (TypeContainer container)
216                         {
217                                 this.container = container;
218                         }
219
220                         //
221                         // Operator pair checking
222                         //
223                         class OperatorEntry
224                         {
225                                 public int flags;
226                                 public Type ret_type;
227                                 public Type type1, type2;
228                                 public Operator op;
229                                 public Operator.OpType ot;
230                                 
231                                 public OperatorEntry (int f, Operator o)
232                                 {
233                                         flags = f;
234
235                                         ret_type = o.MemberType;
236                                         Type [] pt = o.ParameterTypes;
237                                         type1 = pt [0];
238                                         type2 = pt [1];
239                                         op = o;
240                                         ot = o.OperatorType;
241                                 }
242
243                                 public override int GetHashCode ()
244                                 {       
245                                         return ret_type.GetHashCode ();
246                                 }
247
248                                 public override bool Equals (object o)
249                                 {
250                                         OperatorEntry other = (OperatorEntry) o;
251
252                                         if (other.ret_type != ret_type)
253                                                 return false;
254                                         if (other.type1 != type1)
255                                                 return false;
256                                         if (other.type2 != type2)
257                                                 return false;
258                                         return true;
259                                 }
260                         }
261                                 
262                         //
263                         // Checks that some operators come in pairs:
264                         //  == and !=
265                         // > and <
266                         // >= and <=
267                         // true and false
268                         //
269                         // They are matched based on the return type and the argument types
270                         //
271                         void CheckPairedOperators ()
272                         {
273                                 IDictionary pairs = new HybridDictionary ();
274                                 Operator true_op = null;
275                                 Operator false_op = null;
276                                 bool has_equality_or_inequality = false;
277                                 
278                                 // Register all the operators we care about.
279                                 foreach (Operator op in this){
280                                         int reg = 0;
281
282                                         // Skip erroneous code.
283                                         if (op.MethodBuilder == null)
284                                                 continue;
285
286                                         switch (op.OperatorType){
287                                         case Operator.OpType.Equality:
288                                                 reg = 1;
289                                                 has_equality_or_inequality = true;
290                                                 break;
291                                         case Operator.OpType.Inequality:
292                                                 reg = 2;
293                                                 has_equality_or_inequality = true;
294                                                 break;
295
296                                         case Operator.OpType.True:
297                                                 true_op = op;
298                                                 break;
299                                         case Operator.OpType.False:
300                                                 false_op = op;
301                                                 break;
302                                                 
303                                         case Operator.OpType.GreaterThan:
304                                                 reg = 1; break;
305                                         case Operator.OpType.LessThan:
306                                                 reg = 2; break;
307                                                 
308                                         case Operator.OpType.GreaterThanOrEqual:
309                                                 reg = 1; break;
310                                         case Operator.OpType.LessThanOrEqual:
311                                                 reg = 2; break;
312                                         }
313                                         if (reg == 0)
314                                                 continue;
315
316                                         OperatorEntry oe = new OperatorEntry (reg, op);
317
318                                         object o = pairs [oe];
319                                         if (o == null)
320                                                 pairs [oe] = oe;
321                                         else {
322                                                 oe = (OperatorEntry) o;
323                                                 oe.flags |= reg;
324                                         }
325                                 }
326
327                                 if (true_op != null){
328                                         if (false_op == null)
329                                                 Report.Error (216, true_op.Location, "The operator `{0}' requires a matching operator `false' to also be defined",
330                                                         true_op.GetSignatureForError ());
331                                 } else if (false_op != null)
332                                         Report.Error (216, false_op.Location, "The operator `{0}' requires a matching operator `true' to also be defined",
333                                                 false_op.GetSignatureForError ());
334                                 
335                                 //
336                                 // Look for the mistakes.
337                                 //
338                                 foreach (DictionaryEntry de in pairs){
339                                         OperatorEntry oe = (OperatorEntry) de.Key;
340
341                                         if (oe.flags == 3)
342                                                 continue;
343
344                                         string s = "";
345                                         switch (oe.ot){
346                                         case Operator.OpType.Equality:
347                                                 s = "!=";
348                                                 break;
349                                         case Operator.OpType.Inequality: 
350                                                 s = "==";
351                                                 break;
352                                         case Operator.OpType.GreaterThan: 
353                                                 s = "<";
354                                                 break;
355                                         case Operator.OpType.LessThan:
356                                                 s = ">";
357                                                 break;
358                                         case Operator.OpType.GreaterThanOrEqual:
359                                                 s = "<=";
360                                                 break;
361                                         case Operator.OpType.LessThanOrEqual:
362                                                 s = ">=";
363                                                 break;
364                                         }
365                                         Report.Error (216, oe.op.Location,
366                                                 "The operator `{0}' requires a matching operator `{1}' to also be defined",
367                                                 oe.op.GetSignatureForError (), s);
368                                 }
369
370                                 if (has_equality_or_inequality && (RootContext.WarningLevel > 2)) {
371                                         if (container.Methods == null || !container.Methods.HasEquals)
372                                                 Report.Warning (660, 2, container.Location, "`{0}' defines operator == or operator != but does not override Object.Equals(object o)", container.GetSignatureForError ());
373  
374                                         if (container.Methods == null || !container.Methods.HasGetHashCode)
375                                                 Report.Warning (661, 2, container.Location, "`{0}' defines operator == or operator != but does not override Object.GetHashCode()", container.GetSignatureForError ());
376                                 }
377                         }
378
379                         public override void DefineContainerMembers ()
380                         {
381                                 base.DefineContainerMembers ();
382                                 CheckPairedOperators ();
383                         }
384                 }
385
386
387                 // Whether this is a struct, class or interface
388                 public readonly Kind Kind;
389
390                 // Holds a list of classes and structures
391                 protected ArrayList types;
392
393                 // Holds the list of properties
394                 MemberCoreArrayList properties;
395
396                 // Holds the list of enumerations
397                 MemberCoreArrayList enums;
398
399                 // Holds the list of delegates
400                 MemberCoreArrayList delegates;
401                 
402                 // Holds the list of constructors
403                 protected MemberCoreArrayList instance_constructors;
404
405                 // Holds the list of fields
406                 MemberCoreArrayList fields;
407
408                 // Holds a list of fields that have initializers
409                 protected ArrayList initialized_fields;
410
411                 // Holds a list of static fields that have initializers
412                 protected ArrayList initialized_static_fields;
413
414                 // Holds the list of constants
415                 MemberCoreArrayList constants;
416
417                 // Holds the list of
418                 MemberCoreArrayList interfaces;
419
420                 // Holds the methods.
421                 MethodArrayList methods;
422
423                 // Holds the events
424                 protected MemberCoreArrayList events;
425
426                 // Holds the indexers
427                 IndexerArrayList indexers;
428
429                 // Holds the operators
430                 MemberCoreArrayList operators;
431
432                 // Holds the iterators
433                 ArrayList iterators;
434
435                 //
436                 // Pointers to the default constructor and the default static constructor
437                 //
438                 protected Constructor default_constructor;
439                 protected Constructor default_static_constructor;
440
441                 //
442                 // Points to the first non-static field added to the container.
443                 //
444                 // This is an arbitrary choice.  We are interested in looking at _some_ non-static field,
445                 // and the first one's as good as any.
446                 //
447                 FieldBase first_nonstatic_field = null;
448
449                 //
450                 // This one is computed after we can distinguish interfaces
451                 // from classes from the arraylist `type_bases' 
452                 //
453                 TypeExpr base_type;
454                 TypeExpr[] iface_exprs;
455
456                 ArrayList type_bases;
457
458                 bool members_defined;
459                 bool members_defined_ok;
460
461                 // The interfaces we implement.
462                 protected Type[] ifaces;
463
464                 // The base member cache and our member cache
465                 MemberCache base_cache;
466                 MemberCache member_cache;
467
468                 public const string DefaultIndexerName = "Item";
469
470                 Type GenericType;
471                 GenericTypeParameterBuilder[] gen_params;
472
473                 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                         if (mi.IsSpecialName)
4173                                 return null;
4174
4175                         base_ret_type = mi.ReturnType;
4176                         return mi;
4177                 }
4178
4179                 protected override bool VerifyClsCompliance ()
4180                 {
4181                         if (!base.VerifyClsCompliance ())
4182                                 return false;
4183
4184                         if (ParameterInfo.Count > 0) {
4185                                 ArrayList al = (ArrayList)ParentContainer.MemberCache.Members [Name];
4186                                 if (al.Count > 1)
4187                                         MemberCache.VerifyClsParameterConflict (al, this, MethodBuilder);
4188                         }
4189
4190                         return true;
4191                 }
4192         }
4193
4194         public abstract class ConstructorInitializer {
4195                 ArrayList argument_list;
4196                 protected ConstructorInfo base_constructor;
4197                 Location loc;
4198                 
4199                 public ConstructorInitializer (ArrayList argument_list, Location loc)
4200                 {
4201                         this.argument_list = argument_list;
4202                         this.loc = loc;
4203                 }
4204
4205                 public ArrayList Arguments {
4206                         get {
4207                                 return argument_list;
4208                         }
4209                 }
4210
4211                 public bool Resolve (ConstructorBuilder caller_builder, Block block, EmitContext ec)
4212                 {
4213                         Expression base_constructor_group;
4214                         Type t;
4215                         bool error = false;
4216
4217                         ec.CurrentBlock = block;
4218
4219                         if (argument_list != null){
4220                                 foreach (Argument a in argument_list){
4221                                         if (!a.Resolve (ec, loc))
4222                                                 return false;
4223                                 }
4224                         }
4225                         ec.CurrentBlock = null;
4226
4227                         if (this is ConstructorBaseInitializer) {
4228                                 if (ec.ContainerType.BaseType == null)
4229                                         return true;
4230
4231                                 t = ec.ContainerType.BaseType;
4232                                 if (ec.ContainerType.IsValueType) {
4233                                         Report.Error (522, loc,
4234                                                 "`{0}': Struct constructors cannot call base constructors", TypeManager.CSharpSignature (caller_builder));
4235                                         return false;
4236                                 }
4237                         } else
4238                                 t = ec.ContainerType;
4239
4240                         base_constructor_group = Expression.MemberLookup (
4241                                 ec.ContainerType, t, ".ctor", MemberTypes.Constructor,
4242                                 BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
4243                                 loc);
4244                         
4245                         if (base_constructor_group == null){
4246                                 error = true;
4247                                 base_constructor_group = Expression.MemberLookup (
4248                                         t, null, t, ".ctor", MemberTypes.Constructor,
4249                                         BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly,
4250                                         loc);
4251                         }
4252
4253                         int errors = Report.Errors;
4254                         if (base_constructor_group != null)
4255                                 base_constructor = (ConstructorInfo) Invocation.OverloadResolve (
4256                                         ec, (MethodGroupExpr) base_constructor_group, argument_list,
4257                                         false, loc);
4258                         
4259                         if (base_constructor == null) {
4260                                 if (errors == Report.Errors)
4261                                         Invocation.Error_WrongNumArguments (loc, TypeManager.CSharpSignature (caller_builder),
4262                                                 argument_list == null ? 0 : argument_list.Count);
4263                                 return false;
4264                         }
4265
4266                         if (error) {
4267                                 Expression.ErrorIsInaccesible (loc, TypeManager.CSharpSignature (base_constructor));
4268                                 base_constructor = null;
4269                                 return false;
4270                         }
4271                         
4272                         if (base_constructor == caller_builder){
4273                                 Report.Error (516, loc, "Constructor `{0}' cannot call itself", TypeManager.CSharpSignature (caller_builder));
4274                                 return false;
4275                         }
4276                         
4277                         return true;
4278                 }
4279
4280                 public virtual void Emit (EmitContext ec)
4281                 {
4282                         if (base_constructor != null){
4283                                 ec.Mark (loc, false);
4284                                 if (ec.IsStatic)
4285                                         Invocation.EmitCall (ec, true, true, null, base_constructor, argument_list, loc);
4286                                 else
4287                                         Invocation.EmitCall (ec, true, false, ec.GetThis (loc), base_constructor, argument_list, loc);
4288                         }
4289                 }
4290         }
4291
4292         public class ConstructorBaseInitializer : ConstructorInitializer {
4293                 public ConstructorBaseInitializer (ArrayList argument_list, Location l) :
4294                         base (argument_list, l)
4295                 {
4296                 }
4297         }
4298
4299         class GeneratedBaseInitializer: ConstructorBaseInitializer {
4300                 public GeneratedBaseInitializer (Location loc):
4301                         base (null, loc)
4302                 {
4303                 }
4304         }
4305
4306         public class ConstructorThisInitializer : ConstructorInitializer {
4307                 public ConstructorThisInitializer (ArrayList argument_list, Location l) :
4308                         base (argument_list, l)
4309                 {
4310                 }
4311         }
4312         
4313         public class Constructor : MethodCore, IMethodData {
4314                 public ConstructorBuilder ConstructorBuilder;
4315                 public ConstructorInitializer Initializer;
4316                 ListDictionary declarative_security;
4317
4318                 // <summary>
4319                 //   Modifiers allowed for a constructor.
4320                 // </summary>
4321                 public const int AllowedModifiers =
4322                         Modifiers.PUBLIC |
4323                         Modifiers.PROTECTED |
4324                         Modifiers.INTERNAL |
4325                         Modifiers.STATIC |
4326                         Modifiers.UNSAFE |
4327                         Modifiers.EXTERN |              
4328                         Modifiers.PRIVATE;
4329
4330                 static string[] attribute_targets = new string [] { "method" };
4331
4332                 bool has_compliant_args = false;
4333                 //
4334                 // The spec claims that static is not permitted, but
4335                 // my very own code has static constructors.
4336                 //
4337                 public Constructor (DeclSpace parent, string name, int mod, Parameters args,
4338                                     ConstructorInitializer init, Location loc)
4339                         : base (parent, null, null, mod, AllowedModifiers, false,
4340                                 new MemberName (name, loc), null, args)
4341                 {
4342                         Initializer = init;
4343                 }
4344
4345                 public bool HasCompliantArgs {
4346                         get { return has_compliant_args; }
4347                 }
4348
4349                 public override AttributeTargets AttributeTargets {
4350                         get { return AttributeTargets.Constructor; }
4351                 }
4352
4353
4354                 //
4355                 // Returns true if this is a default constructor
4356                 //
4357                 public bool IsDefault ()
4358                 {
4359                         if ((ModFlags & Modifiers.STATIC) != 0)
4360                                 return Parameters.Empty;
4361                         
4362                         return Parameters.Empty &&
4363                                         (Initializer is ConstructorBaseInitializer) &&
4364                                         (Initializer.Arguments == null);
4365                 }
4366
4367                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
4368                 {
4369                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
4370                                 if (declarative_security == null) {
4371                                         declarative_security = new ListDictionary ();
4372                                 }
4373                                 a.ExtractSecurityPermissionSet (declarative_security);
4374                                 return;
4375                         }
4376
4377                         if (a.Type == TypeManager.methodimpl_attr_type &&
4378                                 (a.GetMethodImplOptions () & MethodImplOptions.InternalCall) != 0) {
4379                                 ConstructorBuilder.SetImplementationFlags (MethodImplAttributes.InternalCall | MethodImplAttributes.Runtime);
4380                         }
4381
4382                         ConstructorBuilder.SetCustomAttribute (cb);
4383                 }
4384
4385                 protected override bool CheckForDuplications ()
4386                 {
4387                         ArrayList ar = ParentContainer.InstanceConstructors;
4388                         if (ar != null) {
4389                                 int arLen = ar.Count;
4390                                         
4391                                 for (int i = 0; i < arLen; i++) {
4392                                         Constructor m = (Constructor) ar [i];
4393                                         if (IsDuplicateImplementation (m))
4394                                                 return false;
4395                                 }
4396                         }
4397                         return true;
4398                 }
4399                         
4400                 protected override bool CheckBase ()
4401                 {
4402                         if ((ModFlags & Modifiers.STATIC) != 0) {
4403                                 if (!Parameters.Empty) {
4404                                         Report.Error (132, Location, "`{0}': The static constructor must be parameterless",
4405                                                 GetSignatureForError ());
4406                                         return false;
4407                                 }
4408
4409                                 // the rest can be ignored
4410                                 return true;
4411                         }
4412
4413                         // Check whether arguments were correct.
4414                         if (!DoDefineParameters ())
4415                                 return false;
4416                         
4417                         if (!CheckForDuplications ())
4418                                 return false;
4419
4420                         if (ParentContainer.Kind == Kind.Struct) {
4421                                 if (ParameterTypes.Length == 0) {
4422                                         Report.Error (568, Location, 
4423                                                 "Structs cannot contain explicit parameterless constructors");
4424                                         return false;
4425                                 }
4426
4427                                 if ((ModFlags & Modifiers.PROTECTED) != 0) {
4428                                         Report.Error (666, Location, "`{0}': new protected member declared in struct", GetSignatureForError ());
4429                                                 return false;
4430                                 }
4431                         }
4432                         
4433                         if ((RootContext.WarningLevel >= 4) && ((Parent.ModFlags & Modifiers.SEALED) != 0 && (ModFlags & Modifiers.PROTECTED) != 0)) {
4434                                 Report.Warning (628, 4, Location, "`{0}': new protected member declared in sealed class", GetSignatureForError ());
4435                         }
4436
4437                         return true;
4438                 }
4439                 
4440                 //
4441                 // Creates the ConstructorBuilder
4442                 //
4443                 public override bool Define ()
4444                 {
4445                         if (ConstructorBuilder != null)
4446                                 return true;
4447
4448                         MethodAttributes ca = (MethodAttributes.RTSpecialName |
4449                                                MethodAttributes.SpecialName);
4450
4451                         if ((ModFlags & Modifiers.STATIC) != 0){
4452                                 ca |= MethodAttributes.Static | MethodAttributes.Private;
4453                         } else {
4454                                 ca |= MethodAttributes.HideBySig;
4455
4456                                 if ((ModFlags & Modifiers.PUBLIC) != 0)
4457                                         ca |= MethodAttributes.Public;
4458                                 else if ((ModFlags & Modifiers.PROTECTED) != 0){
4459                                         if ((ModFlags & Modifiers.INTERNAL) != 0)
4460                                                 ca |= MethodAttributes.FamORAssem;
4461                                         else 
4462                                                 ca |= MethodAttributes.Family;
4463                                 } else if ((ModFlags & Modifiers.INTERNAL) != 0)
4464                                         ca |= MethodAttributes.Assembly;
4465                                 else
4466                                         ca |= MethodAttributes.Private;
4467                         }
4468
4469                         if (!CheckAbstractAndExtern (block != null))
4470                                 return false;
4471                         
4472                         // Check if arguments were correct.
4473                         if (!CheckBase ())
4474                                 return false;
4475
4476                         ConstructorBuilder = Parent.TypeBuilder.DefineConstructor (
4477                                 ca, CallingConventions,
4478                                 ParameterTypes);
4479
4480                         if ((ModFlags & Modifiers.UNSAFE) != 0)
4481                                 ConstructorBuilder.InitLocals = false;
4482
4483                         if (ParentContainer.IsComImport) {
4484                                 if (!IsDefault ()) {
4485                                         Report.Error (669, Location, "`{0}': A class with the ComImport attribute cannot have a user-defined constructor",
4486                                                 Parent.GetSignatureForError ());
4487                                         return false;
4488                                 }
4489                                 ConstructorBuilder.SetImplementationFlags (MethodImplAttributes.InternalCall);
4490                         }
4491
4492                         TypeManager.AddMethod (ConstructorBuilder, this);
4493
4494                         return true;
4495                 }
4496
4497                 //
4498                 // Emits the code
4499                 //
4500                 public override void Emit ()
4501                 {
4502                         if (OptAttributes != null)
4503                                 OptAttributes.Emit ();
4504
4505                         EmitContext ec = CreateEmitContext (null, null);
4506
4507                         if (block != null) {
4508                                 // If this is a non-static `struct' constructor and doesn't have any
4509                                 // initializer, it must initialize all of the struct's fields.
4510                                 if ((ParentContainer.Kind == Kind.Struct) &&
4511                                         ((ModFlags & Modifiers.STATIC) == 0) && (Initializer == null))
4512                                         block.AddThisVariable (Parent, Location);
4513
4514                                 if (!block.ResolveMeta (ec, ParameterInfo))
4515                                         block = null;
4516                         }
4517
4518                         if ((ModFlags & Modifiers.STATIC) == 0){
4519                                 if (ParentContainer.Kind == Kind.Class && Initializer == null)
4520                                         Initializer = new GeneratedBaseInitializer (Location);
4521
4522
4523                                 //
4524                                 // Spec mandates that Initializers will not have
4525                                 // `this' access
4526                                 //
4527                                 ec.IsStatic = true;
4528                                 if ((Initializer != null) &&
4529                                     !Initializer.Resolve (ConstructorBuilder, block, ec))
4530                                         return;
4531                                 ec.IsStatic = false;
4532                         }
4533
4534                         Parameters.ApplyAttributes (ConstructorBuilder);
4535                         
4536                         SourceMethod source = SourceMethod.Create (
4537                                 Parent, ConstructorBuilder, block);
4538
4539                         //
4540                         // Classes can have base initializers and instance field initializers.
4541                         //
4542                         if (ParentContainer.Kind == Kind.Class){
4543                                 if ((ModFlags & Modifiers.STATIC) == 0){
4544
4545                                         //
4546                                         // If we use a "this (...)" constructor initializer, then
4547                                         // do not emit field initializers, they are initialized in the other constructor
4548                                         //
4549                                         if (!(Initializer != null && Initializer is ConstructorThisInitializer))
4550                                                 ParentContainer.EmitFieldInitializers (ec);
4551                                 }
4552                         }
4553                         if (Initializer != null) {
4554                                 Initializer.Emit (ec);
4555                         }
4556                         
4557                         if ((ModFlags & Modifiers.STATIC) != 0)
4558                                 ParentContainer.EmitFieldInitializers (ec);
4559
4560                         ec.EmitTopBlock (this, block);
4561
4562                         if (source != null)
4563                                 source.CloseMethod ();
4564
4565                         base.Emit ();
4566
4567                         if (declarative_security != null) {
4568                                 foreach (DictionaryEntry de in declarative_security) {
4569                                         ConstructorBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
4570                                 }
4571                         }
4572
4573                         block = null;
4574                 }
4575
4576                 // Is never override
4577                 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
4578                 {
4579                         return null;
4580                 }
4581
4582                 public override string GetSignatureForError()
4583                 {
4584                         return base.GetSignatureForError () + Parameters.GetSignatureForError ();
4585                 }
4586
4587                 public override string[] ValidAttributeTargets {
4588                         get {
4589                                 return attribute_targets;
4590                         }
4591                 }
4592
4593                 protected override bool VerifyClsCompliance ()
4594                 {
4595                         if (!base.VerifyClsCompliance () || !IsExposedFromAssembly ()) {
4596                                 return false;
4597                         }
4598                         
4599                         if (ParameterInfo.Count > 0) {
4600                                 ArrayList al = (ArrayList)Parent.MemberCache.Members [".ctor"];
4601                                 if (al.Count > 3)
4602                                         MemberCache.VerifyClsParameterConflict (al, this, ConstructorBuilder);
4603  
4604                                 if (Parent.TypeBuilder.IsSubclassOf (TypeManager.attribute_type)) {
4605                                         foreach (Type param in ParameterTypes) {
4606                                                 if (param.IsArray) {
4607                                                         return true;
4608                                                 }
4609                                         }
4610                                 }
4611                         }
4612                         has_compliant_args = true;
4613                         return true;
4614                 }
4615
4616                 #region IMethodData Members
4617
4618                 public System.Reflection.CallingConventions CallingConventions {
4619                         get {
4620                                 CallingConventions cc = Parameters.CallingConvention;
4621
4622                                 if (ParentContainer.Kind == Kind.Class)
4623                                         if ((ModFlags & Modifiers.STATIC) == 0)
4624                                                 cc |= CallingConventions.HasThis;
4625
4626                                 // FIXME: How is `ExplicitThis' used in C#?
4627                         
4628                                 return cc;
4629                                 }
4630                         }
4631                         
4632                 public new Location Location {
4633                         get {
4634                                 return base.Location;
4635                         }
4636                 }
4637
4638                 public MemberName MethodName {
4639                         get {
4640                                 return MemberName;
4641                         }
4642                 }
4643                         
4644                 public Type ReturnType {
4645                         get {
4646                                 return MemberType;
4647                         }
4648                 }
4649
4650                 public EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig)
4651                 {
4652                         ILGenerator ig_ = ConstructorBuilder.GetILGenerator ();
4653                         return new EmitContext (this, Parent, Location, ig_, null, ModFlags, true);
4654                 }
4655
4656                 public bool IsExcluded()
4657                 {
4658                         return false;
4659                 }
4660
4661                 GenericMethod IMethodData.GenericMethod {
4662                         get {
4663                                 return null;
4664                         }
4665                 }
4666
4667                 #endregion
4668         }
4669
4670         /// <summary>
4671         /// Interface for MethodData class. Holds links to parent members to avoid member duplication.
4672         /// </summary>
4673         public interface IMethodData
4674         {
4675                 CallingConventions CallingConventions { get; }
4676                 Location Location { get; }
4677                 MemberName MethodName { get; }
4678                 Type ReturnType { get; }
4679                 GenericMethod GenericMethod { get; }
4680                 Parameters ParameterInfo { get; }
4681
4682                 Attributes OptAttributes { get; }
4683                 ToplevelBlock Block { get; set; }
4684
4685                 EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig);
4686                 ObsoleteAttribute GetObsoleteAttribute ();
4687                 string GetSignatureForError ();
4688                 bool IsExcluded ();
4689                 bool IsClsComplianceRequired ();
4690                 void SetMemberIsUsed ();
4691         }
4692
4693         //
4694         // Encapsulates most of the Method's state
4695         //
4696         public class MethodData {
4697
4698                 readonly IMethodData method;
4699
4700                 public readonly GenericMethod GenericMethod;
4701
4702                 //
4703                 // Are we implementing an interface ?
4704                 //
4705                 public MethodInfo implementing;
4706
4707                 //
4708                 // Protected data.
4709                 //
4710                 protected MemberBase member;
4711                 protected int modifiers;
4712                 protected MethodAttributes flags;
4713                 protected Type declaring_type;
4714                 protected MethodInfo parent_method;
4715
4716                 MethodBuilder builder = null;
4717                 public MethodBuilder MethodBuilder {
4718                         get {
4719                                 return builder;
4720                         }
4721                 }
4722
4723                 public Type DeclaringType {
4724                         get {
4725                                 return declaring_type;
4726                         }
4727                 }
4728
4729                 public MethodData (MemberBase member,
4730                                    int modifiers, MethodAttributes flags, IMethodData method)
4731                 {
4732                         this.member = member;
4733                         this.modifiers = modifiers;
4734                         this.flags = flags;
4735
4736                         this.method = method;
4737                 }
4738
4739                 public MethodData (MemberBase member, 
4740                                    int modifiers, MethodAttributes flags, 
4741                                    IMethodData method, MethodBuilder builder,
4742                                    GenericMethod generic, MethodInfo parent_method)
4743                         : this (member, modifiers, flags, method)
4744                 {
4745                         this.builder = builder;
4746                         this.GenericMethod = generic;
4747                         this.parent_method = parent_method;
4748                 }
4749
4750                 public bool Define (DeclSpace parent)
4751                 {
4752                         string name = method.MethodName.Basename;
4753                         string method_name = method.MethodName.FullName;
4754
4755                         TypeContainer container = ((TypeContainer) parent).PartialContainer;
4756
4757                         PendingImplementation pending = container.PendingImplementations;
4758                         if (pending != null){
4759                                 if (member is Indexer) // TODO: test it, but it should work without this IF
4760                                         implementing = pending.IsInterfaceIndexer (
4761                                                 member.InterfaceType, method.ReturnType, method.ParameterInfo);
4762                                 else
4763                                         implementing = pending.IsInterfaceMethod (
4764                                                 member.InterfaceType, name, method.ReturnType, method.ParameterInfo);
4765
4766                                 if (member.InterfaceType != null){
4767                                         if (implementing == null){
4768                                                 if (member is PropertyBase) {
4769                                                         Report.Error (550, method.Location, "`{0}' is an accessor not found in interface member `{1}{2}'",
4770                                                                       method.GetSignatureForError (), TypeManager.CSharpName (member.InterfaceType),
4771                                                                       member.GetSignatureForError ().Substring (member.GetSignatureForError ().LastIndexOf ('.')));
4772
4773                                                 } else {
4774                                                         Report.Error (539, method.Location,
4775                                                                       "`{0}.{1}' in explicit interface declaration is not a member of interface",
4776                                                                       TypeManager.CSharpName (member.InterfaceType), member.ShortName);
4777                                                 }
4778                                                 return false;
4779                                         }
4780                                         if (implementing.IsSpecialName && !(method is AbstractPropertyEventMethod)) {
4781                                                 Report.SymbolRelatedToPreviousError (implementing);
4782                                                 Report.Error (683, method.Location, "`{0}' explicit method implementation cannot implement `{1}' because it is an accessor",
4783                                                         member.GetSignatureForError (), TypeManager.CSharpSignature (implementing));
4784                                                 return false;
4785                                         }
4786
4787                                         method_name = TypeManager.GetFullName (member.InterfaceType) +
4788                                                 '.' + method_name;
4789                                 } else {
4790                                         if (implementing != null) {
4791                                                 AbstractPropertyEventMethod prop_method = method as AbstractPropertyEventMethod;
4792                                                 if (prop_method != null) {
4793                                                         if (!implementing.IsSpecialName) {
4794                                                                 Report.SymbolRelatedToPreviousError (implementing);
4795                                                                 Report.Error (686, method.Location, "Accessor `{0}' cannot implement interface member `{1}' for type `{2}'. Use an explicit interface implementation",
4796                                                                         method.GetSignatureForError (), TypeManager.CSharpSignature (implementing), container.GetSignatureForError ());
4797                                                                 return false;
4798                                                         }
4799                                                         PropertyBase.PropertyMethod pm = prop_method as PropertyBase.PropertyMethod;
4800                                                         if (pm != null && pm.HasCustomAccessModifier && (pm.ModFlags & Modifiers.PUBLIC) == 0) {
4801                                                                 Report.SymbolRelatedToPreviousError (implementing);
4802                                                                 Report.Error (277, method.Location, "Accessor `{0}' must be declared public to implement interface member `{1}'",
4803                                                                         method.GetSignatureForError (), TypeManager.CSharpSignature (implementing, true));
4804                                                                 return false;
4805                                                         }
4806                                                 }
4807                                         }
4808                                 }
4809                         }
4810
4811                         //
4812                         // For implicit implementations, make sure we are public, for
4813                         // explicit implementations, make sure we are private.
4814                         //
4815                         if (implementing != null){
4816                                 //
4817                                 // Setting null inside this block will trigger a more
4818                                 // verbose error reporting for missing interface implementations
4819                                 //
4820                                 // The "candidate" function has been flagged already
4821                                 // but it wont get cleared
4822                                 //
4823                                 if (member.IsExplicitImpl){
4824                                         if ((modifiers & (Modifiers.PUBLIC | Modifiers.ABSTRACT | Modifiers.VIRTUAL)) != 0){
4825                                                 Modifiers.Error_InvalidModifier (method.Location, "public, virtual or abstract");
4826                                                 implementing = null;
4827                                         }
4828                                         if (method.ParameterInfo.HasParams && !TypeManager.GetParameterData (implementing).HasParams) {
4829                                                 Report.SymbolRelatedToPreviousError (implementing);
4830                                                 Report.Error (466, method.Location, "`{0}': the explicit interface implementation cannot introduce the params modifier",
4831                                                         method.GetSignatureForError ());
4832                                                 return false;
4833                                         }
4834                                 } else if ((flags & MethodAttributes.MemberAccessMask) != MethodAttributes.Public){
4835                                         if (TypeManager.IsInterfaceType (implementing.DeclaringType)){
4836                                                 //
4837                                                 // If this is an interface method implementation,
4838                                                 // check for public accessibility
4839                                                 //
4840                                                 implementing = null;
4841                                         } else if ((flags & MethodAttributes.MemberAccessMask) == MethodAttributes.Private){
4842                                                 // We may never be private.
4843                                                 implementing = null;
4844                                         } else if ((modifiers & Modifiers.OVERRIDE) == 0){
4845                                                 //
4846                                                 // We may be protected if we're overriding something.
4847                                                 //
4848                                                 implementing = null;
4849                                         }
4850                                 } 
4851                                         
4852                                 //
4853                                 // Static is not allowed
4854                                 //
4855                                 if ((modifiers & Modifiers.STATIC) != 0){
4856                                         implementing = null;
4857                                 }
4858                         }
4859                         
4860                         //
4861                         // If implementing is still valid, set flags
4862                         //
4863                         if (implementing != null){
4864                                 //
4865                                 // When implementing interface methods, set NewSlot
4866                                 // unless, we are overwriting a method.
4867                                 //
4868                                 if (implementing.DeclaringType.IsInterface){
4869                                         if ((modifiers & Modifiers.OVERRIDE) == 0)
4870                                                 flags |= MethodAttributes.NewSlot;
4871                                 }
4872                                 flags |=
4873                                         MethodAttributes.Virtual |
4874                                         MethodAttributes.HideBySig;
4875
4876                                 // Set Final unless we're virtual, abstract or already overriding a method.
4877                                 if ((modifiers & (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE)) == 0)
4878                                         flags |= MethodAttributes.Final;
4879                         }
4880
4881                         EmitContext ec = method.CreateEmitContext (container, null);
4882
4883                         DefineMethodBuilder (container, method_name, method.ParameterInfo.Types);
4884
4885                         if (builder == null)
4886                                 return false;
4887
4888                         if (container.CurrentType != null)
4889                                 declaring_type = container.CurrentType;
4890                         else
4891                                 declaring_type = container.TypeBuilder;
4892
4893                         if ((modifiers & Modifiers.UNSAFE) != 0)
4894                                 builder.InitLocals = false;
4895
4896                         if (implementing != null){
4897                                 //
4898                                 // clear the pending implemntation flag
4899                                 //
4900                                 if (member is Indexer) {
4901                                         pending.ImplementIndexer (
4902                                                 member.InterfaceType, builder, method.ReturnType,
4903                                                 method.ParameterInfo, member.IsExplicitImpl);
4904                                 } else
4905                                         pending.ImplementMethod (
4906                                                 member.InterfaceType, name, method.ReturnType,
4907                                                 method.ParameterInfo, member.IsExplicitImpl);
4908
4909                                 if (member.IsExplicitImpl)
4910                                         container.TypeBuilder.DefineMethodOverride (
4911                                                 builder, implementing);
4912
4913                         }
4914
4915                         TypeManager.AddMethod (builder, method);
4916
4917                         if (GenericMethod != null) {
4918                                 bool is_override = member.IsExplicitImpl |
4919                                         ((modifiers & Modifiers.OVERRIDE) != 0);
4920
4921                                 if (implementing != null)
4922                                         parent_method = implementing;
4923
4924                                 if (!GenericMethod.DefineType (ec, builder, parent_method, is_override))
4925                                         return false;
4926                         }
4927
4928                         return true;
4929                 }
4930
4931
4932                 /// <summary>
4933                 /// Create the MethodBuilder for the method 
4934                 /// </summary>
4935                 void DefineMethodBuilder (TypeContainer container, string method_name, Type[] ParameterTypes)
4936                 {
4937                         const int extern_static = Modifiers.EXTERN | Modifiers.STATIC;
4938
4939                         if ((modifiers & extern_static) == extern_static) {
4940
4941                                 if (method.OptAttributes != null) {
4942                                         Attribute dllimport_attribute = method.OptAttributes.Search (TypeManager.dllimport_type);
4943                                         if (dllimport_attribute != null) {
4944                                                 flags |= MethodAttributes.PinvokeImpl;
4945                                                 builder = dllimport_attribute.DefinePInvokeMethod (
4946                                                         container.TypeBuilder, method_name, flags,
4947                                                         method.ReturnType, ParameterTypes);
4948
4949                                                 return;
4950                                         }
4951                                 }
4952
4953                                 // for extern static method must be specified either DllImport attribute or MethodImplAttribute.
4954                                 // We are more strict than Microsoft and report CS0626 like error
4955                                 if (method.OptAttributes == null ||
4956                                         !method.OptAttributes.Contains (TypeManager.methodimpl_attr_type)) {
4957                                         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",
4958                                                 method.GetSignatureForError ());
4959                                         return;
4960                                 }
4961                         }
4962
4963                         if (builder == null) {
4964                                 builder = container.TypeBuilder.DefineMethod (
4965                                         method_name, flags, method.CallingConventions,
4966                                         method.ReturnType, ParameterTypes);
4967                                 return;
4968                         }
4969 #if !MS_COMPATIBLE
4970                                 builder.SetGenericMethodSignature (
4971                                         flags, method.CallingConventions,
4972                                         method.ReturnType, ParameterTypes);
4973 #endif
4974                 }
4975
4976                 //
4977                 // Emits the code
4978                 // 
4979                 public void Emit (DeclSpace parent)
4980                 {
4981                         EmitContext ec;
4982                         if ((flags & MethodAttributes.PinvokeImpl) == 0)
4983                                 ec = method.CreateEmitContext (parent, builder.GetILGenerator ());
4984                         else
4985                                 ec = method.CreateEmitContext (parent, null);
4986
4987                         method.ParameterInfo.ApplyAttributes (MethodBuilder);
4988
4989                         if (GenericMethod != null)
4990                                 GenericMethod.EmitAttributes ();
4991
4992                         ToplevelBlock block = method.Block;
4993                         
4994                         SourceMethod source = SourceMethod.Create (parent, MethodBuilder, method.Block);
4995
4996                         //
4997                         // Handle destructors specially
4998                         //
4999                         // FIXME: This code generates buggy code
5000                         //
5001                         if (member is Destructor)
5002                                 EmitDestructor (ec, block);
5003                         else
5004                                 ec.EmitTopBlock (method, block);
5005
5006                         if (source != null)
5007                                 source.CloseMethod ();
5008                 }
5009
5010                 void EmitDestructor (EmitContext ec, ToplevelBlock block)
5011                 {
5012                         ILGenerator ig = ec.ig;
5013                         
5014                         Label finish = ig.DefineLabel ();
5015
5016                         block.SetDestructor ();
5017                         
5018                         ig.BeginExceptionBlock ();
5019                         ec.ReturnLabel = finish;
5020                         ec.HasReturnLabel = true;
5021                         ec.EmitTopBlock (method, block);
5022                         
5023                         // ig.MarkLabel (finish);
5024                         ig.BeginFinallyBlock ();
5025                         
5026                         if (ec.ContainerType.BaseType != null) {
5027                                 Expression member_lookup = Expression.MemberLookup (
5028                                         ec.ContainerType.BaseType, null, ec.ContainerType.BaseType,
5029                                         "Finalize", MemberTypes.Method, Expression.AllBindingFlags, method.Location);
5030
5031                                 if (member_lookup != null){
5032                                         MethodGroupExpr base_destructor = ((MethodGroupExpr) member_lookup);
5033                                 
5034                                         ig.Emit (OpCodes.Ldarg_0);
5035                                         ig.Emit (OpCodes.Call, (MethodInfo) base_destructor.Methods [0]);
5036                                 }
5037                         }
5038                         
5039                         ig.EndExceptionBlock ();
5040                         //ig.MarkLabel (ec.ReturnLabel);
5041                         ig.Emit (OpCodes.Ret);
5042                 }
5043         }
5044
5045         // TODO: Should derive from MethodCore
5046         public class Destructor : Method {
5047
5048                 static string[] attribute_targets = new string [] { "method" };
5049
5050                 public Destructor (DeclSpace parent, Expression return_type, int mod,
5051                                    string name, Parameters parameters, Attributes attrs,
5052                                    Location l)
5053                         : base (parent, null, return_type, mod, false, new MemberName (name, l),
5054                                 parameters, attrs)
5055                 { }
5056
5057                 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
5058                 {
5059                         if (a.Type == TypeManager.conditional_attribute_type) {
5060                                 Error_ConditionalAttributeIsNotValid ();
5061                                 return;
5062                         }
5063
5064                         base.ApplyAttributeBuilder (a, cb);
5065                 }
5066
5067                 public override string GetSignatureForError ()
5068                 {
5069                         return Parent.GetSignatureForError () + ".~" + Parent.MemberName.Name + "()";
5070                 }
5071
5072                 public override string[] ValidAttributeTargets {
5073                         get {
5074                                 return attribute_targets;
5075                         }
5076                 }
5077         }
5078         
5079         abstract public class MemberBase : MemberCore {
5080                 public Expression Type;
5081
5082                 public MethodAttributes flags;
5083                 public readonly DeclSpace ds;
5084                 public readonly GenericMethod GenericMethod;
5085
5086                 protected readonly int explicit_mod_flags;
5087
5088                 //
5089                 // The "short" name of this property / indexer / event.  This is the
5090                 // name without the explicit interface.
5091                 //
5092                 public string ShortName {
5093                         get { return MemberName.Name; }
5094                         set { SetMemberName (new MemberName (MemberName.Left, value, Location)); }
5095                 }
5096
5097                 public TypeContainer ParentContainer {
5098                         get { return ((TypeContainer) Parent).PartialContainer; }
5099                 }
5100
5101                 //
5102                 // The type of this property / indexer / event
5103                 //
5104                 protected Type member_type;
5105                 public Type MemberType {
5106                         get {
5107                                 if (member_type == null && Type != null) {
5108                                         IResolveContext rc = GenericMethod == null ? this : (IResolveContext)ds;
5109                                         Type = Type.ResolveAsTypeTerminal (rc, false);
5110                                         if (Type != null) {
5111                                                 member_type = Type.Type;
5112                                         }
5113                                 }
5114                                 return member_type;
5115                         }
5116                 }
5117
5118                 //
5119                 // Whether this is an interface member.
5120                 //
5121                 public bool IsInterface;
5122
5123                 //
5124                 // If true, this is an explicit interface implementation
5125                 //
5126                 public bool IsExplicitImpl;
5127
5128                 //
5129                 // The interface type we are explicitly implementing
5130                 //
5131                 public Type InterfaceType = null;
5132
5133                 //
5134                 // The constructor is only exposed to our children
5135                 //
5136                 protected MemberBase (DeclSpace parent, GenericMethod generic,
5137                                       Expression type, int mod, int allowed_mod, int def_mod,
5138                                       MemberName name, Attributes attrs)
5139                         : base (parent, name, attrs)
5140                 {
5141                         this.ds = generic != null ? generic : (DeclSpace) parent;
5142                         explicit_mod_flags = mod;
5143                         Type = type;
5144                         ModFlags = Modifiers.Check (allowed_mod, mod, def_mod, Location);
5145                         IsExplicitImpl = (MemberName.Left != null);
5146                         GenericMethod = generic;
5147                         if (GenericMethod != null)
5148                                 GenericMethod.ModFlags = ModFlags;
5149                 }
5150
5151                 protected virtual bool CheckBase ()
5152                 {
5153                         if ((ModFlags & Modifiers.PROTECTED) != 0 && ParentContainer.Kind == Kind.Struct) {
5154                                 Report.Error (666, Location, "`{0}': new protected member declared in struct", GetSignatureForError ());
5155                                 return false;
5156                         }
5157    
5158                         if ((RootContext.WarningLevel >= 4) &&
5159                             ((Parent.ModFlags & Modifiers.SEALED) != 0) &&
5160                             ((ModFlags & Modifiers.PROTECTED) != 0) &&
5161                             ((ModFlags & Modifiers.OVERRIDE) == 0) && (Name != "Finalize")) {
5162                                 Report.Warning (628, 4, Location, "`{0}': new protected member declared in sealed class", GetSignatureForError ());
5163                         }
5164                         return true;
5165                 }
5166
5167                 protected virtual bool DoDefineBase ()
5168                 {
5169                         if (Name == null)
5170                                 throw new InternalErrorException ();
5171
5172                         if (IsInterface) {
5173                                 ModFlags = Modifiers.PUBLIC |
5174                                         Modifiers.ABSTRACT |
5175                                         Modifiers.VIRTUAL | (ModFlags & Modifiers.UNSAFE) | (ModFlags & Modifiers.NEW);
5176
5177                                 flags = MethodAttributes.Public |
5178                                         MethodAttributes.Abstract |
5179                                         MethodAttributes.HideBySig |
5180                                         MethodAttributes.NewSlot |
5181                                         MethodAttributes.Virtual;
5182                         } else {
5183                                 if (!ParentContainer.MethodModifiersValid (this))
5184                                         return false;
5185
5186                                 flags = Modifiers.MethodAttr (ModFlags);
5187                         }
5188
5189                         if (IsExplicitImpl) {
5190                                 Expression expr = MemberName.Left.GetTypeExpression ();
5191                                 TypeExpr iface_texpr = expr.ResolveAsTypeTerminal (this, false);
5192                                 if (iface_texpr == null)
5193                                         return false;
5194
5195                                 InterfaceType = iface_texpr.Type;
5196
5197                                 if (!InterfaceType.IsInterface) {
5198                                         Report.Error (538, Location, "'{0}' in explicit interface declaration is not an interface", TypeManager.CSharpName (InterfaceType));
5199                                         return false;
5200                                 }
5201
5202                                 if (!ParentContainer.VerifyImplements (this))
5203                                         return false;
5204                                 
5205                                 Modifiers.Check (Modifiers.AllowedExplicitImplFlags, explicit_mod_flags, 0, Location);
5206                         }
5207
5208                         return true;
5209                 }
5210
5211                 protected virtual bool DoDefine ()
5212                 {
5213                         if (MemberType == null)
5214                                 return false;
5215
5216                         if ((Parent.ModFlags & Modifiers.SEALED) != 0 && 
5217                                 (ModFlags & (Modifiers.VIRTUAL|Modifiers.ABSTRACT)) != 0) {
5218                                         Report.Error (549, Location, "New virtual member `{0}' is declared in a sealed class `{1}'",
5219                                                 GetSignatureForError (), Parent.GetSignatureForError ());
5220                                         return false;
5221                         }
5222                         
5223                         // verify accessibility
5224                         if (!Parent.AsAccessible (MemberType, ModFlags)) {
5225                                 Report.SymbolRelatedToPreviousError (MemberType);
5226                                 if (this is Property)
5227                                         Report.Error (53, Location,
5228                                                       "Inconsistent accessibility: property type `" +
5229                                                       TypeManager.CSharpName (MemberType) + "' is less " +
5230                                                       "accessible than property `" + GetSignatureForError () + "'");
5231                                 else if (this is Indexer)
5232                                         Report.Error (54, Location,
5233                                                       "Inconsistent accessibility: indexer return type `" +
5234                                                       TypeManager.CSharpName (MemberType) + "' is less " +
5235                                                       "accessible than indexer `" + GetSignatureForError () + "'");
5236                                 else if (this is MethodCore) {
5237                                         if (this is Operator)
5238                                                 Report.Error (56, Location,
5239                                                               "Inconsistent accessibility: return type `" +
5240                                                               TypeManager.CSharpName (MemberType) + "' is less " +
5241                                                               "accessible than operator `" + GetSignatureForError () + "'");
5242                                         else
5243                                                 Report.Error (50, Location,
5244                                                               "Inconsistent accessibility: return type `" +
5245                                                               TypeManager.CSharpName (MemberType) + "' is less " +
5246                                                               "accessible than method `" + GetSignatureForError () + "'");
5247                                 } else {
5248                                         Report.Error (52, Location,
5249                                                       "Inconsistent accessibility: field type `" +
5250                                                       TypeManager.CSharpName (MemberType) + "' is less " +
5251                                                       "accessible than field `" + GetSignatureForError () + "'");
5252                                 }
5253                                 return false;
5254                         }
5255
5256                         if (IsExplicitImpl) {
5257                                 Expression expr = MemberName.Left.GetTypeExpression ();
5258                                 TypeExpr texpr = expr.ResolveAsTypeTerminal (this, false);
5259                                 if (texpr == null)
5260                                         return false;
5261
5262                                 InterfaceType = texpr.Type;
5263
5264                                 if (!InterfaceType.IsInterface) {
5265                                         Report.Error (538, Location, "`{0}' in explicit interface declaration is not an interface", TypeManager.CSharpName (InterfaceType));
5266                                         return false;
5267                                 }
5268                                 
5269                                 if (!ParentContainer.VerifyImplements (this))
5270                                         return false;
5271                                 
5272                                 Modifiers.Check (Modifiers.AllowedExplicitImplFlags, explicit_mod_flags, 0, Location);
5273                                 
5274                         }
5275                         return true;
5276                 }
5277
5278                 protected bool IsTypePermitted ()
5279                 {
5280                         if (MemberType == TypeManager.arg_iterator_type || MemberType == TypeManager.typed_reference_type) {
5281                                 Report.Error (610, Location, "Field or property cannot be of type `{0}'", TypeManager.CSharpName (MemberType));
5282                                 return false;
5283                         }
5284                         return true;
5285                 }
5286
5287                 protected override bool VerifyClsCompliance()
5288                 {
5289                         if (base.VerifyClsCompliance ()) {
5290                                 return true;
5291                         }
5292
5293                         if (IsInterface && HasClsCompliantAttribute && Parent.IsClsComplianceRequired ()) {
5294                                 Report.Error (3010, Location, "`{0}': CLS-compliant interfaces must have only CLS-compliant members", GetSignatureForError ());
5295                         }
5296                         return false;
5297                 }
5298
5299         }
5300
5301         //
5302         // Fields and Events both generate FieldBuilders, we use this to share 
5303         // their common bits.  This is also used to flag usage of the field
5304         //
5305         abstract public class FieldBase : MemberBase {
5306                 public FieldBuilder  FieldBuilder;
5307                 public Status status;
5308                 protected Expression initializer;
5309                 ExpressionStatement initializerStatement;
5310
5311                 [Flags]
5312                 public enum Status : byte {
5313                         HAS_OFFSET = 4          // Used by FieldMember.
5314                 }
5315
5316                 static string[] attribute_targets = new string [] { "field" };
5317
5318                 /// <summary>
5319                 ///  Symbol with same name in base class/struct
5320                 /// </summary>
5321                 public MemberInfo conflict_symbol;
5322
5323                 protected FieldBase (DeclSpace parent, Expression type, int mod,
5324                                      int allowed_mod, MemberName name, Attributes attrs)
5325                         : base (parent, null, type, mod, allowed_mod, Modifiers.PRIVATE,
5326                                 name, attrs)
5327                 {
5328                 }
5329
5330                 public override AttributeTargets AttributeTargets {
5331                         get {
5332                                 return AttributeTargets.Field;
5333                         }
5334                 }
5335
5336                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
5337                 {
5338                         if (a.Type == TypeManager.marshal_as_attr_type) {
5339                                 UnmanagedMarshal marshal = a.GetMarshal (this);
5340                                 if (marshal != null) {
5341                                         FieldBuilder.SetMarshal (marshal);
5342                                 }
5343                                 return;
5344                         }
5345
5346                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
5347                                 a.Error_InvalidSecurityParent ();
5348                                 return;
5349                         }
5350
5351                         FieldBuilder.SetCustomAttribute (cb);
5352                 }
5353
5354                 public void EmitInitializer (EmitContext ec)
5355                 {
5356                         initializerStatement.EmitStatement (ec);
5357                 }
5358
5359                 protected override bool CheckBase ()
5360                 {
5361                         if (!base.CheckBase ())
5362                                 return false;
5363
5364                         // TODO: Implement
5365                         if (IsInterface)
5366                                 return true;
5367
5368                         conflict_symbol = ParentContainer.FindBaseMemberWithSameName (Name, false);
5369                         if (conflict_symbol == null) {
5370                                 if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0)) {
5371                                         Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
5372                                 }
5373                                 return true;
5374                         }
5375
5376                         if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE)) == 0) {
5377                                 Report.SymbolRelatedToPreviousError (conflict_symbol);
5378                                 Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
5379                                         GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
5380                         }
5381
5382                         return true;
5383                 }
5384
5385                 public Expression Initializer {
5386                         set {
5387                                 if (value != null) {
5388                                         this.initializer = value;
5389                                         ParentContainer.RegisterFieldForInitialization (this);
5390                                 }
5391                         }
5392                 }
5393
5394                 protected virtual bool IsFieldClsCompliant {
5395                         get {
5396                                 if (FieldBuilder == null)
5397                                         return true;
5398
5399                                 return AttributeTester.IsClsCompliant (FieldBuilder.FieldType);
5400                         }
5401                 }
5402
5403                 public Expression ResolveInitializer ()
5404                 {
5405                         // TODO: again it's too heavy-weight
5406                         EmitContext ec = new EmitContext (this, Parent, Location, null, null, ModFlags);
5407                         ec.IsFieldInitializer = true;
5408                         initializer = initializer.Resolve (ec);
5409                         if (initializer == null)
5410                                 return null;
5411
5412                         FieldExpr fe = new FieldExpr (FieldBuilder, Location, true);
5413                         if ((ModFlags & Modifiers.STATIC) == 0) 
5414                         {
5415                                 fe.InstanceExpression = CompilerGeneratedThis.Instance;
5416                         }
5417
5418                         initializerStatement = new Assign (fe, initializer, Location).ResolveStatement (ec);
5419                         return initializer;
5420                 }
5421
5422                 public bool HasDefaultInitializer
5423                 {
5424                         get
5425                         {
5426                                 Constant c = initializer as Constant;
5427                                 if (c == null)
5428                                         return false;
5429
5430                                 return c.IsDefaultInitializer (MemberType);
5431                         }
5432                 }
5433
5434                 public override string[] ValidAttributeTargets 
5435                 {
5436                         get {
5437                                 return attribute_targets;
5438                         }
5439                 }
5440
5441                 protected override bool VerifyClsCompliance ()
5442                 {
5443                         if (!base.VerifyClsCompliance ())
5444                                 return false;
5445
5446                         if (!IsFieldClsCompliant) {
5447                                 Report.Error (3003, Location, "Type of `{0}' is not CLS-compliant", GetSignatureForError ());
5448                         }
5449                         return true;
5450                 }
5451
5452
5453                 public void SetAssigned ()
5454                 {
5455                         caching_flags |= Flags.IsAssigned;
5456                 }
5457         }
5458
5459         public abstract class FieldMember : FieldBase
5460         {
5461                 protected FieldMember (DeclSpace parent, Expression type, int mod,
5462                         int allowed_mod, MemberName name, Attributes attrs)
5463                         : base (parent, type, mod, allowed_mod | Modifiers.ABSTRACT, name, attrs)
5464                 {
5465                         if ((mod & Modifiers.ABSTRACT) != 0)
5466                                 Report.Error (681, Location, "The modifier 'abstract' is not valid on fields. Try using a property instead");
5467                 }
5468
5469                 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
5470                 {
5471                         if (a.Type == TypeManager.field_offset_attribute_type)
5472                         {
5473                                 status |= Status.HAS_OFFSET;
5474
5475                                 if (!ParentContainer.HasExplicitLayout) {
5476                                         Report.Error (636, Location, "The FieldOffset attribute can only be placed on members of types marked with the StructLayout(LayoutKind.Explicit)");
5477                                         return;
5478                                 }
5479
5480                                 if ((ModFlags & Modifiers.STATIC) != 0 || this is Const) {
5481                                         Report.Error (637, Location, "The FieldOffset attribute is not allowed on static or const fields");
5482                                         return;
5483                                 }
5484                         }
5485
5486                         if (a.Type == TypeManager.fixed_buffer_attr_type) {
5487                                 Report.Error (1716, Location, "Do not use 'System.Runtime.CompilerServices.FixedBuffer' attribute. Use the 'fixed' field modifier instead");
5488                                 return;
5489                         }
5490
5491                         base.ApplyAttributeBuilder (a, cb);
5492                 }
5493
5494                 public override bool Define()
5495                 {
5496                         if (MemberType == null || Type == null)
5497                                 return false;
5498                         
5499                         if (MemberType == TypeManager.void_type) {
5500                                 Report.Error (1547, Location, "Keyword 'void' cannot be used in this context");
5501                                 return false;
5502                         }
5503
5504                         if (!CheckBase ())
5505                                 return false;
5506                         
5507                         if (!Parent.AsAccessible (MemberType, ModFlags)) {
5508                                 Report.Error (52, Location,
5509                                         "Inconsistent accessibility: field type `" +
5510                                         TypeManager.CSharpName (MemberType) + "' is less " +
5511                                         "accessible than field `" + GetSignatureForError () + "'");
5512                                 return false;
5513                         }
5514
5515                         if (!IsTypePermitted ())
5516                                 return false;
5517
5518                         return true;
5519                 }
5520
5521                 public override void Emit ()
5522                 {
5523                         if (OptAttributes != null) {
5524                                 OptAttributes.Emit ();
5525                         }
5526
5527                         if (((status & Status.HAS_OFFSET) == 0) && (ModFlags & Modifiers.STATIC) == 0 && ParentContainer.HasExplicitLayout) {
5528                                 Report.Error (625, Location, "`{0}': Instance field types marked with StructLayout(LayoutKind.Explicit) must have a FieldOffset attribute.", GetSignatureForError ());
5529                         }
5530
5531                         base.Emit ();
5532                 }
5533
5534                 //
5535                 //   Represents header string for documentation comment.
5536                 //
5537                 public override string DocCommentHeader {
5538                         get { return "F:"; }
5539                 }
5540         }
5541
5542         interface IFixedBuffer
5543         {
5544                 FieldInfo Element { get; }
5545                 Type ElementType { get; }
5546         }
5547
5548         public class FixedFieldExternal: IFixedBuffer
5549         {
5550                 FieldInfo element_field;
5551
5552                 public FixedFieldExternal (FieldInfo fi)
5553                 {
5554                         element_field = fi.FieldType.GetField (FixedField.FixedElementName);
5555                 }
5556
5557                 #region IFixedField Members
5558
5559                 public FieldInfo Element {
5560                         get {
5561                                 return element_field;
5562                         }
5563                 }
5564
5565                 public Type ElementType {
5566                         get {
5567                                 return element_field.FieldType;
5568                         }
5569                 }
5570
5571                 #endregion
5572         }
5573
5574         /// <summary>
5575         /// Fixed buffer implementation
5576         /// </summary>
5577         public class FixedField : FieldMember, IFixedBuffer
5578         {
5579                 public const string FixedElementName = "FixedElementField";
5580                 static int GlobalCounter = 0;
5581                 static object[] ctor_args = new object[] { (short)LayoutKind.Sequential };
5582                 static FieldInfo[] fi;
5583
5584                 TypeBuilder fixed_buffer_type;
5585                 FieldBuilder element;
5586                 Expression size_expr;
5587                 int buffer_size;
5588
5589                 const int AllowedModifiers =
5590                         Modifiers.NEW |
5591                         Modifiers.PUBLIC |
5592                         Modifiers.PROTECTED |
5593                         Modifiers.INTERNAL |
5594                         Modifiers.PRIVATE;
5595
5596                 public FixedField (DeclSpace parent, Expression type, int mod, string name,
5597                         Expression size_expr, Attributes attrs, Location loc):
5598                         base (parent, type, mod, AllowedModifiers, new MemberName (name, loc), attrs)
5599                 {
5600                         if (RootContext.Version == LanguageVersion.ISO_1)
5601                                 Report.FeatureIsNotStandardized (loc, "fixed size buffers");
5602
5603                         this.size_expr = size_expr;
5604                 }
5605
5606                 public override bool Define()
5607                 {
5608 #if !NET_2_0
5609                         if ((ModFlags & (Modifiers.PUBLIC | Modifiers.PROTECTED)) != 0)
5610                                 Report.Warning (-23, 1, Location, "Only private or internal fixed sized buffers are supported by .NET 1.x");
5611 #endif
5612
5613                         if (ParentContainer.Kind != Kind.Struct) {
5614                                 Report.Error (1642, Location, "`{0}': Fixed size buffer fields may only be members of structs",
5615                                         GetSignatureForError ());
5616                                 return false;
5617                         }
5618
5619                         if (!base.Define ())
5620                                 return false;
5621
5622                         if (!TypeManager.IsPrimitiveType (MemberType)) {
5623                                 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",
5624                                         GetSignatureForError ());
5625                                 return false;
5626                         }
5627
5628                         EmitContext ec = new EmitContext (this, Parent, Location, null, null, ModFlags);
5629                         Constant c = size_expr.ResolveAsConstant (ec, this);
5630                         if (c == null)
5631                                 return false;
5632
5633                         IntConstant buffer_size_const = c.ToInt (Location);
5634                         if (buffer_size_const == null)
5635                                 return false;
5636
5637                         buffer_size = buffer_size_const.Value;
5638
5639                         if (buffer_size <= 0) {
5640                                 Report.Error (1665, Location, "`{0}': Fixed size buffers must have a length greater than zero", GetSignatureForError ());
5641                                 return false;
5642                         }
5643
5644                         int type_size = Expression.GetTypeSize (MemberType);
5645
5646                         if (buffer_size > int.MaxValue / type_size) {
5647                                 Report.Error (1664, Location, "Fixed size buffer `{0}' of length `{1}' and type `{2}' exceeded 2^31 limit",
5648                                         GetSignatureForError (), buffer_size.ToString (), TypeManager.CSharpName (MemberType));
5649                                 return false;
5650                         }
5651
5652                         buffer_size *= type_size;
5653
5654                         // Define nested
5655                         string name = String.Format ("<{0}>__FixedBuffer{1}", Name, GlobalCounter++);
5656
5657                         fixed_buffer_type = Parent.TypeBuilder.DefineNestedType (name,
5658                                 TypeAttributes.NestedPublic | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit, TypeManager.value_type);
5659                         element = fixed_buffer_type.DefineField (FixedElementName, MemberType, FieldAttributes.Public);
5660                         RootContext.RegisterCompilerGeneratedType (fixed_buffer_type);
5661
5662                         FieldBuilder = Parent.TypeBuilder.DefineField (Name, fixed_buffer_type, Modifiers.FieldAttr (ModFlags));
5663                         TypeManager.RegisterFieldBase (FieldBuilder, this);
5664
5665                         return true;
5666                 }
5667
5668                 public override void Emit()
5669                 {
5670                         if (fi == null)
5671                                 fi = new FieldInfo [] { TypeManager.struct_layout_attribute_type.GetField ("Size") };
5672
5673                         object[] fi_val = new object[1];
5674                         fi_val [0] = buffer_size;
5675
5676                         CustomAttributeBuilder cab = new CustomAttributeBuilder (TypeManager.struct_layout_attribute_ctor, 
5677                                 ctor_args, fi, fi_val);
5678                         fixed_buffer_type.SetCustomAttribute (cab);
5679
5680                         cab = new CustomAttributeBuilder (TypeManager.fixed_buffer_attr_ctor, new object[] { MemberType, buffer_size } );
5681                         FieldBuilder.SetCustomAttribute (cab);
5682                         base.Emit ();
5683                 }
5684
5685                 protected override bool IsFieldClsCompliant {
5686                         get {
5687                                 return false;
5688                         }
5689                 }
5690
5691                 #region IFixedField Members
5692
5693                 public FieldInfo Element {
5694                         get {
5695                                 return element;
5696                         }
5697                 }
5698
5699                 public Type ElementType {
5700                         get {
5701                                 return MemberType;
5702                         }
5703                 }
5704
5705                 #endregion
5706         }
5707
5708         //
5709         // The Field class is used to represents class/struct fields during parsing.
5710         //
5711         public class Field : FieldMember {
5712                 // <summary>
5713                 //   Modifiers allowed in a class declaration
5714                 // </summary>
5715                 const int AllowedModifiers =
5716                         Modifiers.NEW |
5717                         Modifiers.PUBLIC |
5718                         Modifiers.PROTECTED |
5719                         Modifiers.INTERNAL |
5720                         Modifiers.PRIVATE |
5721                         Modifiers.STATIC |
5722                         Modifiers.VOLATILE |
5723                         Modifiers.UNSAFE |
5724                         Modifiers.READONLY;
5725
5726                 public Field (DeclSpace parent, Expression type, int mod, string name,
5727                               Attributes attrs, Location loc)
5728                         : base (parent, type, mod, AllowedModifiers, new MemberName (name, loc),
5729                                 attrs)
5730                 {
5731                 }
5732
5733                 public override bool Define ()
5734                 {
5735                         if (!base.Define ())
5736                                 return false;
5737
5738                         if (RootContext.WarningLevel > 1){
5739                                 Type ptype = Parent.TypeBuilder.BaseType;
5740
5741                                 // ptype is only null for System.Object while compiling corlib.
5742                                 if (ptype != null){
5743                                         TypeContainer.FindMembers (
5744                                                 ptype, MemberTypes.Method,
5745                                                 BindingFlags.Public |
5746                                                 BindingFlags.Static | BindingFlags.Instance,
5747                                                 System.Type.FilterName, Name);
5748                                 }
5749                         }
5750
5751                         if ((ModFlags & Modifiers.VOLATILE) != 0){
5752                                 if (!MemberType.IsClass){
5753                                         Type vt = MemberType;
5754                                         
5755                                         if (TypeManager.IsEnumType (vt))
5756                                                 vt = TypeManager.EnumToUnderlying (MemberType);
5757
5758                                         if (!((vt == TypeManager.bool_type) ||
5759                                               (vt == TypeManager.sbyte_type) ||
5760                                               (vt == TypeManager.byte_type) ||
5761                                               (vt == TypeManager.short_type) ||
5762                                               (vt == TypeManager.ushort_type) ||
5763                                               (vt == TypeManager.int32_type) ||
5764                                               (vt == TypeManager.uint32_type) ||    
5765                                               (vt == TypeManager.char_type) ||
5766                                               (vt == TypeManager.float_type) ||
5767                                               (!vt.IsValueType))){
5768                                                 Report.Error (677, Location, "`{0}': A volatile field cannot be of the type `{1}'",
5769                                                         GetSignatureForError (), TypeManager.CSharpName (vt));
5770                                                 return false;
5771                                         }
5772                                 }
5773
5774                                 if ((ModFlags & Modifiers.READONLY) != 0){
5775                                         Report.Error (678, Location, "`{0}': A field cannot be both volatile and readonly",
5776                                                 GetSignatureForError ());
5777                                         return false;
5778                                 }
5779                         }
5780
5781                         FieldAttributes fa = Modifiers.FieldAttr (ModFlags);
5782
5783                         if (ParentContainer.Kind == Kind.Struct && 
5784                             ((fa & FieldAttributes.Static) == 0) &&
5785                             MemberType == Parent.TypeBuilder &&
5786                             !TypeManager.IsBuiltinType (MemberType)){
5787                                 Report.Error (523, Location, "Struct member `" + Parent.Name + "." + Name + 
5788                                               "' causes a cycle in the structure layout");
5789                                 return false;
5790                         }
5791
5792                         try {
5793                                 FieldBuilder = Parent.TypeBuilder.DefineField (
5794                                         Name, MemberType, Modifiers.FieldAttr (ModFlags));
5795
5796                         TypeManager.RegisterFieldBase (FieldBuilder, this);
5797                         }
5798                         catch (ArgumentException) {
5799                                 Report.Warning (-24, 1, Location, "The Microsoft runtime is unable to use [void|void*] as a field type, try using the Mono runtime.");
5800                                 return false;
5801                         }
5802
5803                         return true;
5804                 }
5805
5806                 protected override bool VerifyClsCompliance ()
5807                 {
5808                         if (!base.VerifyClsCompliance ())
5809                                 return false;
5810
5811                         if ((ModFlags & Modifiers.VOLATILE) != 0) {
5812                                 Report.Warning (3026, 1, Location, "CLS-compliant field `{0}' cannot be volatile", GetSignatureForError ());
5813                         }
5814
5815                         return true;
5816                 }
5817         }
5818
5819         //
5820         // `set' and `get' accessors are represented with an Accessor.
5821         // 
5822         public class Accessor : IIteratorContainer {
5823                 //
5824                 // Null if the accessor is empty, or a Block if not
5825                 //
5826                 public const int AllowedModifiers = 
5827                         Modifiers.PUBLIC |
5828                         Modifiers.PROTECTED |
5829                         Modifiers.INTERNAL |
5830                         Modifiers.PRIVATE;
5831                 
5832                 public ToplevelBlock Block;
5833                 public Attributes Attributes;
5834                 public Location Location;
5835                 public int ModFlags;
5836                 public bool Yields;
5837                 
5838                 public Accessor (ToplevelBlock b, int mod, Attributes attrs, Location loc)
5839                 {
5840                         Block = b;
5841                         Attributes = attrs;
5842                         Location = loc;
5843                         ModFlags = Modifiers.Check (AllowedModifiers, mod, 0, loc);
5844                 }
5845
5846                 public void SetYields ()
5847                 {
5848                         Yields = true;
5849                 }
5850         }
5851
5852         // Ooouh Martin, templates are missing here.
5853         // When it will be possible move here a lot of child code and template method type.
5854         public abstract class AbstractPropertyEventMethod : MemberCore, IMethodData {
5855                 protected MethodData method_data;
5856                 protected ToplevelBlock block;
5857                 protected ListDictionary declarative_security;
5858
5859                 // The accessor are created event if they are not wanted.
5860                 // But we need them because their names are reserved.
5861                 // Field says whether accessor will be emited or not
5862                 public readonly bool IsDummy;
5863
5864                 protected readonly string prefix;
5865
5866                 ReturnParameter return_attributes;
5867
5868                 public AbstractPropertyEventMethod (MemberBase member, string prefix)
5869                         : base (member.Parent, SetupName (prefix, member, member.Location), null)
5870                 {
5871                         this.prefix = prefix;
5872                         IsDummy = true;
5873                 }
5874
5875                 public AbstractPropertyEventMethod (MemberBase member, Accessor accessor,
5876                                                     string prefix)
5877                         : base (member.Parent, SetupName (prefix, member, accessor.Location),
5878                                 accessor.Attributes)
5879                 {
5880                         this.prefix = prefix;
5881                         this.block = accessor.Block;
5882                 }
5883
5884                 static MemberName SetupName (string prefix, MemberBase member, Location loc)
5885                 {
5886                         return new MemberName (member.MemberName.Left, prefix + member.ShortName, loc);
5887                 }
5888
5889                 public void UpdateName (MemberBase member)
5890                 {
5891                         SetMemberName (SetupName (prefix, member, Location));
5892                 }
5893
5894                 #region IMethodData Members
5895
5896                 public ToplevelBlock Block {
5897                         get {
5898                                 return block;
5899                         }
5900
5901                         set {
5902                                 block = value;
5903                         }
5904                 }
5905
5906                 public CallingConventions CallingConventions {
5907                         get {
5908                                 return CallingConventions.Standard;
5909                         }
5910                 }
5911
5912                 public bool IsExcluded ()
5913                 {
5914                         return false;
5915                 }
5916
5917                 GenericMethod IMethodData.GenericMethod {
5918                         get {
5919                                 return null;
5920                         }
5921                 }
5922
5923                 public MemberName MethodName {
5924                         get {
5925                                 return MemberName;
5926                         }
5927                 }
5928
5929                 public Type[] ParameterTypes { 
5930                         get {
5931                                 return ParameterInfo.Types;
5932                         }
5933                 }
5934
5935                 public abstract Parameters ParameterInfo { get ; }
5936                 public abstract Type ReturnType { get; }
5937                 public abstract EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig);
5938
5939                 #endregion
5940
5941                 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
5942                 {
5943                         if (a.Type == TypeManager.cls_compliant_attribute_type || a.Type == TypeManager.obsolete_attribute_type ||
5944                                         a.Type == TypeManager.conditional_attribute_type) {
5945                                 Report.Error (1667, a.Location,
5946                                         "Attribute `{0}' is not valid on property or event accessors. It is valid on `{1}' declarations only",
5947                                         TypeManager.CSharpName (a.Type), a.GetValidTargets ());
5948                                 return;
5949                         }
5950
5951                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
5952                                 if (declarative_security == null)
5953                                         declarative_security = new ListDictionary ();
5954                                 a.ExtractSecurityPermissionSet (declarative_security);
5955                                 return;
5956                         }
5957
5958                         if (a.Target == AttributeTargets.Method) {
5959                                 method_data.MethodBuilder.SetCustomAttribute (cb);
5960                                 return;
5961                         }
5962
5963                         if (a.Target == AttributeTargets.ReturnValue) {
5964                                 if (return_attributes == null)
5965                                         return_attributes = new ReturnParameter (method_data.MethodBuilder, Location);
5966
5967                                 return_attributes.ApplyAttributeBuilder (a, cb);
5968                                 return;
5969                         }
5970
5971                         ApplyToExtraTarget (a, cb);
5972                 }
5973
5974                 virtual protected void ApplyToExtraTarget (Attribute a, CustomAttributeBuilder cb)
5975                 {
5976                         System.Diagnostics.Debug.Fail ("You forgot to define special attribute target handling");
5977                 }
5978
5979                 public override bool Define()
5980                 {
5981                         throw new NotSupportedException ();
5982                 }
5983
5984                 public void Emit (DeclSpace parent)
5985                 {
5986                         EmitMethod (parent);
5987
5988                         if (OptAttributes != null)
5989                                 OptAttributes.Emit ();
5990
5991                         if (declarative_security != null) {
5992                                 foreach (DictionaryEntry de in declarative_security) {
5993                                         method_data.MethodBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
5994                                 }
5995                         }
5996
5997                         block = null;
5998                 }
5999
6000                 protected virtual void EmitMethod (DeclSpace parent)
6001                 {
6002                         method_data.Emit (parent);
6003                 }
6004
6005                 public override bool IsClsComplianceRequired()
6006                 {
6007                         return false;
6008                 }
6009
6010                 public bool IsDuplicateImplementation (MethodCore method)
6011                 {
6012                         if (!MemberName.Equals (method.MemberName))
6013                                 return false;
6014
6015                         Type[] param_types = method.ParameterTypes;
6016
6017                         if (param_types.Length != ParameterTypes.Length)
6018                                 return false;
6019
6020                         for (int i = 0; i < param_types.Length; i++)
6021                                 if (param_types [i] != ParameterTypes [i])
6022                                         return false;
6023
6024                         Report.SymbolRelatedToPreviousError (method);
6025                         Report.Error (111, Location, TypeContainer.Error111, method.GetSignatureForError ());
6026                         return true;
6027                 }
6028
6029                 public override bool IsUsed
6030                 {
6031                         get {
6032                                 if (IsDummy)
6033                                         return false;
6034
6035                                 return base.IsUsed;
6036                         }
6037                 }
6038
6039                 public new Location Location { 
6040                         get {
6041                                 return base.Location;
6042                         }
6043                 }
6044
6045                 //
6046                 //   Represents header string for documentation comment.
6047                 //
6048                 public override string DocCommentHeader {
6049                         get { throw new InvalidOperationException ("Unexpected attempt to get doc comment from " + this.GetType () + "."); }
6050                 }
6051
6052         }
6053
6054         //
6055         // Properties and Indexers both generate PropertyBuilders, we use this to share 
6056         // their common bits.
6057         //
6058         abstract public class PropertyBase : MethodCore {
6059
6060                 public class GetMethod : PropertyMethod
6061                 {
6062                         static string[] attribute_targets = new string [] { "method", "return" };
6063
6064                         public GetMethod (MethodCore method):
6065                                 base (method, "get_")
6066                         {
6067                         }
6068
6069                         public GetMethod (MethodCore method, Accessor accessor):
6070                                 base (method, accessor, "get_")
6071                         {
6072                         }
6073
6074                         public override MethodBuilder Define (DeclSpace parent)
6075                         {
6076                                 base.Define (parent);
6077                                 
6078                                 method_data = new MethodData (method, ModFlags, flags, this);
6079
6080                                 if (!method_data.Define (parent))
6081                                         return null;
6082
6083                                 return method_data.MethodBuilder;
6084                         }
6085
6086                         public override Type ReturnType {
6087                                 get {
6088                                         return method.MemberType;
6089                                 }
6090                         }
6091
6092                         public override Parameters ParameterInfo {
6093                                 get {
6094                                         return Parameters.EmptyReadOnlyParameters;
6095                                 }
6096                         }
6097
6098                         public override string[] ValidAttributeTargets {
6099                                 get {
6100                                         return attribute_targets;
6101                                 }
6102                         }
6103                 }
6104
6105                 public class SetMethod : PropertyMethod {
6106
6107                         static string[] attribute_targets = new string [] { "method", "param", "return" };
6108                         ImplicitParameter param_attr;
6109                         protected Parameters parameters;
6110
6111                         public SetMethod (MethodCore method):
6112                                 base (method, "set_")
6113                         {
6114                         }
6115
6116                         public SetMethod (MethodCore method, Accessor accessor):
6117                                 base (method, accessor, "set_")
6118                         {
6119                         }
6120
6121                         protected override void ApplyToExtraTarget(Attribute a, CustomAttributeBuilder cb)
6122                         {
6123                                 if (a.Target == AttributeTargets.Parameter) {
6124                                         if (param_attr == null)
6125                                                 param_attr = new ImplicitParameter (method_data.MethodBuilder);
6126
6127                                         param_attr.ApplyAttributeBuilder (a, cb);
6128                                         return;
6129                                 }
6130
6131                                 base.ApplyAttributeBuilder (a, cb);
6132                         }
6133
6134                         public override Parameters ParameterInfo {
6135                                 get {
6136                                         return parameters;
6137                                 }
6138                         }
6139
6140                         protected virtual void DefineParameters ()
6141                         {
6142                                 parameters = new Parameters (
6143                                         new Parameter[] { new Parameter (method.MemberType, "value", Parameter.Modifier.NONE, null, Location) },
6144                                         new Type[] { method.MemberType });
6145                         }
6146
6147                         public override MethodBuilder Define (DeclSpace parent)
6148                         {
6149                                 DefineParameters ();
6150                                 if (IsDummy)
6151                                         return null;
6152
6153                                 base.Define (parent);
6154
6155                                 method_data = new MethodData (method, ModFlags, flags, this);
6156
6157                                 if (!method_data.Define (parent))
6158                                         return null;
6159
6160                                 return method_data.MethodBuilder;
6161                         }
6162
6163                         public override Type ReturnType {
6164                                 get {
6165                                         return TypeManager.void_type;
6166                                 }
6167                         }
6168
6169                         public override string[] ValidAttributeTargets {
6170                                 get {
6171                                         return attribute_targets;
6172                                 }
6173                         }
6174                 }
6175
6176                 static string[] attribute_targets = new string [] { "property" };
6177
6178                 public abstract class PropertyMethod : AbstractPropertyEventMethod
6179                 {
6180                         protected readonly MethodCore method;
6181                         protected MethodAttributes flags;
6182                         bool yields;
6183
6184                         public PropertyMethod (MethodCore method, string prefix)
6185                                 : base (method, prefix)
6186                         {
6187                                 this.method = method;
6188                         }
6189
6190                         public PropertyMethod (MethodCore method, Accessor accessor,
6191                                                string prefix)
6192                                 : base (method, accessor, prefix)
6193                         {
6194                                 this.method = method;
6195                                 this.ModFlags = accessor.ModFlags;
6196                                 yields = accessor.Yields;
6197
6198                                 if (accessor.ModFlags != 0 && RootContext.Version == LanguageVersion.ISO_1) {
6199                                         Report.FeatureIsNotStandardized (Location, "access modifiers on properties");
6200                                 }
6201                         }
6202
6203                         public override AttributeTargets AttributeTargets {
6204                                 get {
6205                                         return AttributeTargets.Method;
6206                                 }
6207                         }
6208
6209                         public override bool IsClsComplianceRequired ()
6210                         {
6211                                 return method.IsClsComplianceRequired ();
6212                         }
6213
6214                         public virtual MethodBuilder Define (DeclSpace parent)
6215                         {
6216                                 if (!method.CheckAbstractAndExtern (block != null))
6217                                         return null;
6218
6219                                 TypeContainer container = ((TypeContainer) parent).PartialContainer;
6220
6221                                 //
6222                                 // Check for custom access modifier
6223                                 //
6224                                 if (ModFlags == 0) {
6225                                         ModFlags = method.ModFlags;
6226                                         flags = method.flags;
6227                                 } else {
6228                                         if (container.Kind == Kind.Interface)
6229                                                 Report.Error (275, Location, "`{0}': accessibility modifiers may not be used on accessors in an interface",
6230                                                         GetSignatureForError ());
6231
6232                                         if ((method.ModFlags & Modifiers.ABSTRACT) != 0 && (ModFlags & Modifiers.PRIVATE) != 0) {
6233                                                 Report.Error (442, Location, "`{0}': abstract properties cannot have private accessors", GetSignatureForError ());
6234                                         }
6235
6236                                         CheckModifiers (ModFlags);
6237                                         ModFlags |= (method.ModFlags & (~Modifiers.Accessibility));
6238                                         ModFlags |= Modifiers.PROPERTY_CUSTOM;
6239                                         flags = Modifiers.MethodAttr (ModFlags);
6240                                         flags |= (method.flags & (~MethodAttributes.MemberAccessMask));
6241                                 }
6242
6243                                 //
6244                                 // Setup iterator if we are one
6245                                 //
6246                                 if (yields) {
6247                                         Iterator iterator = new Iterator (this, Parent as TypeContainer, null, ModFlags);
6248                                         
6249                                         if (!iterator.DefineIterator ())
6250                                                 return null;
6251                                 }
6252
6253                                 return null;
6254                         }
6255
6256                         public bool HasCustomAccessModifier
6257                         {
6258                                 get {
6259                                         return (ModFlags & Modifiers.PROPERTY_CUSTOM) != 0;
6260                                 }
6261                         }
6262
6263                         public override EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig)
6264                         {
6265                                 return new EmitContext (method,
6266                                         ds, method.ds, method.Location, ig, ReturnType,
6267                                         method.ModFlags, false);
6268                         }
6269
6270                         public override ObsoleteAttribute GetObsoleteAttribute ()
6271                         {
6272                                 return method.GetObsoleteAttribute ();
6273                         }
6274
6275                         public override string GetSignatureForError()
6276                         {
6277                                 return method.GetSignatureForError () + '.' + prefix.Substring (0, 3);
6278                         }
6279
6280                         void CheckModifiers (int modflags)
6281                         {
6282                                 int flags = 0;
6283                                 int mflags = method.ModFlags & Modifiers.Accessibility;
6284
6285                                 if ((mflags & Modifiers.PUBLIC) != 0) {
6286                                         flags |= Modifiers.PROTECTED | Modifiers.INTERNAL | Modifiers.PRIVATE;
6287                                 }
6288                                 else if ((mflags & Modifiers.PROTECTED) != 0) {
6289                                         if ((mflags & Modifiers.INTERNAL) != 0)
6290                                                 flags |= Modifiers.PROTECTED | Modifiers.INTERNAL;
6291
6292                                         flags |= Modifiers.PRIVATE;
6293                                 }
6294                                 else if ((mflags & Modifiers.INTERNAL) != 0)
6295                                         flags |= Modifiers.PRIVATE;
6296
6297                                 if ((mflags == modflags) || (modflags & (~flags)) != 0) {
6298                                         Report.Error (273, Location,
6299                                                 "The accessibility modifier of the `{0}' accessor must be more restrictive than the modifier of the property or indexer `{1}'",
6300                                                 GetSignatureForError (), method.GetSignatureForError ());
6301                                 }
6302                         }
6303
6304                         public override bool MarkForDuplicationCheck ()
6305                         {
6306                                 caching_flags |= Flags.TestMethodDuplication;
6307                                 return true;
6308                         }
6309                 }
6310
6311                 public PropertyMethod Get, Set;
6312                 public PropertyBuilder PropertyBuilder;
6313                 public MethodBuilder GetBuilder, SetBuilder;
6314
6315                 protected EmitContext ec;
6316
6317                 public PropertyBase (DeclSpace parent, Expression type, int mod_flags,
6318                                      int allowed_mod, bool is_iface, MemberName name,
6319                                      Parameters parameters, Attributes attrs)
6320                         : base (parent, null, type, mod_flags, allowed_mod, is_iface, name,
6321                                 attrs, parameters)
6322                 {
6323                 }
6324
6325                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
6326                 {
6327                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
6328                                 a.Error_InvalidSecurityParent ();
6329                                 return;
6330                         }
6331
6332                         PropertyBuilder.SetCustomAttribute (cb);
6333                 }
6334
6335                 public override AttributeTargets AttributeTargets {
6336                         get {
6337                                 return AttributeTargets.Property;
6338                         }
6339                 }
6340
6341                 public override bool Define ()
6342                 {
6343                         if (!DoDefine ())
6344                                 return false;
6345
6346                         if (!IsTypePermitted ())
6347                                 return false;
6348
6349                         return true;
6350                 }
6351
6352                 protected override bool DoDefine ()
6353                 {
6354                         if (!base.DoDefine ())
6355                                 return false;
6356
6357                         //
6358                         // Accessors modifiers check
6359                         //
6360                         if (Get.ModFlags != 0 && Set.ModFlags != 0) {
6361                                 Report.Error (274, Location, "`{0}': Cannot specify accessibility modifiers for both accessors of the property or indexer",
6362                                                 GetSignatureForError ());
6363                                 return false;
6364                         }
6365
6366                         if ((Get.IsDummy || Set.IsDummy)
6367                                         && (Get.ModFlags != 0 || Set.ModFlags != 0) && (ModFlags & Modifiers.OVERRIDE) == 0) {
6368                                 Report.Error (276, Location, 
6369                                         "`{0}': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor",
6370                                         GetSignatureForError ());
6371                                 return false;
6372                         }
6373
6374                         if (MemberType.IsAbstract && MemberType.IsSealed) {
6375                                 Report.Error (722, Location, Error722, TypeManager.CSharpName (MemberType));
6376                                 return false;
6377                         }
6378
6379                         ec = new EmitContext (this, Parent, Location, null, MemberType, ModFlags);
6380                         return true;
6381                 }
6382
6383                 protected override bool CheckForDuplications ()
6384                 {
6385                         ArrayList ar = ParentContainer.Indexers;
6386                         if (ar != null) {
6387                                 int arLen = ar.Count;
6388                                         
6389                                 for (int i = 0; i < arLen; i++) {
6390                                         Indexer m = (Indexer) ar [i];
6391                                         if (IsDuplicateImplementation (m))
6392                                                 return false;
6393                                 }
6394                         }
6395
6396                         ar = ParentContainer.Properties;
6397                         if (ar != null) {
6398                                 int arLen = ar.Count;
6399                                         
6400                                 for (int i = 0; i < arLen; i++) {
6401                                         Property m = (Property) ar [i];
6402                                         if (IsDuplicateImplementation (m))
6403                                                 return false;
6404                                 }
6405                         }
6406
6407                         return true;
6408                 }
6409
6410                 // TODO: rename to Resolve......
6411                 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
6412                 {
6413                         PropertyInfo base_property = ParentContainer.BaseCache.FindMemberToOverride (
6414                                 Parent.TypeBuilder, Name, ParameterTypes, null, true) as PropertyInfo;
6415
6416                         if (base_property == null)
6417                                 return null;
6418
6419                         base_ret_type = base_property.PropertyType;
6420                         MethodInfo get_accessor = base_property.GetGetMethod (true);
6421                         MethodInfo set_accessor = base_property.GetSetMethod (true);
6422                         MethodAttributes get_accessor_access, set_accessor_access;
6423
6424                         if ((ModFlags & Modifiers.OVERRIDE) != 0) {
6425                                 if (Get != null && !Get.IsDummy && get_accessor == null) {
6426                                         Report.SymbolRelatedToPreviousError (base_property);
6427                                         Report.Error (545, Location, "`{0}.get': cannot override because `{1}' does not have an overridable get accessor", GetSignatureForError (), TypeManager.GetFullNameSignature (base_property));
6428                                 }
6429
6430                                 if (Set != null && !Set.IsDummy && set_accessor == null) {
6431                                         Report.SymbolRelatedToPreviousError (base_property);
6432                                         Report.Error (546, Location, "`{0}.set': cannot override because `{1}' does not have an overridable set accessor", GetSignatureForError (), TypeManager.GetFullNameSignature (base_property));
6433                                 }
6434                         }
6435                         
6436                         //
6437                         // Check base class accessors access
6438                         //
6439
6440                         // TODO: rewrite to reuse Get|Set.CheckAccessModifiers and share code there
6441                         get_accessor_access = set_accessor_access = 0;
6442                         if ((ModFlags & Modifiers.NEW) == 0) {
6443                                 if (get_accessor != null) {
6444                                         MethodAttributes get_flags = Modifiers.MethodAttr (Get.ModFlags != 0 ? Get.ModFlags : ModFlags);
6445                                         get_accessor_access = (get_accessor.Attributes & MethodAttributes.MemberAccessMask);
6446
6447                                         if (!Get.IsDummy && !CheckAccessModifiers (get_flags & MethodAttributes.MemberAccessMask, get_accessor_access, get_accessor))
6448                                                 Error_CannotChangeAccessModifiers (get_accessor, get_accessor_access,  ".get");
6449                                 }
6450
6451                                 if (set_accessor != null)  {
6452                                         MethodAttributes set_flags = Modifiers.MethodAttr (Set.ModFlags != 0 ? Set.ModFlags : ModFlags);
6453                                         set_accessor_access = (set_accessor.Attributes & MethodAttributes.MemberAccessMask);
6454
6455                                         if (!Set.IsDummy && !CheckAccessModifiers (set_flags & MethodAttributes.MemberAccessMask, set_accessor_access, set_accessor))
6456                                                 Error_CannotChangeAccessModifiers (set_accessor, set_accessor_access, ".set");
6457                                 }
6458                         }
6459
6460                         //
6461                         // Get the less restrictive access
6462                         //
6463                         return get_accessor_access > set_accessor_access ? get_accessor : set_accessor;
6464                 }
6465
6466                 public override void Emit ()
6467                 {
6468                         //
6469                         // The PropertyBuilder can be null for explicit implementations, in that
6470                         // case, we do not actually emit the ".property", so there is nowhere to
6471                         // put the attribute
6472                         //
6473                         if (PropertyBuilder != null && OptAttributes != null)
6474                                 OptAttributes.Emit ();
6475
6476                         if (!Get.IsDummy)
6477                                 Get.Emit (Parent);
6478
6479                         if (!Set.IsDummy)
6480                                 Set.Emit (Parent);
6481
6482                         base.Emit ();
6483                 }
6484
6485                 /// <summary>
6486                 /// Tests whether accessors are not in collision with some method (CS0111)
6487                 /// </summary>
6488                 public bool AreAccessorsDuplicateImplementation (MethodCore mc)
6489                 {
6490                         return Get.IsDuplicateImplementation (mc) || Set.IsDuplicateImplementation (mc);
6491                 }
6492
6493                 public override bool IsUsed
6494                 {
6495                         get {
6496                                 if (IsExplicitImpl)
6497                                         return true;
6498
6499                                 return Get.IsUsed | Set.IsUsed;
6500                         }
6501                 }
6502
6503                 protected override void SetMemberName (MemberName new_name)
6504                 {
6505                         base.SetMemberName (new_name);
6506
6507                         Get.UpdateName (this);
6508                         Set.UpdateName (this);
6509                 }
6510
6511                 public override string[] ValidAttributeTargets {
6512                         get {
6513                                 return attribute_targets;
6514                         }
6515                 }
6516
6517                 //
6518                 //   Represents header string for documentation comment.
6519                 //
6520                 public override string DocCommentHeader {
6521                         get { return "P:"; }
6522                 }
6523         }
6524                         
6525         public class Property : PropertyBase {
6526                 const int AllowedModifiers =
6527                         Modifiers.NEW |
6528                         Modifiers.PUBLIC |
6529                         Modifiers.PROTECTED |
6530                         Modifiers.INTERNAL |
6531                         Modifiers.PRIVATE |
6532                         Modifiers.STATIC |
6533                         Modifiers.SEALED |
6534                         Modifiers.OVERRIDE |
6535                         Modifiers.ABSTRACT |
6536                         Modifiers.UNSAFE |
6537                         Modifiers.EXTERN |
6538                         Modifiers.METHOD_YIELDS |
6539                         Modifiers.VIRTUAL;
6540
6541                 const int AllowedInterfaceModifiers =
6542                         Modifiers.NEW;
6543
6544                 public Property (DeclSpace parent, Expression type, int mod, bool is_iface,
6545                                  MemberName name, Attributes attrs, Accessor get_block,
6546                                  Accessor set_block)
6547                         : base (parent, type, mod,
6548                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
6549                                 is_iface, name, Parameters.EmptyReadOnlyParameters, attrs)
6550                 {
6551                         if (get_block == null)
6552                                 Get = new GetMethod (this);
6553                         else
6554                                 Get = new GetMethod (this, get_block);
6555
6556                         if (set_block == null)
6557                                 Set = new SetMethod (this);
6558                         else
6559                                 Set = new SetMethod (this, set_block);
6560                 }
6561
6562                 public override bool Define ()
6563                 {
6564                         if (!DoDefineBase ())
6565                                 return false;
6566
6567                         if (!base.Define ())
6568                                 return false;
6569
6570                         if (!CheckBase ())
6571                                 return false;
6572
6573                         flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
6574
6575                         if (!Get.IsDummy) {
6576                                 GetBuilder = Get.Define (Parent);
6577                                 if (GetBuilder == null)
6578                                         return false;
6579                         }
6580
6581                         SetBuilder = Set.Define (Parent);
6582                         if (!Set.IsDummy) {
6583                                 if (SetBuilder == null)
6584                                         return false;
6585                         }
6586
6587                         // FIXME - PropertyAttributes.HasDefault ?
6588
6589                         PropertyBuilder = Parent.TypeBuilder.DefineProperty (
6590                                 MemberName.ToString (), PropertyAttributes.None, MemberType, null);
6591
6592                         if (!Get.IsDummy)
6593                                 PropertyBuilder.SetGetMethod (GetBuilder);
6594
6595                         if (!Set.IsDummy)
6596                                 PropertyBuilder.SetSetMethod (SetBuilder);
6597
6598                         TypeManager.RegisterProperty (PropertyBuilder, this);
6599                         return true;
6600                 }
6601         }
6602
6603         /// </summary>
6604         ///  Gigantic workaround  for lameness in SRE follows :
6605         ///  This class derives from EventInfo and attempts to basically
6606         ///  wrap around the EventBuilder so that FindMembers can quickly
6607         ///  return this in it search for members
6608         /// </summary>
6609         public class MyEventBuilder : EventInfo {
6610                 
6611                 //
6612                 // We use this to "point" to our Builder which is
6613                 // not really a MemberInfo
6614                 //
6615                 EventBuilder MyBuilder;
6616                 
6617                 //
6618                 // We "catch" and wrap these methods
6619                 //
6620                 MethodInfo raise, remove, add;
6621
6622                 EventAttributes attributes;
6623                 Type declaring_type, reflected_type, event_type;
6624                 string name;
6625
6626                 Event my_event;
6627
6628                 public MyEventBuilder (Event ev, TypeBuilder type_builder, string name, EventAttributes event_attr, Type event_type)
6629                 {
6630                         MyBuilder = type_builder.DefineEvent (name, event_attr, event_type);
6631
6632                         // And now store the values in our own fields.
6633                         
6634                         declaring_type = type_builder;
6635
6636                         reflected_type = type_builder;
6637                         
6638                         attributes = event_attr;
6639                         this.name = name;
6640                         my_event = ev;
6641                         this.event_type = event_type;
6642                 }
6643                 
6644                 //
6645                 // Methods that you have to override.  Note that you only need 
6646                 // to "implement" the variants that take the argument (those are
6647                 // the "abstract" methods, the others (GetAddMethod()) are 
6648                 // regular.
6649                 //
6650                 public override MethodInfo GetAddMethod (bool nonPublic)
6651                 {
6652                         return add;
6653                 }
6654                 
6655                 public override MethodInfo GetRemoveMethod (bool nonPublic)
6656                 {
6657                         return remove;
6658                 }
6659                 
6660                 public override MethodInfo GetRaiseMethod (bool nonPublic)
6661                 {
6662                         return raise;
6663                 }
6664                 
6665                 //
6666                 // These methods make "MyEventInfo" look like a Builder
6667                 //
6668                 public void SetRaiseMethod (MethodBuilder raiseMethod)
6669                 {
6670                         raise = raiseMethod;
6671                         MyBuilder.SetRaiseMethod (raiseMethod);
6672                 }
6673
6674                 public void SetRemoveOnMethod (MethodBuilder removeMethod)
6675                 {
6676                         remove = removeMethod;
6677                         MyBuilder.SetRemoveOnMethod (removeMethod);
6678                 }
6679
6680                 public void SetAddOnMethod (MethodBuilder addMethod)
6681                 {
6682                         add = addMethod;
6683                         MyBuilder.SetAddOnMethod (addMethod);
6684                 }
6685
6686                 public void SetCustomAttribute (CustomAttributeBuilder cb)
6687                 {
6688                         MyBuilder.SetCustomAttribute (cb);
6689                 }
6690                 
6691                 public override object [] GetCustomAttributes (bool inherit)
6692                 {
6693                         // FIXME : There's nothing which can be seemingly done here because
6694                         // we have no way of getting at the custom attribute objects of the
6695                         // EventBuilder !
6696                         return null;
6697                 }
6698
6699                 public override object [] GetCustomAttributes (Type t, bool inherit)
6700                 {
6701                         // FIXME : Same here !
6702                         return null;
6703                 }
6704
6705                 public override bool IsDefined (Type t, bool b)
6706                 {
6707                         return true;
6708                 }
6709
6710                 public override EventAttributes Attributes {
6711                         get {
6712                                 return attributes;
6713                         }
6714                 }
6715
6716                 public override string Name {
6717                         get {
6718                                 return name;
6719                         }
6720                 }
6721
6722                 public override Type DeclaringType {
6723                         get {
6724                                 return declaring_type;
6725                         }
6726                 }
6727
6728                 public override Type ReflectedType {
6729                         get {
6730                                 return reflected_type;
6731                         }
6732                 }
6733
6734                 public Type EventType {
6735                         get {
6736                                 return event_type;
6737                         }
6738                 }
6739                 
6740                 public void SetUsed ()
6741                 {
6742                         if (my_event != null) {
6743                                 my_event.SetAssigned ();
6744                                 my_event.SetMemberIsUsed ();
6745                         }
6746                 }
6747         }
6748         
6749         /// <summary>
6750         /// For case when event is declared like property (with add and remove accessors).
6751         /// </summary>
6752         public class EventProperty: Event {
6753
6754                 static string[] attribute_targets = new string [] { "event" }; // "property" target was disabled for 2.0 version
6755
6756                 public EventProperty (DeclSpace parent, Expression type, int mod_flags,
6757                                       bool is_iface, MemberName name,
6758                                       Attributes attrs, Accessor add, Accessor remove)
6759                         : base (parent, type, mod_flags, is_iface, name, attrs)
6760                 {
6761                         Add = new AddDelegateMethod (this, add);
6762                         Remove = new RemoveDelegateMethod (this, remove);
6763
6764                         // For this event syntax we don't report error CS0067
6765                         // because it is hard to do it.
6766                         SetAssigned ();
6767                 }
6768
6769                 public override string[] ValidAttributeTargets {
6770                         get {
6771                                 return attribute_targets;
6772                         }
6773                 }
6774         }
6775
6776         /// <summary>
6777         /// Event is declared like field.
6778         /// </summary>
6779         public class EventField : Event {
6780
6781                 static string[] attribute_targets = new string [] { "event", "field", "method" };
6782                 static string[] attribute_targets_interface = new string[] { "event", "method" };
6783
6784                 public EventField (DeclSpace parent, Expression type, int mod_flags,
6785                                    bool is_iface, MemberName name,
6786                                    Attributes attrs)
6787                         : base (parent, type, mod_flags, is_iface, name, attrs)
6788                 {
6789                         Add = new AddDelegateMethod (this);
6790                         Remove = new RemoveDelegateMethod (this);
6791                 }
6792
6793                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
6794                 {
6795                         if (a.Target == AttributeTargets.Field) {
6796                                 FieldBuilder.SetCustomAttribute (cb);
6797                                 return;
6798                         }
6799
6800                         if (a.Target == AttributeTargets.Method) {
6801                                 Add.ApplyAttributeBuilder (a, cb);
6802                                 Remove.ApplyAttributeBuilder (a, cb);
6803                                 return;
6804                         }
6805
6806                         base.ApplyAttributeBuilder (a, cb);
6807                 }
6808
6809                 public override bool Define()
6810                 {
6811                         if (!base.Define ())
6812                                 return false;
6813
6814                         if (initializer != null) {
6815                                 if (((ModFlags & Modifiers.ABSTRACT) != 0)) {
6816                                         Report.Error (74, Location, "`{0}': abstract event cannot have an initializer",
6817                                                 GetSignatureForError ());
6818                                         return false;
6819                                 }
6820                         }
6821
6822                         return true;
6823                 }
6824
6825                 public override string[] ValidAttributeTargets {
6826                         get {
6827                                 return IsInterface ? attribute_targets_interface : attribute_targets;
6828                         }
6829                 }
6830         }
6831
6832         public abstract class Event : FieldBase {
6833
6834                 protected sealed class AddDelegateMethod: DelegateMethod
6835                 {
6836
6837                         public AddDelegateMethod (Event method):
6838                                 base (method, "add_")
6839                         {
6840                         }
6841
6842                         public AddDelegateMethod (Event method, Accessor accessor):
6843                                 base (method, accessor, "add_")
6844                         {
6845                         }
6846
6847                         protected override MethodInfo DelegateMethodInfo {
6848                                 get {
6849                                         return TypeManager.delegate_combine_delegate_delegate;
6850                                 }
6851                         }
6852
6853                 }
6854
6855                 protected sealed class RemoveDelegateMethod: DelegateMethod
6856                 {
6857                         public RemoveDelegateMethod (Event method):
6858                                 base (method, "remove_")
6859                         {
6860                         }
6861
6862                         public RemoveDelegateMethod (Event method, Accessor accessor):
6863                                 base (method, accessor, "remove_")
6864                         {
6865                         }
6866
6867                         protected override MethodInfo DelegateMethodInfo {
6868                                 get {
6869                                         return TypeManager.delegate_remove_delegate_delegate;
6870                                 }
6871                         }
6872
6873                 }
6874
6875                 public abstract class DelegateMethod : AbstractPropertyEventMethod
6876                 {
6877                         protected readonly Event method;
6878                         ImplicitParameter param_attr;
6879
6880                         static string[] attribute_targets = new string [] { "method", "param", "return" };
6881
6882                         public DelegateMethod (Event method, string prefix)
6883                                 : base (method, prefix)
6884                         {
6885                                 this.method = method;
6886                         }
6887
6888                         public DelegateMethod (Event method, Accessor accessor, string prefix)
6889                                 : base (method, accessor, prefix)
6890                         {
6891                                 this.method = method;
6892                         }
6893
6894                         protected override void ApplyToExtraTarget(Attribute a, CustomAttributeBuilder cb)
6895                         {
6896                                 if (a.Target == AttributeTargets.Parameter) {
6897                                         if (param_attr == null)
6898                                                 param_attr = new ImplicitParameter (method_data.MethodBuilder);
6899
6900                                         param_attr.ApplyAttributeBuilder (a, cb);
6901                                         return;
6902                                 }
6903
6904                                 base.ApplyAttributeBuilder (a, cb);
6905                         }
6906
6907                         public override AttributeTargets AttributeTargets {
6908                                 get {
6909                                         return AttributeTargets.Method;
6910                                 }
6911                         }
6912
6913                         public override bool IsClsComplianceRequired ()
6914                         {
6915                                 return method.IsClsComplianceRequired ();
6916                         }
6917
6918                         public MethodBuilder Define (DeclSpace parent)
6919                         {
6920                                 method_data = new MethodData (method, method.ModFlags,
6921                                         method.flags | MethodAttributes.HideBySig | MethodAttributes.SpecialName, this);
6922
6923                                 if (!method_data.Define (parent))
6924                                         return null;
6925
6926                                 MethodBuilder mb = method_data.MethodBuilder;
6927                                 ParameterInfo.ApplyAttributes (mb);
6928                                 return mb;
6929                         }
6930
6931
6932                         protected override void EmitMethod (DeclSpace parent)
6933                         {
6934                                 if (block != null) {
6935                                         base.EmitMethod (parent);
6936                                         return;
6937                                 }
6938
6939                                 if ((method.ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
6940                                         return;
6941
6942                                 ILGenerator ig = method_data.MethodBuilder.GetILGenerator ();
6943                                 FieldInfo field_info = (FieldInfo)method.FieldBuilder;
6944
6945                                 method_data.MethodBuilder.SetImplementationFlags (MethodImplAttributes.Synchronized);
6946                                 if ((method.ModFlags & Modifiers.STATIC) != 0) {
6947                                         ig.Emit (OpCodes.Ldsfld, field_info);
6948                                         ig.Emit (OpCodes.Ldarg_0);
6949                                         ig.Emit (OpCodes.Call, DelegateMethodInfo);
6950                                         ig.Emit (OpCodes.Castclass, method.MemberType);
6951                                         ig.Emit (OpCodes.Stsfld, field_info);
6952                                 } else {
6953                                         ig.Emit (OpCodes.Ldarg_0);
6954                                         ig.Emit (OpCodes.Ldarg_0);
6955                                         ig.Emit (OpCodes.Ldfld, field_info);
6956                                         ig.Emit (OpCodes.Ldarg_1);
6957                                         ig.Emit (OpCodes.Call, DelegateMethodInfo);
6958                                         ig.Emit (OpCodes.Castclass, method.MemberType);
6959                                         ig.Emit (OpCodes.Stfld, field_info);
6960                                 }
6961                                 ig.Emit (OpCodes.Ret);
6962                         }
6963
6964                         protected abstract MethodInfo DelegateMethodInfo { get; }
6965
6966                         public override Type ReturnType {
6967                                 get {
6968                                         return TypeManager.void_type;
6969                                 }
6970                         }
6971
6972                         public override EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig)
6973                         {
6974                                 return new EmitContext (
6975                                         ds, method.Parent, Location, ig, ReturnType,
6976                                         method.ModFlags, false);
6977                         }
6978
6979                         public override ObsoleteAttribute GetObsoleteAttribute ()
6980                         {
6981                                 return method.GetObsoleteAttribute ();
6982                         }
6983
6984                         public override string[] ValidAttributeTargets {
6985                                 get {
6986                                         return attribute_targets;
6987                                 }
6988                         }
6989
6990                         public override Parameters ParameterInfo {
6991                                 get {
6992                                         return method.parameters;
6993                                 }
6994                         }
6995
6996                 }
6997
6998
6999                 const int AllowedModifiers =
7000                         Modifiers.NEW |
7001                         Modifiers.PUBLIC |
7002                         Modifiers.PROTECTED |
7003                         Modifiers.INTERNAL |
7004                         Modifiers.PRIVATE |
7005                         Modifiers.STATIC |
7006                         Modifiers.VIRTUAL |
7007                         Modifiers.SEALED |
7008                         Modifiers.OVERRIDE |
7009                         Modifiers.UNSAFE |
7010                         Modifiers.ABSTRACT;
7011
7012                 const int AllowedInterfaceModifiers =
7013                         Modifiers.NEW;
7014
7015                 public DelegateMethod Add, Remove;
7016                 public MyEventBuilder     EventBuilder;
7017                 public MethodBuilder AddBuilder, RemoveBuilder;
7018                 Parameters parameters;
7019
7020                 protected Event (DeclSpace parent, Expression type, int mod_flags,
7021                               bool is_iface, MemberName name, Attributes attrs)
7022                         : base (parent, type, mod_flags,
7023                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
7024                                 name, attrs)
7025                 {
7026                         IsInterface = is_iface;
7027                 }
7028
7029                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
7030                 {
7031                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
7032                                 a.Error_InvalidSecurityParent ();
7033                                 return;
7034                         }
7035                         
7036                         EventBuilder.SetCustomAttribute (cb);
7037                 }
7038
7039                 public bool AreAccessorsDuplicateImplementation (MethodCore mc)
7040                 {
7041                         return Add.IsDuplicateImplementation (mc) || Remove.IsDuplicateImplementation (mc);
7042                 }
7043
7044                 public override AttributeTargets AttributeTargets {
7045                         get {
7046                                 return AttributeTargets.Event;
7047                         }
7048                 }
7049   
7050                 public override bool Define ()
7051                 {
7052                         EventAttributes e_attr;
7053                         e_attr = EventAttributes.None;
7054
7055                         if (!DoDefineBase ())
7056                                 return false;
7057
7058                         if (!DoDefine ())
7059                                 return false;
7060
7061                         if (!TypeManager.IsDelegateType (MemberType)) {
7062                                 Report.Error (66, Location, "`{0}': event must be of a delegate type", GetSignatureForError ());
7063                                 return false;
7064                         }
7065
7066                         parameters = new Parameters (
7067                                 new Parameter[] { new Parameter (MemberType, "value", Parameter.Modifier.NONE, null, Location) },
7068                                 new Type[] { MemberType } );
7069
7070                         if (!CheckBase ())
7071                                 return false;
7072
7073                         //
7074                         // Now define the accessors
7075                         //
7076
7077                         AddBuilder = Add.Define (Parent);
7078                         if (AddBuilder == null)
7079                                 return false;
7080
7081                         RemoveBuilder = Remove.Define (Parent);
7082                         if (RemoveBuilder == null)
7083                                 return false;
7084
7085                         EventBuilder = new MyEventBuilder (this, Parent.TypeBuilder, Name, e_attr, MemberType);
7086                         
7087                         if (Add.Block == null && Remove.Block == null && !IsInterface) {
7088                                 FieldBuilder = Parent.TypeBuilder.DefineField (
7089                                         Name, MemberType,
7090                                         FieldAttributes.Private | ((ModFlags & Modifiers.STATIC) != 0 ? FieldAttributes.Static : 0));
7091                                 TypeManager.RegisterPrivateFieldOfEvent (
7092                                         (EventInfo) EventBuilder, FieldBuilder);
7093                                 TypeManager.RegisterFieldBase (FieldBuilder, this);
7094                         }
7095                         
7096                         EventBuilder.SetAddOnMethod (AddBuilder);
7097                         EventBuilder.SetRemoveOnMethod (RemoveBuilder);
7098
7099                         TypeManager.RegisterEvent (EventBuilder, AddBuilder, RemoveBuilder);
7100                         return true;
7101                 }
7102
7103                 protected override bool CheckBase ()
7104                 {
7105                         if (!base.CheckBase ())
7106                                 return false;
7107  
7108                         if (conflict_symbol != null && (ModFlags & Modifiers.NEW) == 0) {
7109                                 if (!(conflict_symbol is EventInfo)) {
7110                                         Report.SymbolRelatedToPreviousError (conflict_symbol);
7111                                         Report.Error (72, Location, "Event `{0}' can override only event", GetSignatureForError ());
7112                                         return false;
7113                                 }
7114                         }
7115  
7116                         return true;
7117                 }
7118
7119                 public override void Emit ()
7120                 {
7121                         if (OptAttributes != null) {
7122                                 OptAttributes.Emit ();
7123                         }
7124
7125                         Add.Emit (Parent);
7126                         Remove.Emit (Parent);
7127
7128                         base.Emit ();
7129                 }
7130
7131                 public override string GetSignatureForError ()
7132                 {
7133                         return base.GetSignatureForError ();
7134                 }
7135
7136                 //
7137                 //   Represents header string for documentation comment.
7138                 //
7139                 public override string DocCommentHeader {
7140                         get { return "E:"; }
7141                 }
7142         }
7143
7144  
7145         public class Indexer : PropertyBase, IIteratorContainer {
7146
7147                 class GetIndexerMethod : GetMethod
7148                 {
7149                         public GetIndexerMethod (MethodCore method):
7150                                 base (method)
7151                         {
7152                         }
7153
7154                         public GetIndexerMethod (MethodCore method, Accessor accessor):
7155                                 base (method, accessor)
7156                         {
7157                         }
7158
7159                         public override Parameters ParameterInfo {
7160                                 get {
7161                                         return method.ParameterInfo;
7162                                 }
7163                         }
7164                 }
7165
7166                 class SetIndexerMethod: SetMethod
7167                 {
7168                         public SetIndexerMethod (MethodCore method):
7169                                 base (method)
7170                         {
7171                         }
7172
7173                         public SetIndexerMethod (MethodCore method, Accessor accessor):
7174                                 base (method, accessor)
7175                         {
7176                         }
7177
7178                         protected override void DefineParameters ()
7179                         {
7180                                 parameters = Parameters.MergeGenerated (method.Parameters,
7181                                         new Parameter (method.MemberType, "value", Parameter.Modifier.NONE, null, method.Location));
7182                         }
7183                 }
7184
7185                 const int AllowedModifiers =
7186                         Modifiers.NEW |
7187                         Modifiers.PUBLIC |
7188                         Modifiers.PROTECTED |
7189                         Modifiers.INTERNAL |
7190                         Modifiers.PRIVATE |
7191                         Modifiers.VIRTUAL |
7192                         Modifiers.SEALED |
7193                         Modifiers.OVERRIDE |
7194                         Modifiers.UNSAFE |
7195                         Modifiers.EXTERN |
7196                         Modifiers.ABSTRACT;
7197
7198                 const int AllowedInterfaceModifiers =
7199                         Modifiers.NEW;
7200
7201                 //
7202                 // Are we implementing an interface ?
7203                 //
7204                 public Indexer (DeclSpace parent, Expression type, MemberName name, int mod,
7205                                 bool is_iface, Parameters parameters, Attributes attrs,
7206                                 Accessor get_block, Accessor set_block)
7207                         : base (parent, type, mod,
7208                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
7209                                 is_iface, name, parameters, attrs)
7210                 {
7211                         if (get_block == null)
7212                                 Get = new GetIndexerMethod (this);
7213                         else
7214                                 Get = new GetIndexerMethod (this, get_block);
7215
7216                         if (set_block == null)
7217                                 Set = new SetIndexerMethod (this);
7218                         else
7219                                 Set = new SetIndexerMethod (this, set_block);
7220                 }
7221                        
7222                 public override bool Define ()
7223                 {
7224                         if (!DoDefineBase ())
7225                                 return false;
7226
7227                         if (!base.Define ())
7228                                 return false;
7229
7230                         if (MemberType == TypeManager.void_type) {
7231                                 Report.Error (620, Location, "Indexers cannot have void type");
7232                                 return false;
7233                         }
7234
7235                         if (OptAttributes != null) {
7236                                 Attribute indexer_attr = OptAttributes.Search (TypeManager.indexer_name_type);
7237                                 if (indexer_attr != null) {
7238                                         // Remove the attribute from the list because it is not emitted
7239                                         OptAttributes.Attrs.Remove (indexer_attr);
7240
7241                                         string name = indexer_attr.GetIndexerAttributeValue ();
7242                                         if (name == null)
7243                                                 return false;
7244
7245                                         ShortName = name;
7246
7247                                         if (IsExplicitImpl) {
7248                                                 Report.Error (415, indexer_attr.Location,
7249                                                               "The `IndexerName' attribute is valid only on an " +
7250                                                               "indexer that is not an explicit interface member declaration");
7251                                                 return false;
7252                                         }
7253
7254                                         if ((ModFlags & Modifiers.OVERRIDE) != 0) {
7255                                                 Report.Error (609, indexer_attr.Location,
7256                                                               "Cannot set the `IndexerName' attribute on an indexer marked override");
7257                                                 return false;
7258                                         }
7259                                 }
7260                         }
7261
7262                         if (InterfaceType != null) {
7263                                 string base_IndexerName = TypeManager.IndexerPropertyName (InterfaceType);
7264                                 if (base_IndexerName != Name)
7265                                         ShortName = base_IndexerName;
7266                         }
7267
7268                         if (!ParentContainer.AddToMemberContainer (this) ||
7269                                 !ParentContainer.AddToMemberContainer (Get) || !ParentContainer.AddToMemberContainer (Set))
7270                                 return false;
7271
7272                         if (!CheckBase ())
7273                                 return false;
7274
7275                         flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
7276                         if (!Get.IsDummy){
7277                                 GetBuilder = Get.Define (Parent);
7278                                 if (GetBuilder == null)
7279                                         return false;
7280
7281                                 //
7282                                 // Setup iterator if we are one
7283                                 //
7284                                 if ((ModFlags & Modifiers.METHOD_YIELDS) != 0){
7285                                         Iterator iterator = new Iterator (
7286                                                 Get, Parent, null, ModFlags);
7287
7288                                         if (!iterator.DefineIterator ())
7289                                                 return false;
7290                                 }
7291                         }
7292                         
7293                         SetBuilder = Set.Define (Parent);
7294                         if (!Set.IsDummy){
7295                                 if (SetBuilder == null)
7296                                         return false;
7297                         }
7298
7299                         //
7300                         // Now name the parameters
7301                         //
7302                         Parameter [] p = Parameters.FixedParameters;
7303                         if (p != null) {
7304                                 // TODO: should be done in parser and it needs to do cycle
7305                                 if ((p [0].ModFlags & Parameter.Modifier.ISBYREF) != 0) {
7306                                         Report.Error (631, Location, "ref and out are not valid in this context");
7307                                         return false;
7308                                 }
7309                         }
7310
7311                         PropertyBuilder = Parent.TypeBuilder.DefineProperty (
7312                                 Name, PropertyAttributes.None, MemberType, ParameterTypes);
7313                         
7314                         if (!Get.IsDummy)
7315                                 PropertyBuilder.SetGetMethod (GetBuilder);
7316
7317                         if (!Set.IsDummy)
7318                                 PropertyBuilder.SetSetMethod (SetBuilder);
7319                                 
7320                         TypeManager.RegisterIndexer (PropertyBuilder, GetBuilder, SetBuilder, ParameterTypes);
7321
7322                         return true;
7323                 }
7324
7325                 public override string GetSignatureForError ()
7326                 {
7327                         StringBuilder sb = new StringBuilder (Parent.GetSignatureForError ());
7328                         if (MemberName.Left != null) {
7329                                 sb.Append ('.');
7330                                 sb.Append (MemberName.Left);
7331                         }
7332
7333                         sb.Append (".this");
7334                         sb.Append (Parameters.GetSignatureForError ().Replace ('(', '[').Replace (')', ']'));
7335                         return sb.ToString ();
7336                 }
7337
7338                 public override bool MarkForDuplicationCheck ()
7339                 {
7340                         caching_flags |= Flags.TestMethodDuplication;
7341                         return true;
7342                 }
7343         }
7344
7345         public class Operator : MethodOrOperator, IIteratorContainer {
7346
7347                 const int AllowedModifiers =
7348                         Modifiers.PUBLIC |
7349                         Modifiers.UNSAFE |
7350                         Modifiers.EXTERN |
7351                         Modifiers.STATIC;
7352
7353                 public enum OpType : byte {
7354
7355                         // Unary operators
7356                         LogicalNot,
7357                         OnesComplement,
7358                         Increment,
7359                         Decrement,
7360                         True,
7361                         False,
7362
7363                         // Unary and Binary operators
7364                         Addition,
7365                         Subtraction,
7366
7367                         UnaryPlus,
7368                         UnaryNegation,
7369                         
7370                         // Binary operators
7371                         Multiply,
7372                         Division,
7373                         Modulus,
7374                         BitwiseAnd,
7375                         BitwiseOr,
7376                         ExclusiveOr,
7377                         LeftShift,
7378                         RightShift,
7379                         Equality,
7380                         Inequality,
7381                         GreaterThan,
7382                         LessThan,
7383                         GreaterThanOrEqual,
7384                         LessThanOrEqual,
7385
7386                         // Implicit and Explicit
7387                         Implicit,
7388                         Explicit,
7389
7390                         // Just because of enum
7391                         TOP
7392                 };
7393
7394                 public readonly OpType OperatorType;
7395                 
7396                 public Operator (DeclSpace parent, OpType type, Expression ret_type,
7397                                  int mod_flags, Parameters parameters,
7398                                  ToplevelBlock block, Attributes attrs, Location loc)
7399                         : base (parent, null, ret_type, mod_flags, AllowedModifiers, false,
7400                                 new MemberName ("op_" + type, loc), attrs, parameters)
7401                 {
7402                         OperatorType = type;
7403                         Block = block;
7404                 }
7405
7406                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb) 
7407                 {
7408                         if (a.Type == TypeManager.conditional_attribute_type) {
7409                                 Error_ConditionalAttributeIsNotValid ();
7410                                 return;
7411                         }
7412
7413                         base.ApplyAttributeBuilder (a, cb);
7414                 }
7415                 
7416                 protected override bool CheckForDuplications ()
7417                 {
7418                         ArrayList ar = ParentContainer.Operators;
7419                         if (ar != null) {
7420                                 int arLen = ar.Count;
7421
7422                                 for (int i = 0; i < arLen; i++) {
7423                                         Operator o = (Operator) ar [i];
7424                                         if (IsDuplicateImplementation (o))
7425                                                 return false;
7426                                 }
7427                         }
7428
7429                         ar = ParentContainer.Methods;
7430                         if (ar != null) {
7431                                 int arLen = ar.Count;
7432
7433                                 for (int i = 0; i < arLen; i++) {
7434                                         Method m = (Method) ar [i];
7435                                         if (IsDuplicateImplementation (m))
7436                                                 return false;
7437                                 }
7438                         }
7439
7440                         return true;
7441                 }
7442
7443                 public override bool Define ()
7444                 {
7445                         const int RequiredModifiers = Modifiers.PUBLIC | Modifiers.STATIC;
7446                         if ((ModFlags & RequiredModifiers) != RequiredModifiers){
7447                                 Report.Error (558, Location, "User-defined operator `{0}' must be declared static and public", GetSignatureForError ());
7448                                 return false;
7449                         }
7450
7451                         if (!base.Define ())
7452                                 return false;
7453
7454                         if (MemberType == TypeManager.void_type) {
7455                                 Report.Error (590, Location, "User-defined operators cannot return void");
7456                                 return false;
7457                         }
7458
7459                         Type declaring_type = MethodData.DeclaringType;
7460                         Type return_type = MemberType;
7461                         Type first_arg_type = ParameterTypes [0];
7462
7463                         // Rules for conversion operators
7464                         
7465                         if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
7466                                 if (first_arg_type == return_type && first_arg_type == declaring_type){
7467                                         Report.Error (555, Location,
7468                                                 "User-defined operator cannot take an object of the enclosing type and convert to an object of the enclosing type");
7469                                         return false;
7470                                 }
7471                                 
7472                                 if (first_arg_type != declaring_type && return_type != declaring_type){
7473                                         Report.Error (
7474                                                 556, Location, 
7475                                                 "User-defined conversion must convert to or from the " +
7476                                                 "enclosing type");
7477                                         return false;
7478                                 }
7479
7480                                 if (first_arg_type.IsInterface || return_type.IsInterface){
7481                                         Report.Error (552, Location, "User-defined conversion `{0}' cannot convert to or from an interface type",
7482                                                 GetSignatureForError ());
7483                                         return false;
7484                                 }
7485                                 
7486                                 if (first_arg_type.IsSubclassOf (return_type) || return_type.IsSubclassOf (first_arg_type)) {
7487                                         if (declaring_type.IsSubclassOf (return_type) || declaring_type.IsSubclassOf (first_arg_type)) {
7488                                                 Report.Error (553, Location, "User-defined conversion `{0}' cannot convert to or from base class",
7489                                                         GetSignatureForError ());
7490                                                 return false;
7491                                         }
7492                                         Report.Error (554, Location, "User-defined conversion `{0}' cannot convert to or from derived class",
7493                                                 GetSignatureForError ());
7494                                         return false;
7495                                 }
7496                         } else if (OperatorType == OpType.LeftShift || OperatorType == OpType.RightShift) {
7497                                 if (first_arg_type != declaring_type || ParameterTypes [1] != TypeManager.int32_type) {
7498                                         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");
7499                                         return false;
7500                                 }
7501                         } else if (Parameters.Count == 1) {
7502                                 // Checks for Unary operators
7503
7504                                 if (OperatorType == OpType.Increment || OperatorType == OpType.Decrement) {
7505                                         if (return_type != declaring_type && !TypeManager.IsSubclassOf (return_type, declaring_type)) {
7506                                                 Report.Error (448, Location,
7507                                                         "The return type for ++ or -- operator must be the containing type or derived from the containing type");
7508                                                 return false;
7509                                         }
7510                                         if (first_arg_type != declaring_type) {
7511                                                 Report.Error (
7512                                                         559, Location, "The parameter type for ++ or -- operator must be the containing type");
7513                                                 return false;
7514                                         }
7515                                 }
7516                                 
7517                                 if (first_arg_type != declaring_type){
7518                                         Report.Error (
7519                                                 562, Location,
7520                                                 "The parameter of a unary operator must be the " +
7521                                                 "containing type");
7522                                         return false;
7523                                 }
7524                                 
7525                                 if (OperatorType == OpType.True || OperatorType == OpType.False) {
7526                                         if (return_type != TypeManager.bool_type){
7527                                                 Report.Error (
7528                                                         215, Location,
7529                                                         "The return type of operator True or False " +
7530                                                         "must be bool");
7531                                                 return false;
7532                                         }
7533                                 }
7534                                 
7535                         } else {
7536                                 // Checks for Binary operators
7537                                 
7538                                 if (first_arg_type != declaring_type &&
7539                                     ParameterTypes [1] != declaring_type){
7540                                         Report.Error (
7541                                                 563, Location,
7542                                                 "One of the parameters of a binary operator must " +
7543                                                 "be the containing type");
7544                                         return false;
7545                                 }
7546                         }
7547
7548                         return true;
7549                 }
7550
7551                 protected override bool DoDefine ()
7552                 {
7553                         if (!base.DoDefine ())
7554                                 return false;
7555
7556                         flags |= MethodAttributes.SpecialName | MethodAttributes.HideBySig;
7557                         return true;
7558                 }
7559                 
7560                 public override void Emit ()
7561                 {
7562                         base.Emit ();
7563
7564                         Parameters.ApplyAttributes (MethodBuilder);
7565
7566                         //
7567                         // abstract or extern methods have no bodies
7568                         //
7569                         if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
7570                                 return;
7571                         
7572                         EmitContext ec;
7573                         if ((flags & MethodAttributes.PinvokeImpl) == 0)
7574                                 ec = CreateEmitContext (Parent, MethodBuilder.GetILGenerator ());
7575                         else
7576                                 ec = CreateEmitContext (Parent, null);
7577                         
7578                         SourceMethod source = SourceMethod.Create (Parent, MethodBuilder, Block);
7579                         ec.EmitTopBlock (this, Block);
7580
7581                         if (source != null)
7582                                 source.CloseMethod ();
7583
7584                         Block = null;
7585                 }
7586
7587                 // Operator cannot be override
7588                 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
7589                 {
7590                         return null;
7591                 }
7592
7593                 public static string GetName (OpType ot)
7594                 {
7595                         switch (ot){
7596                         case OpType.LogicalNot:
7597                                 return "!";
7598                         case OpType.OnesComplement:
7599                                 return "~";
7600                         case OpType.Increment:
7601                                 return "++";
7602                         case OpType.Decrement:
7603                                 return "--";
7604                         case OpType.True:
7605                                 return "true";
7606                         case OpType.False:
7607                                 return "false";
7608                         case OpType.Addition:
7609                                 return "+";
7610                         case OpType.Subtraction:
7611                                 return "-";
7612                         case OpType.UnaryPlus:
7613                                 return "+";
7614                         case OpType.UnaryNegation:
7615                                 return "-";
7616                         case OpType.Multiply:
7617                                 return "*";
7618                         case OpType.Division:
7619                                 return "/";
7620                         case OpType.Modulus:
7621                                 return "%";
7622                         case OpType.BitwiseAnd:
7623                                 return "&";
7624                         case OpType.BitwiseOr:
7625                                 return "|";
7626                         case OpType.ExclusiveOr:
7627                                 return "^";
7628                         case OpType.LeftShift:
7629                                 return "<<";
7630                         case OpType.RightShift:
7631                                 return ">>";
7632                         case OpType.Equality:
7633                                 return "==";
7634                         case OpType.Inequality:
7635                                 return "!=";
7636                         case OpType.GreaterThan:
7637                                 return ">";
7638                         case OpType.LessThan:
7639                                 return "<";
7640                         case OpType.GreaterThanOrEqual:
7641                                 return ">=";
7642                         case OpType.LessThanOrEqual:
7643                                 return "<=";
7644                         case OpType.Implicit:
7645                                 return "implicit";
7646                         case OpType.Explicit:
7647                                 return "explicit";
7648                         default: return "";
7649                         }
7650                 }
7651
7652                 public static OpType GetOperatorType (string name)
7653                 {
7654                         if (name.StartsWith ("op_")){
7655                                 for (int i = 0; i < Unary.oper_names.Length; ++i) {
7656                                         if (Unary.oper_names [i] == name)
7657                                                 return (OpType)i;
7658                                 }
7659
7660                                 for (int i = 0; i < Binary.oper_names.Length; ++i) {
7661                                         if (Binary.oper_names [i] == name)
7662                                                 return (OpType)i;
7663                                 }
7664                         }
7665                         return OpType.TOP;
7666                 }
7667
7668                 public override string GetSignatureForError ()
7669                 {
7670                         StringBuilder sb = new StringBuilder ();
7671                         if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
7672                                 sb.AppendFormat ("{0}.{1} operator {2}", Parent.GetSignatureForError (), GetName (OperatorType), Type.Type == null ? Type.ToString () : TypeManager.CSharpName (Type.Type));
7673                         }
7674                         else {
7675                                 sb.AppendFormat ("{0}.operator {1}", Parent.GetSignatureForError (), GetName (OperatorType));
7676                         }
7677
7678                         sb.Append (Parameters.GetSignatureForError ());
7679                         return sb.ToString ();
7680                 }
7681         }
7682
7683         //
7684         // This is used to compare method signatures
7685         //
7686         struct MethodSignature {
7687                 public string Name;
7688                 public Type RetType;
7689                 public Type [] Parameters;
7690                 
7691                 /// <summary>
7692                 ///    This delegate is used to extract methods which have the
7693                 ///    same signature as the argument
7694                 /// </summary>
7695                 public static MemberFilter method_signature_filter = new MemberFilter (MemberSignatureCompare);
7696                 
7697                 public MethodSignature (string name, Type ret_type, Type [] parameters)
7698                 {
7699                         Name = name;
7700                         RetType = ret_type;
7701
7702                         if (parameters == null)
7703                                 Parameters = Type.EmptyTypes;
7704                         else
7705                                 Parameters = parameters;
7706                 }
7707
7708                 public override string ToString ()
7709                 {
7710                         string pars = "";
7711                         if (Parameters.Length != 0){
7712                                 System.Text.StringBuilder sb = new System.Text.StringBuilder ();
7713                                 for (int i = 0; i < Parameters.Length; i++){
7714                                         sb.Append (Parameters [i]);
7715                                         if (i+1 < Parameters.Length)
7716                                                 sb.Append (", ");
7717                                 }
7718                                 pars = sb.ToString ();
7719                         }
7720
7721                         return String.Format ("{0} {1} ({2})", RetType, Name, pars);
7722                 }
7723                 
7724                 public override int GetHashCode ()
7725                 {
7726                         return Name.GetHashCode ();
7727                 }
7728
7729                 public override bool Equals (Object o)
7730                 {
7731                         MethodSignature other = (MethodSignature) o;
7732
7733                         if (other.Name != Name)
7734                                 return false;
7735
7736                         if (other.RetType != RetType)
7737                                 return false;
7738                         
7739                         if (Parameters == null){
7740                                 if (other.Parameters == null)
7741                                         return true;
7742                                 return false;
7743                         }
7744
7745                         if (other.Parameters == null)
7746                                 return false;
7747                         
7748                         int c = Parameters.Length;
7749                         if (other.Parameters.Length != c)
7750                                 return false;
7751
7752                         for (int i = 0; i < c; i++)
7753                                 if (other.Parameters [i] != Parameters [i])
7754                                         return false;
7755
7756                         return true;
7757                 }
7758
7759                 static bool MemberSignatureCompare (MemberInfo m, object filter_criteria)
7760                 {
7761                         MethodSignature sig = (MethodSignature) filter_criteria;
7762
7763                         if (m.Name != sig.Name)
7764                                 return false;
7765
7766                         Type ReturnType;
7767                         MethodInfo mi = m as MethodInfo;
7768                         PropertyInfo pi = m as PropertyInfo;
7769
7770                         if (mi != null)
7771                                 ReturnType = mi.ReturnType;
7772                         else if (pi != null)
7773                                 ReturnType = pi.PropertyType;
7774                         else
7775                                 return false;
7776                         
7777                         //
7778                         // we use sig.RetType == null to mean `do not check the
7779                         // method return value.  
7780                         //
7781                         if (sig.RetType != null)
7782                                 if (ReturnType != sig.RetType)
7783                                         return false;
7784
7785                         Type [] args;
7786                         if (mi != null)
7787                                 args = TypeManager.GetParameterData (mi).Types;
7788                         else
7789                                 args = TypeManager.GetArgumentTypes (pi);
7790                         Type [] sigp = sig.Parameters;
7791
7792                         if (args.Length != sigp.Length)
7793                                 return false;
7794
7795                         for (int i = args.Length; i > 0; ){
7796                                 i--;
7797                                 if (args [i] != sigp [i])
7798                                         return false;
7799                         }
7800                         return true;
7801                 }
7802         }
7803 }