2006-04-28 Marek Safar <marek.safar@seznam.cz>
[mono.git] / mcs / gmcs / class.cs
1 //
2 // class.cs: Class and Struct handlers
3 //
4 // Authors: Miguel de Icaza (miguel@gnu.org)
5 //          Martin Baulig (martin@ximian.com)
6 //          Marek Safar (marek.safar@seznam.cz)
7 //
8 // Licensed under the terms of the GNU GPL
9 //
10 // (C) 2001, 2002, 2003 Ximian, Inc (http://www.ximian.com)
11 // (C) 2004 Novell, Inc
12 //
13 //
14 //  2002-10-11  Miguel de Icaza  <miguel@ximian.com>
15 //
16 //      * class.cs: Following the comment from 2002-09-26 to AddMethod, I
17 //      have fixed a remaining problem: not every AddXXXX was adding a
18 //      fully qualified name.  
19 //
20 //      Now everyone registers a fully qualified name in the DeclSpace as
21 //      being defined instead of the partial name.  
22 //
23 //      Downsides: we are slower than we need to be due to the excess
24 //      copies and the names being registered this way.  
25 //
26 //      The reason for this is that we currently depend (on the corlib
27 //      bootstrap for instance) that types are fully qualified, because
28 //      we dump all the types in the namespace, and we should really have
29 //      types inserted into the proper namespace, so we can only store the
30 //      basenames in the defined_names array.
31 //
32 //
33 #define CACHE
34 using System;
35 using System.Collections;
36 using System.Collections.Specialized;
37 using System.Reflection;
38 using System.Reflection.Emit;
39 using System.Runtime.CompilerServices;
40 using System.Runtime.InteropServices;
41 using System.Security;
42 using System.Security.Permissions;
43 using System.Text;
44 using System.Xml;
45
46 using Mono.CompilerServices.SymbolWriter;
47
48 namespace Mono.CSharp {
49
50         public enum Kind {
51                 Root,
52                 Struct,
53                 Class,
54                 Interface
55         }
56
57         /// <summary>
58         ///   This is the base class for structs and classes.  
59         /// </summary>
60         public abstract class TypeContainer : DeclSpace, IMemberContainer {
61
62                 public class MemberCoreArrayList: ArrayList
63                 {
64                         /// <summary>
65                         ///   Defines the MemberCore objects that are in this array
66                         /// </summary>
67                         public virtual void DefineContainerMembers ()
68                         {
69                                 foreach (MemberCore mc in this) {
70                                         try {
71                                                 mc.Define ();
72                                         }
73                                         catch (Exception e) {
74                                                 throw new InternalErrorException (mc.Location, mc.GetSignatureForError (), e);
75                                         }
76                                 }
77                         }
78
79                         public virtual void Emit ()
80                         {
81                                 foreach (MemberCore mc in this)
82                                         mc.Emit ();
83                         }
84                 }
85
86                 public class MethodArrayList : MemberCoreArrayList
87                 {
88                         [Flags]
89                         enum CachedMethods {
90                                 Equals                  = 1,
91                                 GetHashCode             = 1 << 1
92                         }
93  
94                         CachedMethods cached_method;
95                         TypeContainer container;
96
97                         public MethodArrayList (TypeContainer container)
98                         {
99                                 this.container = container;
100                         }
101  
102                         /// <summary>
103                         /// Method container contains Equals method
104                         /// </summary>
105                         public bool HasEquals {
106                                 set {
107                                         cached_method |= CachedMethods.Equals;
108                                 }
109  
110                                 get {
111                                         return (cached_method & CachedMethods.Equals) != 0;
112                                 }
113                         }
114  
115                         /// <summary>
116                         /// Method container contains GetHashCode method
117                         /// </summary>
118                         public bool HasGetHashCode {
119                                 set {
120                                         cached_method |= CachedMethods.GetHashCode;
121                                 }
122  
123                                 get {
124                                         return (cached_method & CachedMethods.GetHashCode) != 0;
125                                 }
126                         }
127  
128                         public override void DefineContainerMembers ()
129                         {
130                                 base.DefineContainerMembers ();
131  
132                                 if (HasEquals && !HasGetHashCode) {
133                                         Report.Warning (659, 3, container.Location, "`{0}' overrides Object.Equals(object) but does not override Object.GetHashCode()", container.GetSignatureForError ());
134                                 }
135                         }
136  
137                 }
138
139                 public sealed class IndexerArrayList : MemberCoreArrayList
140                 {
141                         /// <summary>
142                         /// The indexer name for this container
143                         /// </summary>
144                         public string IndexerName = DefaultIndexerName;
145
146                         bool seen_normal_indexers = false;
147
148                         TypeContainer container;
149
150                         public IndexerArrayList (TypeContainer container)
151                         {
152                                 this.container = container;
153                         }
154
155                         /// <summary>
156                         /// Defines the indexers, and also verifies that the IndexerNameAttribute in the
157                         /// class is consistent.  Either it is `Item' or it is the name defined by all the
158                         /// indexers with the `IndexerName' attribute.
159                         ///
160                         /// Turns out that the IndexerNameAttribute is applied to each indexer,
161                         /// but it is never emitted, instead a DefaultMember attribute is attached
162                         /// to the class.
163                         /// </summary>
164                         public override void DefineContainerMembers()
165                         {
166                                 base.DefineContainerMembers ();
167
168                                 string class_indexer_name = null;
169
170                                 //
171                                 // If there's both an explicit and an implicit interface implementation, the
172                                 // explicit one actually implements the interface while the other one is just
173                                 // a normal indexer.  See bug #37714.
174                                 //
175
176                                 // Invariant maintained by AddIndexer(): All explicit interface indexers precede normal indexers
177                                 foreach (Indexer i in this) {
178                                         if (i.InterfaceType != null) {
179                                                 if (seen_normal_indexers)
180                                                         throw new Exception ("Internal Error: 'Indexers' array not sorted properly.");
181                                                 continue;
182                                         }
183
184                                         seen_normal_indexers = true;
185
186                                         if (class_indexer_name == null) {
187                                                 class_indexer_name = i.ShortName;
188                                                 continue;
189                                         }
190
191                                         if (i.ShortName != class_indexer_name)
192                                                 Report.Error (668, i.Location, "Two indexers have different names; the IndexerName attribute must be used with the same name on every indexer within a type");
193                                 }
194
195                                 if (class_indexer_name != null)
196                                         IndexerName = class_indexer_name;
197                         }
198
199                         public override void Emit ()
200                         {
201                                 base.Emit ();
202
203                                 if (!seen_normal_indexers)
204                                         return;
205
206                                 CustomAttributeBuilder cb = new CustomAttributeBuilder (TypeManager.default_member_ctor, new string [] { IndexerName });
207                                 container.TypeBuilder.SetCustomAttribute (cb);
208                         }
209                 }
210
211                 public class OperatorArrayList: MemberCoreArrayList
212                 {
213                         TypeContainer container;
214
215                         public OperatorArrayList (TypeContainer container)
216                         {
217                                 this.container = container;
218                         }
219
220                         //
221                         // Operator pair checking
222                         //
223                         class OperatorEntry
224                         {
225                                 public int flags;
226                                 public Type ret_type;
227                                 public Type type1, type2;
228                                 public Operator op;
229                                 public Operator.OpType ot;
230                                 
231                                 public OperatorEntry (int f, Operator o)
232                                 {
233                                         flags = f;
234
235                                         ret_type = o.MemberType;
236                                         Type [] pt = o.ParameterTypes;
237                                         type1 = pt [0];
238                                         type2 = pt [1];
239                                         op = o;
240                                         ot = o.OperatorType;
241                                 }
242
243                                 public override int GetHashCode ()
244                                 {       
245                                         return ret_type.GetHashCode ();
246                                 }
247
248                                 public override bool Equals (object o)
249                                 {
250                                         OperatorEntry other = (OperatorEntry) o;
251
252                                         if (other.ret_type != ret_type)
253                                                 return false;
254                                         if (other.type1 != type1)
255                                                 return false;
256                                         if (other.type2 != type2)
257                                                 return false;
258                                         return true;
259                                 }
260                         }
261                                 
262                         //
263                         // Checks that some operators come in pairs:
264                         //  == and !=
265                         // > and <
266                         // >= and <=
267                         // true and false
268                         //
269                         // They are matched based on the return type and the argument types
270                         //
271                         void CheckPairedOperators ()
272                         {
273                                 IDictionary pairs = new HybridDictionary ();
274                                 Operator true_op = null;
275                                 Operator false_op = null;
276                                 bool has_equality_or_inequality = false;
277                                 
278                                 // Register all the operators we care about.
279                                 foreach (Operator op in this){
280                                         int reg = 0;
281
282                                         // Skip erroneous code.
283                                         if (op.MethodBuilder == null)
284                                                 continue;
285
286                                         switch (op.OperatorType){
287                                         case Operator.OpType.Equality:
288                                                 reg = 1;
289                                                 has_equality_or_inequality = true;
290                                                 break;
291                                         case Operator.OpType.Inequality:
292                                                 reg = 2;
293                                                 has_equality_or_inequality = true;
294                                                 break;
295
296                                         case Operator.OpType.True:
297                                                 true_op = op;
298                                                 break;
299                                         case Operator.OpType.False:
300                                                 false_op = op;
301                                                 break;
302                                                 
303                                         case Operator.OpType.GreaterThan:
304                                                 reg = 1; break;
305                                         case Operator.OpType.LessThan:
306                                                 reg = 2; break;
307                                                 
308                                         case Operator.OpType.GreaterThanOrEqual:
309                                                 reg = 1; break;
310                                         case Operator.OpType.LessThanOrEqual:
311                                                 reg = 2; break;
312                                         }
313                                         if (reg == 0)
314                                                 continue;
315
316                                         OperatorEntry oe = new OperatorEntry (reg, op);
317
318                                         object o = pairs [oe];
319                                         if (o == null)
320                                                 pairs [oe] = oe;
321                                         else {
322                                                 oe = (OperatorEntry) o;
323                                                 oe.flags |= reg;
324                                         }
325                                 }
326
327                                 if (true_op != null){
328                                         if (false_op == null)
329                                                 Report.Error (216, true_op.Location, "The operator `{0}' requires a matching operator `false' to also be defined",
330                                                         true_op.GetSignatureForError ());
331                                 } else if (false_op != null)
332                                         Report.Error (216, false_op.Location, "The operator `{0}' requires a matching operator `true' to also be defined",
333                                                 false_op.GetSignatureForError ());
334                                 
335                                 //
336                                 // Look for the mistakes.
337                                 //
338                                 foreach (DictionaryEntry de in pairs){
339                                         OperatorEntry oe = (OperatorEntry) de.Key;
340
341                                         if (oe.flags == 3)
342                                                 continue;
343
344                                         string s = "";
345                                         switch (oe.ot){
346                                         case Operator.OpType.Equality:
347                                                 s = "!=";
348                                                 break;
349                                         case Operator.OpType.Inequality: 
350                                                 s = "==";
351                                                 break;
352                                         case Operator.OpType.GreaterThan: 
353                                                 s = "<";
354                                                 break;
355                                         case Operator.OpType.LessThan:
356                                                 s = ">";
357                                                 break;
358                                         case Operator.OpType.GreaterThanOrEqual:
359                                                 s = "<=";
360                                                 break;
361                                         case Operator.OpType.LessThanOrEqual:
362                                                 s = ">=";
363                                                 break;
364                                         }
365                                         Report.Error (216, oe.op.Location,
366                                                 "The operator `{0}' requires a matching operator `{1}' to also be defined",
367                                                 oe.op.GetSignatureForError (), s);
368                                 }
369
370                                 if (has_equality_or_inequality && (RootContext.WarningLevel > 2)) {
371                                         if (container.Methods == null || !container.Methods.HasEquals)
372                                                 Report.Warning (660, 2, container.Location, "`{0}' defines operator == or operator != but does not override Object.Equals(object o)", container.GetSignatureForError ());
373  
374                                         if (container.Methods == null || !container.Methods.HasGetHashCode)
375                                                 Report.Warning (661, 2, container.Location, "`{0}' defines operator == or operator != but does not override Object.GetHashCode()", container.GetSignatureForError ());
376                                 }
377                         }
378
379                         public override void DefineContainerMembers ()
380                         {
381                                 base.DefineContainerMembers ();
382                                 CheckPairedOperators ();
383                         }
384                 }
385
386
387                 // Whether this is a struct, class or interface
388                 public readonly Kind Kind;
389
390                 // Holds a list of classes and structures
391                 protected ArrayList types;
392
393                 // Holds the list of properties
394                 MemberCoreArrayList properties;
395
396                 // Holds the list of enumerations
397                 MemberCoreArrayList enums;
398
399                 // Holds the list of delegates
400                 MemberCoreArrayList delegates;
401                 
402                 // Holds the list of constructors
403                 protected MemberCoreArrayList instance_constructors;
404
405                 // Holds the list of fields
406                 MemberCoreArrayList fields;
407
408                 // Holds a list of fields that have initializers
409                 protected ArrayList initialized_fields;
410
411                 // Holds a list of static fields that have initializers
412                 protected ArrayList initialized_static_fields;
413
414                 // Holds the list of constants
415                 MemberCoreArrayList constants;
416
417                 // Holds the list of
418                 MemberCoreArrayList interfaces;
419
420                 // Holds the methods.
421                 MethodArrayList methods;
422
423                 // Holds the events
424                 protected MemberCoreArrayList events;
425
426                 // Holds the indexers
427                 IndexerArrayList indexers;
428
429                 // Holds the operators
430                 MemberCoreArrayList operators;
431
432                 // Holds the iterators
433                 ArrayList iterators;
434
435                 //
436                 // Pointers to the default constructor and the default static constructor
437                 //
438                 protected Constructor default_constructor;
439                 protected Constructor default_static_constructor;
440
441                 //
442                 // Points to the first non-static field added to the container.
443                 //
444                 // This is an arbitrary choice.  We are interested in looking at _some_ non-static field,
445                 // and the first one's as good as any.
446                 //
447                 FieldBase first_nonstatic_field = null;
448
449                 //
450                 // This one is computed after we can distinguish interfaces
451                 // from classes from the arraylist `type_bases' 
452                 //
453                 TypeExpr base_type;
454                 TypeExpr[] iface_exprs;
455
456                 ArrayList type_bases;
457
458                 bool members_defined;
459                 bool members_defined_ok;
460
461                 // The interfaces we implement.
462                 protected Type[] ifaces;
463
464                 // The base member cache and our member cache
465                 MemberCache base_cache;
466                 MemberCache member_cache;
467
468                 public const string DefaultIndexerName = "Item";
469
470                 Type GenericType;
471                 GenericTypeParameterBuilder[] gen_params;
472
473                 public TypeContainer PartialContainer;
474                 ArrayList partial_parts;
475
476                 /// <remarks>
477                 ///  The pending methods that need to be implemented
478                 //   (interfaces or abstract methods)
479                 /// </remarks>
480                 PendingImplementation pending;
481
482                 public TypeContainer (NamespaceEntry ns, DeclSpace parent, MemberName name,
483                                       Attributes attrs, Kind kind)
484                         : base (ns, parent, name, attrs)
485                 {
486                         if (parent != null && parent != RootContext.Tree.Types && parent.NamespaceEntry != ns)
487                                 throw new InternalErrorException ("A nested type should be in the same NamespaceEntry as its enclosing class");
488
489                         this.Kind = kind;
490                         this.PartialContainer = this;
491                 }
492
493                 public bool AddToMemberContainer (MemberCore symbol)
494                 {
495                         return AddToContainer (symbol, symbol.MemberName.MethodName);
496                 }
497
498                 protected virtual bool AddToTypeContainer (DeclSpace ds)
499                 {
500                         return AddToContainer (ds, ds.Basename);
501                 }
502
503                 public void AddConstant (Const constant)
504                 {
505                         if (!AddToMemberContainer (constant))
506                                 return;
507
508                         if (constants == null)
509                                 constants = new MemberCoreArrayList ();
510
511                         constants.Add (constant);
512                 }
513
514                 public void AddEnum (Mono.CSharp.Enum e)
515                 {
516                         if (!AddToTypeContainer (e))
517                                 return;
518
519                         if (enums == null)
520                                 enums = new MemberCoreArrayList ();
521
522                         enums.Add (e);
523                 }
524                 
525                 public bool AddClassOrStruct (TypeContainer c)
526                 {
527                         if (!AddToTypeContainer (c))
528                                 return false;
529
530                         if (types == null)
531                                 types = new ArrayList (2);
532
533                         RootContext.Tree.RecordDecl (c.NamespaceEntry.NS, c.MemberName, c);
534                         types.Add (c);
535                         return true;
536                 }
537
538                 public virtual TypeContainer AddPartial (TypeContainer nextPart)
539                 {
540                         return AddPartial (nextPart, nextPart.Basename);
541                 }
542
543                 protected TypeContainer AddPartial (TypeContainer nextPart, string name)
544                 {
545                         nextPart.ModFlags |= Modifiers.PARTIAL;
546                         TypeContainer tc = defined_names [name] as TypeContainer;
547
548                         if (tc == null) {
549                                 if (nextPart is Interface)
550                                         AddInterface (nextPart);
551                                 else
552                                         AddClassOrStruct (nextPart);
553                                 return nextPart;
554                         }
555
556                         if ((tc.ModFlags & Modifiers.PARTIAL) == 0) {
557                                 Report.SymbolRelatedToPreviousError (tc);
558                                 Error_MissingPartialModifier (nextPart);
559                                 return tc;
560                         }
561
562                         if (tc.Kind != nextPart.Kind) {
563                                 Report.SymbolRelatedToPreviousError (tc);
564                                 Report.Error (261, nextPart.Location,
565                                         "Partial declarations of `{0}' must be all classes, all structs or all interfaces",
566                                         nextPart.GetSignatureForError ());
567                                 return tc;
568                         }
569
570                         if ((tc.ModFlags & Modifiers.Accessibility) != (nextPart.ModFlags & Modifiers.Accessibility) &&
571                                 ((tc.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) == 0 &&
572                                  (nextPart.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) == 0)) {
573                                 Report.SymbolRelatedToPreviousError (tc);
574                                 Report.Error (262, nextPart.Location,
575                                         "Partial declarations of `{0}' have conflicting accessibility modifiers",
576                                         nextPart.GetSignatureForError ());
577                                 return tc;
578                         }
579
580                         if (tc.partial_parts == null)
581                                 tc.partial_parts = new ArrayList (1);
582
583                         tc.ModFlags |= nextPart.ModFlags;
584                         if (nextPart.attributes != null) {
585                                 if (tc.attributes == null)
586                                         tc.attributes = nextPart.attributes;
587                                 else
588                                         tc.attributes.AddAttributes (nextPart.attributes.Attrs);
589                         }
590
591                         nextPart.PartialContainer = tc;
592                         tc.partial_parts.Add (nextPart);
593                         return tc;
594                 }
595
596                 public void AddDelegate (Delegate d)
597                 {
598                         if (!AddToTypeContainer (d))
599                                 return;
600
601                         if (delegates == null)
602                                 delegates = new MemberCoreArrayList ();
603                         
604                         delegates.Add (d);
605                 }
606
607                 public void AddMethod (Method method)
608                 {
609                         if (!AddToMemberContainer (method))
610                                 return;
611
612                         if (methods == null)
613                                 methods = new MethodArrayList (this);
614
615                         if (method.MemberName.Left != null)
616                                 methods.Insert (0, method);
617                         else 
618                                 methods.Add (method);
619                 }
620
621                 //
622                 // Do not use this method: use AddMethod.
623                 //
624                 // This is only used by iterators.
625                 //
626                 public void AppendMethod (Method method)
627                 {
628                         if (!AddToMemberContainer (method))
629                                 return;
630
631                         if (methods == null)
632                                 methods = new MethodArrayList (this);
633
634                         methods.Add (method);
635                 }
636
637                 public void AddConstructor (Constructor c)
638                 {
639                         if (c.Name != MemberName.Name) {
640                                 Report.Error (1520, c.Location, "Class, struct, or interface method must have a return type");
641                         }
642
643                         bool is_static = (c.ModFlags & Modifiers.STATIC) != 0;
644                         
645                         if (is_static){
646                                 if (default_static_constructor != null) {
647                                         Report.SymbolRelatedToPreviousError (default_static_constructor);
648                                         Report.Error (111, c.Location, Error111, c.GetSignatureForError ());
649                                         return;
650                                 }
651
652                                 default_static_constructor = c;
653                         } else {
654                                 if (c.Parameters.Empty){
655                                         if (default_constructor != null) {
656                                                 Report.SymbolRelatedToPreviousError (default_constructor);
657                                                 Report.Error (111, c.Location, Error111, c.GetSignatureForError ());
658                                                 return;
659                                         }
660                                         default_constructor = c;
661                                 }
662                                 
663                                 if (instance_constructors == null)
664                                         instance_constructors = new MemberCoreArrayList ();
665                                 
666                                 instance_constructors.Add (c);
667                         }
668                 }
669
670                 internal static string Error111 {
671                         get {
672                                 return "`{0}' is already defined. Rename this member or use different parameter types";
673                         }
674                 }
675                 
676                 public bool AddInterface (TypeContainer iface)
677                 {
678                         if (!AddToTypeContainer (iface))
679                                 return false;
680
681                         if (interfaces == null) {
682                                 interfaces = new MemberCoreArrayList ();
683                         }
684
685                         RootContext.Tree.RecordDecl (iface.NamespaceEntry.NS, iface.MemberName, iface);
686                         interfaces.Add (iface);
687                         return true;
688                 }
689
690                 public void AddField (FieldMember field)
691                 {
692                         if (!AddToMemberContainer (field))
693                                 return;
694
695                         if (fields == null)
696                                 fields = new MemberCoreArrayList ();
697
698                         fields.Add (field);
699                         
700                         if ((field.ModFlags & Modifiers.STATIC) != 0)
701                                 return;
702
703                         if (first_nonstatic_field == null) {
704                                 first_nonstatic_field = field;
705                                 return;
706                         }
707
708                         if (Kind == Kind.Struct &&
709                             first_nonstatic_field.Parent != field.Parent &&
710                             RootContext.WarningLevel >= 3) {
711                                 Report.SymbolRelatedToPreviousError (first_nonstatic_field.Parent);
712                                 Report.Warning (282, 3, field.Location,
713                                         "struct instance field `{0}' found in different declaration from instance field `{1}'",
714                                         field.GetSignatureForError (), first_nonstatic_field.GetSignatureForError ());
715                         }
716                 }
717
718                 public void AddProperty (Property prop)
719                 {
720                         if (!AddToMemberContainer (prop) || 
721                                 !AddToMemberContainer (prop.Get) || !AddToMemberContainer (prop.Set))
722                                 return;
723
724                         if (properties == null)
725                                 properties = new MemberCoreArrayList ();
726
727                         if (prop.MemberName.Left != null)
728                                 properties.Insert (0, prop);
729                         else
730                                 properties.Add (prop);
731                 }
732
733                 public void AddEvent (Event e)
734                 {
735                         if (!AddToMemberContainer (e))
736                                 return;
737
738                         if (e is EventProperty) {
739                                 if (!AddToMemberContainer (e.Add))
740                                         return;
741
742                                 if (!AddToMemberContainer (e.Remove))
743                                         return;
744                         }
745
746                         if (events == null)
747                                 events = new MemberCoreArrayList ();
748
749                         events.Add (e);
750                 }
751
752                 /// <summary>
753                 /// Indexer has special handling in constrast to other AddXXX because the name can be driven by IndexerNameAttribute
754                 /// </summary>
755                 public void AddIndexer (Indexer i)
756                 {
757                         if (indexers == null)
758                                 indexers = new IndexerArrayList (this);
759
760                         if (i.IsExplicitImpl)
761                                 indexers.Insert (0, i);
762                         else
763                                 indexers.Add (i);
764                 }
765
766                 public void AddOperator (Operator op)
767                 {
768                         if (!AddToMemberContainer (op))
769                                 return;
770
771                         if (operators == null)
772                                 operators = new OperatorArrayList (this);
773
774                         operators.Add (op);
775                 }
776
777                 public void AddIterator (Iterator i)
778                 {
779                         if (iterators == null)
780                                 iterators = new ArrayList ();
781
782                         iterators.Add (i);
783                 }
784
785                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
786                 {
787                         if (a.Type == TypeManager.default_member_type) {
788                                 if (Indexers != null) {
789                                         Report.Error (646, a.Location, "Cannot specify the `DefaultMember' attribute on type containing an indexer");
790                                         return;
791                                 }
792                         }
793                         
794                         base.ApplyAttributeBuilder (a, cb);
795                 } 
796
797                 public override AttributeTargets AttributeTargets {
798                         get {
799                                 throw new NotSupportedException ();
800                         }
801                 }
802
803                 public ArrayList Types {
804                         get {
805                                 return types;
806                         }
807                 }
808
809                 public MethodArrayList Methods {
810                         get {
811                                 return methods;
812                         }
813                 }
814
815                 public ArrayList Constants {
816                         get {
817                                 return constants;
818                         }
819                 }
820
821                 public ArrayList Interfaces {
822                         get {
823                                 return interfaces;
824                         }
825                 }
826
827                 public ArrayList Iterators {
828                         get {
829                                 return iterators;
830                         }
831                 }
832
833                 protected Type BaseType {
834                         get {
835                                 return TypeBuilder.BaseType;
836                         }
837                 }
838                 
839                 public ArrayList Bases {
840                         get {
841                                 return type_bases;
842                         }
843
844                         set {
845                                 type_bases = value;
846                         }
847                 }
848
849                 public ArrayList Fields {
850                         get {
851                                 return fields;
852                         }
853                 }
854
855                 public ArrayList InstanceConstructors {
856                         get {
857                                 return instance_constructors;
858                         }
859                 }
860
861                 public ArrayList Properties {
862                         get {
863                                 return properties;
864                         }
865                 }
866
867                 public ArrayList Events {
868                         get {
869                                 return events;
870                         }
871                 }
872                 
873                 public ArrayList Enums {
874                         get {
875                                 return enums;
876                         }
877                 }
878
879                 public ArrayList Indexers {
880                         get {
881                                 return indexers;
882                         }
883                 }
884
885                 public ArrayList Operators {
886                         get {
887                                 return operators;
888                         }
889                 }
890
891                 public ArrayList Delegates {
892                         get {
893                                 return delegates;
894                         }
895                 }
896                 
897                 protected override TypeAttributes TypeAttr {
898                         get {
899                                 return Modifiers.TypeAttr (ModFlags, IsTopLevel) | base.TypeAttr;
900                         }
901                 }
902
903                 public string IndexerName {
904                         get {
905                                 return indexers == null ? DefaultIndexerName : indexers.IndexerName;
906                         }
907                 }
908
909                 public bool IsComImport {
910                         get {
911                                 if (OptAttributes == null)
912                                         return false;
913
914                                 return OptAttributes.Contains (TypeManager.comimport_attr_type);
915                         }
916                 }
917
918                 public virtual void RegisterFieldForInitialization (FieldBase field)
919                 {
920                         if ((field.ModFlags & Modifiers.STATIC) != 0){
921                                 if (initialized_static_fields == null)
922                                         initialized_static_fields = new ArrayList (4);
923
924                                 initialized_static_fields.Add (field);
925                         } else {
926                                 if (initialized_fields == null)
927                                         initialized_fields = new ArrayList (4);
928
929                                 initialized_fields.Add (field);
930                         }
931                 }
932
933                 //
934                 // Emits the instance field initializers
935                 //
936                 public bool EmitFieldInitializers (EmitContext ec)
937                 {
938                         ArrayList fields;
939                         
940                         if (ec.IsStatic){
941                                 fields = initialized_static_fields;
942                         } else {
943                                 fields = initialized_fields;
944                         }
945
946                         if (fields == null)
947                                 return true;
948
949                         foreach (FieldBase f in fields) {
950                                 f.EmitInitializer (ec);
951                         }
952                         return true;
953                 }
954                 
955                 public override string DocComment {
956                         get {
957                                 return comment;
958                         }
959                         set {
960                                 if (value == null)
961                                         return;
962
963                                 comment += value;
964                         }
965                 }
966
967                 public PendingImplementation PendingImplementations {
968                         get { return pending; }
969                 }
970
971                 public override bool GetClsCompliantAttributeValue ()
972                 {
973                         if (PartialContainer != this)
974                                 return PartialContainer.GetClsCompliantAttributeValue ();
975
976                         return base.GetClsCompliantAttributeValue ();
977                 }
978
979                 TypeExpr[] GetNormalBases (out TypeExpr base_class)
980                 {
981                         base_class = null;
982                         if (Bases == null)
983                                 return null;
984
985                         int count = Bases.Count;
986                         int start = 0, i, j;
987
988                         if (Kind == Kind.Class){
989                                 TypeExpr name = ((Expression) Bases [0]).ResolveAsBaseTerminal (this, false);
990
991                                 if (name == null){
992                                         return null;
993                                 }
994
995                                 if (!name.IsInterface) {
996                                         // base_class could be a class, struct, enum, delegate.
997                                         // This is validated in GetClassBases.
998                                         base_class = name;
999                                         start = 1;
1000                                 }
1001                         }
1002
1003                         TypeExpr [] ifaces = new TypeExpr [count-start];
1004                         
1005                         for (i = start, j = 0; i < count; i++, j++){
1006                                 TypeExpr resolved = ((Expression) Bases [i]).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                                 } else if ((flags & MethodAttributes.MemberAccessMask) != MethodAttributes.Public){
4829                                         if (TypeManager.IsInterfaceType (implementing.DeclaringType)){
4830                                                 //
4831                                                 // If this is an interface method implementation,
4832                                                 // check for public accessibility
4833                                                 //
4834                                                 implementing = null;
4835                                         } else if ((flags & MethodAttributes.MemberAccessMask) == MethodAttributes.Private){
4836                                                 // We may never be private.
4837                                                 implementing = null;
4838                                         } else if ((modifiers & Modifiers.OVERRIDE) == 0){
4839                                                 //
4840                                                 // We may be protected if we're overriding something.
4841                                                 //
4842                                                 implementing = null;
4843                                         }
4844                                 } 
4845                                         
4846                                 //
4847                                 // Static is not allowed
4848                                 //
4849                                 if ((modifiers & Modifiers.STATIC) != 0){
4850                                         implementing = null;
4851                                 }
4852                         }
4853                         
4854                         //
4855                         // If implementing is still valid, set flags
4856                         //
4857                         if (implementing != null){
4858                                 //
4859                                 // When implementing interface methods, set NewSlot
4860                                 // unless, we are overwriting a method.
4861                                 //
4862                                 if (implementing.DeclaringType.IsInterface){
4863                                         if ((modifiers & Modifiers.OVERRIDE) == 0)
4864                                                 flags |= MethodAttributes.NewSlot;
4865                                 }
4866                                 flags |=
4867                                         MethodAttributes.Virtual |
4868                                         MethodAttributes.HideBySig;
4869
4870                                 // Set Final unless we're virtual, abstract or already overriding a method.
4871                                 if ((modifiers & (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE)) == 0)
4872                                         flags |= MethodAttributes.Final;
4873                         }
4874
4875                         EmitContext ec = method.CreateEmitContext (container, null);
4876
4877                         DefineMethodBuilder (container, method_name, method.ParameterInfo.Types);
4878
4879                         if (builder == null)
4880                                 return false;
4881
4882                         if (container.CurrentType != null)
4883                                 declaring_type = container.CurrentType;
4884                         else
4885                                 declaring_type = container.TypeBuilder;
4886
4887                         if ((modifiers & Modifiers.UNSAFE) != 0)
4888                                 builder.InitLocals = false;
4889
4890                         if (implementing != null){
4891                                 //
4892                                 // clear the pending implemntation flag
4893                                 //
4894                                 if (member is Indexer) {
4895                                         pending.ImplementIndexer (
4896                                                 member.InterfaceType, builder, method.ReturnType,
4897                                                 method.ParameterInfo, member.IsExplicitImpl);
4898                                 } else
4899                                         pending.ImplementMethod (
4900                                                 member.InterfaceType, name, method.ReturnType,
4901                                                 method.ParameterInfo, member.IsExplicitImpl);
4902
4903                                 if (member.IsExplicitImpl)
4904                                         container.TypeBuilder.DefineMethodOverride (
4905                                                 builder, implementing);
4906
4907                         }
4908
4909                         TypeManager.AddMethod (builder, method);
4910
4911                         if (GenericMethod != null) {
4912                                 bool is_override = member.IsExplicitImpl |
4913                                         ((modifiers & Modifiers.OVERRIDE) != 0);
4914
4915                                 if (implementing != null)
4916                                         parent_method = implementing;
4917
4918                                 if (!GenericMethod.DefineType (ec, builder, parent_method, is_override))
4919                                         return false;
4920                         }
4921
4922                         return true;
4923                 }
4924
4925
4926                 /// <summary>
4927                 /// Create the MethodBuilder for the method 
4928                 /// </summary>
4929                 void DefineMethodBuilder (TypeContainer container, string method_name, Type[] ParameterTypes)
4930                 {
4931                         const int extern_static = Modifiers.EXTERN | Modifiers.STATIC;
4932
4933                         if ((modifiers & extern_static) == extern_static) {
4934
4935                                 if (method.OptAttributes != null) {
4936                                         Attribute dllimport_attribute = method.OptAttributes.Search (TypeManager.dllimport_type);
4937                                         if (dllimport_attribute != null) {
4938                                                 flags |= MethodAttributes.PinvokeImpl;
4939                                                 builder = dllimport_attribute.DefinePInvokeMethod (
4940                                                         container.TypeBuilder, method_name, flags,
4941                                                         method.ReturnType, ParameterTypes);
4942
4943                                                 return;
4944                                         }
4945                                 }
4946
4947                                 // for extern static method must be specified either DllImport attribute or MethodImplAttribute.
4948                                 // We are more strict than Microsoft and report CS0626 like error
4949                                 if (method.OptAttributes == null ||
4950                                         !method.OptAttributes.Contains (TypeManager.methodimpl_attr_type)) {
4951                                         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",
4952                                                 method.GetSignatureForError ());
4953                                         return;
4954                                 }
4955                         }
4956
4957                         if (builder == null) {
4958                                 builder = container.TypeBuilder.DefineMethod (
4959                                         method_name, flags, method.CallingConventions,
4960                                         method.ReturnType, ParameterTypes);
4961                                 return;
4962                         }
4963 #if !MS_COMPATIBLE
4964                                 builder.SetGenericMethodSignature (
4965                                         flags, method.CallingConventions,
4966                                         method.ReturnType, ParameterTypes);
4967 #endif
4968                 }
4969
4970                 //
4971                 // Emits the code
4972                 // 
4973                 public void Emit (DeclSpace parent)
4974                 {
4975                         EmitContext ec;
4976                         if ((flags & MethodAttributes.PinvokeImpl) == 0)
4977                                 ec = method.CreateEmitContext (parent, builder.GetILGenerator ());
4978                         else
4979                                 ec = method.CreateEmitContext (parent, null);
4980
4981                         method.ParameterInfo.ApplyAttributes (MethodBuilder);
4982
4983                         if (GenericMethod != null)
4984                                 GenericMethod.EmitAttributes ();
4985
4986                         ToplevelBlock block = method.Block;
4987                         
4988                         SourceMethod source = SourceMethod.Create (parent, MethodBuilder, method.Block);
4989
4990                         //
4991                         // Handle destructors specially
4992                         //
4993                         // FIXME: This code generates buggy code
4994                         //
4995                         if (member is Destructor)
4996                                 EmitDestructor (ec, block);
4997                         else
4998                                 ec.EmitTopBlock (method, block);
4999
5000                         if (source != null)
5001                                 source.CloseMethod ();
5002                 }
5003
5004                 void EmitDestructor (EmitContext ec, ToplevelBlock block)
5005                 {
5006                         ILGenerator ig = ec.ig;
5007                         
5008                         Label finish = ig.DefineLabel ();
5009
5010                         block.SetDestructor ();
5011                         
5012                         ig.BeginExceptionBlock ();
5013                         ec.ReturnLabel = finish;
5014                         ec.HasReturnLabel = true;
5015                         ec.EmitTopBlock (method, block);
5016                         
5017                         // ig.MarkLabel (finish);
5018                         ig.BeginFinallyBlock ();
5019                         
5020                         if (ec.ContainerType.BaseType != null) {
5021                                 Expression member_lookup = Expression.MemberLookup (
5022                                         ec.ContainerType.BaseType, null, ec.ContainerType.BaseType,
5023                                         "Finalize", MemberTypes.Method, Expression.AllBindingFlags, method.Location);
5024
5025                                 if (member_lookup != null){
5026                                         MethodGroupExpr base_destructor = ((MethodGroupExpr) member_lookup);
5027                                 
5028                                         ig.Emit (OpCodes.Ldarg_0);
5029                                         ig.Emit (OpCodes.Call, (MethodInfo) base_destructor.Methods [0]);
5030                                 }
5031                         }
5032                         
5033                         ig.EndExceptionBlock ();
5034                         //ig.MarkLabel (ec.ReturnLabel);
5035                         ig.Emit (OpCodes.Ret);
5036                 }
5037         }
5038
5039         // TODO: Should derive from MethodCore
5040         public class Destructor : Method {
5041
5042                 static string[] attribute_targets = new string [] { "method" };
5043
5044                 public Destructor (DeclSpace parent, Expression return_type, int mod,
5045                                    string name, Parameters parameters, Attributes attrs,
5046                                    Location l)
5047                         : base (parent, null, return_type, mod, false, new MemberName (name, l),
5048                                 parameters, attrs)
5049                 { }
5050
5051                 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
5052                 {
5053                         if (a.Type == TypeManager.conditional_attribute_type) {
5054                                 Error_ConditionalAttributeIsNotValid ();
5055                                 return;
5056                         }
5057
5058                         base.ApplyAttributeBuilder (a, cb);
5059                 }
5060
5061                 public override string GetSignatureForError ()
5062                 {
5063                         return Parent.GetSignatureForError () + ".~" + Parent.MemberName.Name + "()";
5064                 }
5065
5066                 public override string[] ValidAttributeTargets {
5067                         get {
5068                                 return attribute_targets;
5069                         }
5070                 }
5071         }
5072         
5073         abstract public class MemberBase : MemberCore {
5074                 public Expression Type;
5075
5076                 public MethodAttributes flags;
5077                 public readonly DeclSpace ds;
5078                 public readonly GenericMethod GenericMethod;
5079
5080                 protected readonly int explicit_mod_flags;
5081
5082                 //
5083                 // The "short" name of this property / indexer / event.  This is the
5084                 // name without the explicit interface.
5085                 //
5086                 public string ShortName {
5087                         get { return MemberName.Name; }
5088                         set { SetMemberName (new MemberName (MemberName.Left, value, Location)); }
5089                 }
5090
5091                 public TypeContainer ParentContainer {
5092                         get { return ((TypeContainer) Parent).PartialContainer; }
5093                 }
5094
5095                 //
5096                 // The type of this property / indexer / event
5097                 //
5098                 protected Type member_type;
5099                 public Type MemberType {
5100                         get {
5101                                 if (member_type == null && Type != null) {
5102                                         IResolveContext rc = GenericMethod == null ? this : (IResolveContext)ds;
5103                                         Type = Type.ResolveAsTypeTerminal (rc, false);
5104                                         if (Type != null) {
5105                                                 member_type = Type.Type;
5106                                         }
5107                                 }
5108                                 return member_type;
5109                         }
5110                 }
5111
5112                 //
5113                 // Whether this is an interface member.
5114                 //
5115                 public bool IsInterface;
5116
5117                 //
5118                 // If true, this is an explicit interface implementation
5119                 //
5120                 public bool IsExplicitImpl;
5121
5122                 //
5123                 // The interface type we are explicitly implementing
5124                 //
5125                 public Type InterfaceType = null;
5126
5127                 //
5128                 // The constructor is only exposed to our children
5129                 //
5130                 protected MemberBase (DeclSpace parent, GenericMethod generic,
5131                                       Expression type, int mod, int allowed_mod, int def_mod,
5132                                       MemberName name, Attributes attrs)
5133                         : base (parent, name, attrs)
5134                 {
5135                         this.ds = generic != null ? generic : (DeclSpace) parent;
5136                         explicit_mod_flags = mod;
5137                         Type = type;
5138                         ModFlags = Modifiers.Check (allowed_mod, mod, def_mod, Location);
5139                         IsExplicitImpl = (MemberName.Left != null);
5140                         GenericMethod = generic;
5141                         if (GenericMethod != null)
5142                                 GenericMethod.ModFlags = ModFlags;
5143                 }
5144
5145                 protected virtual bool CheckBase ()
5146                 {
5147                         if ((ModFlags & Modifiers.PROTECTED) != 0 && ParentContainer.Kind == Kind.Struct) {
5148                                 Report.Error (666, Location, "`{0}': new protected member declared in struct", GetSignatureForError ());
5149                                 return false;
5150                         }
5151    
5152                         if ((RootContext.WarningLevel >= 4) &&
5153                             ((Parent.ModFlags & Modifiers.SEALED) != 0) &&
5154                             ((ModFlags & Modifiers.PROTECTED) != 0) &&
5155                             ((ModFlags & Modifiers.OVERRIDE) == 0) && (Name != "Finalize")) {
5156                                 Report.Warning (628, 4, Location, "`{0}': new protected member declared in sealed class", GetSignatureForError ());
5157                         }
5158                         return true;
5159                 }
5160
5161                 protected virtual bool DoDefineBase ()
5162                 {
5163                         if (Name == null)
5164                                 throw new InternalErrorException ();
5165
5166                         if (IsInterface) {
5167                                 ModFlags = Modifiers.PUBLIC |
5168                                         Modifiers.ABSTRACT |
5169                                         Modifiers.VIRTUAL | (ModFlags & Modifiers.UNSAFE) | (ModFlags & Modifiers.NEW);
5170
5171                                 flags = MethodAttributes.Public |
5172                                         MethodAttributes.Abstract |
5173                                         MethodAttributes.HideBySig |
5174                                         MethodAttributes.NewSlot |
5175                                         MethodAttributes.Virtual;
5176                         } else {
5177                                 if (!ParentContainer.MethodModifiersValid (this))
5178                                         return false;
5179
5180                                 flags = Modifiers.MethodAttr (ModFlags);
5181                         }
5182
5183                         if (IsExplicitImpl) {
5184                                 Expression expr = MemberName.Left.GetTypeExpression ();
5185                                 TypeExpr iface_texpr = expr.ResolveAsTypeTerminal (this, false);
5186                                 if (iface_texpr == null)
5187                                         return false;
5188
5189                                 InterfaceType = iface_texpr.Type;
5190
5191                                 if (!InterfaceType.IsInterface) {
5192                                         Report.Error (538, Location, "'{0}' in explicit interface declaration is not an interface", TypeManager.CSharpName (InterfaceType));
5193                                         return false;
5194                                 }
5195
5196                                 if (!ParentContainer.VerifyImplements (this))
5197                                         return false;
5198                                 
5199                                 Modifiers.Check (Modifiers.AllowedExplicitImplFlags, explicit_mod_flags, 0, Location);
5200                         }
5201
5202                         return true;
5203                 }
5204
5205                 protected virtual bool DoDefine ()
5206                 {
5207                         if (MemberType == null)
5208                                 return false;
5209
5210                         if ((Parent.ModFlags & Modifiers.SEALED) != 0 && 
5211                                 (ModFlags & (Modifiers.VIRTUAL|Modifiers.ABSTRACT)) != 0) {
5212                                         Report.Error (549, Location, "New virtual member `{0}' is declared in a sealed class `{1}'",
5213                                                 GetSignatureForError (), Parent.GetSignatureForError ());
5214                                         return false;
5215                         }
5216                         
5217                         // verify accessibility
5218                         if (!Parent.AsAccessible (MemberType, ModFlags)) {
5219                                 Report.SymbolRelatedToPreviousError (MemberType);
5220                                 if (this is Property)
5221                                         Report.Error (53, Location,
5222                                                       "Inconsistent accessibility: property type `" +
5223                                                       TypeManager.CSharpName (MemberType) + "' is less " +
5224                                                       "accessible than property `" + GetSignatureForError () + "'");
5225                                 else if (this is Indexer)
5226                                         Report.Error (54, Location,
5227                                                       "Inconsistent accessibility: indexer return type `" +
5228                                                       TypeManager.CSharpName (MemberType) + "' is less " +
5229                                                       "accessible than indexer `" + GetSignatureForError () + "'");
5230                                 else if (this is MethodCore) {
5231                                         if (this is Operator)
5232                                                 Report.Error (56, Location,
5233                                                               "Inconsistent accessibility: return type `" +
5234                                                               TypeManager.CSharpName (MemberType) + "' is less " +
5235                                                               "accessible than operator `" + GetSignatureForError () + "'");
5236                                         else
5237                                                 Report.Error (50, Location,
5238                                                               "Inconsistent accessibility: return type `" +
5239                                                               TypeManager.CSharpName (MemberType) + "' is less " +
5240                                                               "accessible than method `" + GetSignatureForError () + "'");
5241                                 } else {
5242                                         Report.Error (52, Location,
5243                                                       "Inconsistent accessibility: field type `" +
5244                                                       TypeManager.CSharpName (MemberType) + "' is less " +
5245                                                       "accessible than field `" + GetSignatureForError () + "'");
5246                                 }
5247                                 return false;
5248                         }
5249
5250                         if (IsExplicitImpl) {
5251                                 Expression expr = MemberName.Left.GetTypeExpression ();
5252                                 TypeExpr texpr = expr.ResolveAsTypeTerminal (this, false);
5253                                 if (texpr == null)
5254                                         return false;
5255
5256                                 InterfaceType = texpr.Type;
5257
5258                                 if (!InterfaceType.IsInterface) {
5259                                         Report.Error (538, Location, "`{0}' in explicit interface declaration is not an interface", TypeManager.CSharpName (InterfaceType));
5260                                         return false;
5261                                 }
5262                                 
5263                                 if (!ParentContainer.VerifyImplements (this))
5264                                         return false;
5265                                 
5266                                 Modifiers.Check (Modifiers.AllowedExplicitImplFlags, explicit_mod_flags, 0, Location);
5267                                 
5268                         }
5269                         return true;
5270                 }
5271
5272                 protected bool IsTypePermitted ()
5273                 {
5274                         if (MemberType == TypeManager.arg_iterator_type || MemberType == TypeManager.typed_reference_type) {
5275                                 Report.Error (610, Location, "Field or property cannot be of type `{0}'", TypeManager.CSharpName (MemberType));
5276                                 return false;
5277                         }
5278                         return true;
5279                 }
5280
5281                 protected override bool VerifyClsCompliance()
5282                 {
5283                         if (base.VerifyClsCompliance ()) {
5284                                 return true;
5285                         }
5286
5287                         if (IsInterface && HasClsCompliantAttribute && Parent.IsClsComplianceRequired ()) {
5288                                 Report.Error (3010, Location, "`{0}': CLS-compliant interfaces must have only CLS-compliant members", GetSignatureForError ());
5289                         }
5290                         return false;
5291                 }
5292
5293         }
5294
5295         //
5296         // Fields and Events both generate FieldBuilders, we use this to share 
5297         // their common bits.  This is also used to flag usage of the field
5298         //
5299         abstract public class FieldBase : MemberBase {
5300                 public FieldBuilder  FieldBuilder;
5301                 public Status status;
5302                 protected Expression initializer;
5303                 ExpressionStatement initializerStatement;
5304
5305                 [Flags]
5306                 public enum Status : byte {
5307                         HAS_OFFSET = 4          // Used by FieldMember.
5308                 }
5309
5310                 static string[] attribute_targets = new string [] { "field" };
5311
5312                 /// <summary>
5313                 ///  Symbol with same name in base class/struct
5314                 /// </summary>
5315                 public MemberInfo conflict_symbol;
5316
5317                 protected FieldBase (DeclSpace parent, Expression type, int mod,
5318                                      int allowed_mod, MemberName name, Attributes attrs)
5319                         : base (parent, null, type, mod, allowed_mod, Modifiers.PRIVATE,
5320                                 name, attrs)
5321                 {
5322                 }
5323
5324                 public override AttributeTargets AttributeTargets {
5325                         get {
5326                                 return AttributeTargets.Field;
5327                         }
5328                 }
5329
5330                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
5331                 {
5332                         if (a.Type == TypeManager.marshal_as_attr_type) {
5333                                 UnmanagedMarshal marshal = a.GetMarshal (this);
5334                                 if (marshal != null) {
5335                                         FieldBuilder.SetMarshal (marshal);
5336                                 }
5337                                 return;
5338                         }
5339
5340                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
5341                                 a.Error_InvalidSecurityParent ();
5342                                 return;
5343                         }
5344
5345                         FieldBuilder.SetCustomAttribute (cb);
5346                 }
5347
5348                 public void EmitInitializer (EmitContext ec)
5349                 {
5350                         initializerStatement.EmitStatement (ec);
5351                 }
5352
5353                 protected override bool CheckBase ()
5354                 {
5355                         if (!base.CheckBase ())
5356                                 return false;
5357
5358                         // TODO: Implement
5359                         if (IsInterface)
5360                                 return true;
5361
5362                         conflict_symbol = ParentContainer.FindBaseMemberWithSameName (Name, false);
5363                         if (conflict_symbol == null) {
5364                                 if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0)) {
5365                                         Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
5366                                 }
5367                                 return true;
5368                         }
5369
5370                         if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE)) == 0) {
5371                                 Report.SymbolRelatedToPreviousError (conflict_symbol);
5372                                 Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
5373                                         GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
5374                         }
5375
5376                         return true;
5377                 }
5378
5379                 public Expression Initializer {
5380                         set {
5381                                 if (value != null) {
5382                                         this.initializer = value;
5383                                         ParentContainer.RegisterFieldForInitialization (this);
5384                                 }
5385                         }
5386                 }
5387
5388                 protected virtual bool IsFieldClsCompliant {
5389                         get {
5390                                 if (FieldBuilder == null)
5391                                         return true;
5392
5393                                 return AttributeTester.IsClsCompliant (FieldBuilder.FieldType);
5394                         }
5395                 }
5396
5397                 public Expression ResolveInitializer ()
5398                 {
5399                         // TODO: again it's too heavy-weight
5400                         EmitContext ec = new EmitContext (this, Parent, Location, null, null, ModFlags);
5401                         ec.IsFieldInitializer = true;
5402                         initializer = initializer.Resolve (ec);
5403                         if (initializer == null)
5404                                 return null;
5405
5406                         FieldExpr fe = new FieldExpr (FieldBuilder, Location, true);
5407                         if ((ModFlags & Modifiers.STATIC) == 0) 
5408                         {
5409                                 fe.InstanceExpression = CompilerGeneratedThis.Instance;
5410                         }
5411
5412                         initializerStatement = new Assign (fe, initializer, Location).ResolveStatement (ec);
5413                         return initializer;
5414                 }
5415
5416                 public bool HasDefaultInitializer
5417                 {
5418                         get
5419                         {
5420                                 Constant c = initializer as Constant;
5421                                 if (c == null)
5422                                         return false;
5423
5424                                 return c.IsDefaultInitializer (MemberType);
5425                         }
5426                 }
5427
5428                 public override string[] ValidAttributeTargets 
5429                 {
5430                         get {
5431                                 return attribute_targets;
5432                         }
5433                 }
5434
5435                 protected override bool VerifyClsCompliance ()
5436                 {
5437                         if (!base.VerifyClsCompliance ())
5438                                 return false;
5439
5440                         if (!IsFieldClsCompliant) {
5441                                 Report.Error (3003, Location, "Type of `{0}' is not CLS-compliant", GetSignatureForError ());
5442                         }
5443                         return true;
5444                 }
5445
5446
5447                 public void SetAssigned ()
5448                 {
5449                         caching_flags |= Flags.IsAssigned;
5450                 }
5451         }
5452
5453         public abstract class FieldMember : FieldBase
5454         {
5455                 protected FieldMember (DeclSpace parent, Expression type, int mod,
5456                         int allowed_mod, MemberName name, Attributes attrs)
5457                         : base (parent, type, mod, allowed_mod | Modifiers.ABSTRACT, name, attrs)
5458                 {
5459                         if ((mod & Modifiers.ABSTRACT) != 0)
5460                                 Report.Error (681, Location, "The modifier 'abstract' is not valid on fields. Try using a property instead");
5461                 }
5462
5463                 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
5464                 {
5465                         if (a.Type == TypeManager.field_offset_attribute_type)
5466                         {
5467                                 status |= Status.HAS_OFFSET;
5468
5469                                 if (!ParentContainer.HasExplicitLayout) {
5470                                         Report.Error (636, Location, "The FieldOffset attribute can only be placed on members of types marked with the StructLayout(LayoutKind.Explicit)");
5471                                         return;
5472                                 }
5473
5474                                 if ((ModFlags & Modifiers.STATIC) != 0 || this is Const) {
5475                                         Report.Error (637, Location, "The FieldOffset attribute is not allowed on static or const fields");
5476                                         return;
5477                                 }
5478                         }
5479
5480                         if (a.Type == TypeManager.fixed_buffer_attr_type) {
5481                                 Report.Error (1716, Location, "Do not use 'System.Runtime.CompilerServices.FixedBuffer' attribute. Use the 'fixed' field modifier instead");
5482                                 return;
5483                         }
5484
5485                         base.ApplyAttributeBuilder (a, cb);
5486                 }
5487
5488                 public override bool Define()
5489                 {
5490                         if (MemberType == null || Type == null)
5491                                 return false;
5492                         
5493                         if (MemberType == TypeManager.void_type) {
5494                                 Report.Error (1547, Location, "Keyword 'void' cannot be used in this context");
5495                                 return false;
5496                         }
5497
5498                         if (!CheckBase ())
5499                                 return false;
5500                         
5501                         if (!Parent.AsAccessible (MemberType, ModFlags)) {
5502                                 Report.Error (52, Location,
5503                                         "Inconsistent accessibility: field type `" +
5504                                         TypeManager.CSharpName (MemberType) + "' is less " +
5505                                         "accessible than field `" + GetSignatureForError () + "'");
5506                                 return false;
5507                         }
5508
5509                         if (!IsTypePermitted ())
5510                                 return false;
5511
5512                         return true;
5513                 }
5514
5515                 public override void Emit ()
5516                 {
5517                         if (OptAttributes != null) {
5518                                 OptAttributes.Emit ();
5519                         }
5520
5521                         if (((status & Status.HAS_OFFSET) == 0) && (ModFlags & Modifiers.STATIC) == 0 && ParentContainer.HasExplicitLayout) {
5522                                 Report.Error (625, Location, "`{0}': Instance field types marked with StructLayout(LayoutKind.Explicit) must have a FieldOffset attribute.", GetSignatureForError ());
5523                         }
5524
5525                         base.Emit ();
5526                 }
5527
5528                 //
5529                 //   Represents header string for documentation comment.
5530                 //
5531                 public override string DocCommentHeader {
5532                         get { return "F:"; }
5533                 }
5534         }
5535
5536         interface IFixedBuffer
5537         {
5538                 FieldInfo Element { get; }
5539                 Type ElementType { get; }
5540         }
5541
5542         public class FixedFieldExternal: IFixedBuffer
5543         {
5544                 FieldInfo element_field;
5545
5546                 public FixedFieldExternal (FieldInfo fi)
5547                 {
5548                         element_field = fi.FieldType.GetField (FixedField.FixedElementName);
5549                 }
5550
5551                 #region IFixedField Members
5552
5553                 public FieldInfo Element {
5554                         get {
5555                                 return element_field;
5556                         }
5557                 }
5558
5559                 public Type ElementType {
5560                         get {
5561                                 return element_field.FieldType;
5562                         }
5563                 }
5564
5565                 #endregion
5566         }
5567
5568         /// <summary>
5569         /// Fixed buffer implementation
5570         /// </summary>
5571         public class FixedField : FieldMember, IFixedBuffer
5572         {
5573                 public const string FixedElementName = "FixedElementField";
5574                 static int GlobalCounter = 0;
5575                 static object[] ctor_args = new object[] { (short)LayoutKind.Sequential };
5576                 static FieldInfo[] fi;
5577
5578                 TypeBuilder fixed_buffer_type;
5579                 FieldBuilder element;
5580                 Expression size_expr;
5581                 int buffer_size;
5582
5583                 const int AllowedModifiers =
5584                         Modifiers.NEW |
5585                         Modifiers.PUBLIC |
5586                         Modifiers.PROTECTED |
5587                         Modifiers.INTERNAL |
5588                         Modifiers.PRIVATE;
5589
5590                 public FixedField (DeclSpace parent, Expression type, int mod, string name,
5591                         Expression size_expr, Attributes attrs, Location loc):
5592                         base (parent, type, mod, AllowedModifiers, new MemberName (name, loc), attrs)
5593                 {
5594                         if (RootContext.Version == LanguageVersion.ISO_1)
5595                                 Report.FeatureIsNotStandardized (loc, "fixed size buffers");
5596
5597                         this.size_expr = size_expr;
5598                 }
5599
5600                 public override bool Define()
5601                 {
5602 #if !NET_2_0
5603                         if ((ModFlags & (Modifiers.PUBLIC | Modifiers.PROTECTED)) != 0)
5604                                 Report.Warning (-23, 1, Location, "Only private or internal fixed sized buffers are supported by .NET 1.x");
5605 #endif
5606
5607                         if (ParentContainer.Kind != Kind.Struct) {
5608                                 Report.Error (1642, Location, "`{0}': Fixed size buffer fields may only be members of structs",
5609                                         GetSignatureForError ());
5610                                 return false;
5611                         }
5612
5613                         if (!base.Define ())
5614                                 return false;
5615
5616                         if (!TypeManager.IsPrimitiveType (MemberType)) {
5617                                 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",
5618                                         GetSignatureForError ());
5619                                 return false;
5620                         }
5621
5622                         EmitContext ec = new EmitContext (this, Parent, Location, null, null, ModFlags);
5623                         Constant c = size_expr.ResolveAsConstant (ec, this);
5624                         if (c == null)
5625                                 return false;
5626
5627                         IntConstant buffer_size_const = c.ToInt (Location);
5628                         if (buffer_size_const == null)
5629                                 return false;
5630
5631                         buffer_size = buffer_size_const.Value;
5632
5633                         if (buffer_size <= 0) {
5634                                 Report.Error (1665, Location, "`{0}': Fixed size buffers must have a length greater than zero", GetSignatureForError ());
5635                                 return false;
5636                         }
5637
5638                         int type_size = Expression.GetTypeSize (MemberType);
5639
5640                         if (buffer_size > int.MaxValue / type_size) {
5641                                 Report.Error (1664, Location, "Fixed size buffer `{0}' of length `{1}' and type `{2}' exceeded 2^31 limit",
5642                                         GetSignatureForError (), buffer_size.ToString (), TypeManager.CSharpName (MemberType));
5643                                 return false;
5644                         }
5645
5646                         buffer_size *= type_size;
5647
5648                         // Define nested
5649                         string name = String.Format ("<{0}>__FixedBuffer{1}", Name, GlobalCounter++);
5650
5651                         fixed_buffer_type = Parent.TypeBuilder.DefineNestedType (name,
5652                                 TypeAttributes.NestedPublic | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit, TypeManager.value_type);
5653                         element = fixed_buffer_type.DefineField (FixedElementName, MemberType, FieldAttributes.Public);
5654                         RootContext.RegisterCompilerGeneratedType (fixed_buffer_type);
5655
5656                         FieldBuilder = Parent.TypeBuilder.DefineField (Name, fixed_buffer_type, Modifiers.FieldAttr (ModFlags));
5657                         TypeManager.RegisterFieldBase (FieldBuilder, this);
5658
5659                         return true;
5660                 }
5661
5662                 public override void Emit()
5663                 {
5664                         if (fi == null)
5665                                 fi = new FieldInfo [] { TypeManager.struct_layout_attribute_type.GetField ("Size") };
5666
5667                         object[] fi_val = new object[1];
5668                         fi_val [0] = buffer_size;
5669
5670                         CustomAttributeBuilder cab = new CustomAttributeBuilder (TypeManager.struct_layout_attribute_ctor, 
5671                                 ctor_args, fi, fi_val);
5672                         fixed_buffer_type.SetCustomAttribute (cab);
5673
5674                         cab = new CustomAttributeBuilder (TypeManager.fixed_buffer_attr_ctor, new object[] { MemberType, buffer_size } );
5675                         FieldBuilder.SetCustomAttribute (cab);
5676                         base.Emit ();
5677                 }
5678
5679                 protected override bool IsFieldClsCompliant {
5680                         get {
5681                                 return false;
5682                         }
5683                 }
5684
5685                 #region IFixedField Members
5686
5687                 public FieldInfo Element {
5688                         get {
5689                                 return element;
5690                         }
5691                 }
5692
5693                 public Type ElementType {
5694                         get {
5695                                 return MemberType;
5696                         }
5697                 }
5698
5699                 #endregion
5700         }
5701
5702         //
5703         // The Field class is used to represents class/struct fields during parsing.
5704         //
5705         public class Field : FieldMember {
5706                 // <summary>
5707                 //   Modifiers allowed in a class declaration
5708                 // </summary>
5709                 const int AllowedModifiers =
5710                         Modifiers.NEW |
5711                         Modifiers.PUBLIC |
5712                         Modifiers.PROTECTED |
5713                         Modifiers.INTERNAL |
5714                         Modifiers.PRIVATE |
5715                         Modifiers.STATIC |
5716                         Modifiers.VOLATILE |
5717                         Modifiers.UNSAFE |
5718                         Modifiers.READONLY;
5719
5720                 public Field (DeclSpace parent, Expression type, int mod, string name,
5721                               Attributes attrs, Location loc)
5722                         : base (parent, type, mod, AllowedModifiers, new MemberName (name, loc),
5723                                 attrs)
5724                 {
5725                 }
5726
5727                 public override bool Define ()
5728                 {
5729                         if (!base.Define ())
5730                                 return false;
5731
5732                         if (RootContext.WarningLevel > 1){
5733                                 Type ptype = Parent.TypeBuilder.BaseType;
5734
5735                                 // ptype is only null for System.Object while compiling corlib.
5736                                 if (ptype != null){
5737                                         TypeContainer.FindMembers (
5738                                                 ptype, MemberTypes.Method,
5739                                                 BindingFlags.Public |
5740                                                 BindingFlags.Static | BindingFlags.Instance,
5741                                                 System.Type.FilterName, Name);
5742                                 }
5743                         }
5744
5745                         if ((ModFlags & Modifiers.VOLATILE) != 0){
5746                                 if (!MemberType.IsClass){
5747                                         Type vt = MemberType;
5748                                         
5749                                         if (TypeManager.IsEnumType (vt))
5750                                                 vt = TypeManager.EnumToUnderlying (MemberType);
5751
5752                                         if (!((vt == TypeManager.bool_type) ||
5753                                               (vt == TypeManager.sbyte_type) ||
5754                                               (vt == TypeManager.byte_type) ||
5755                                               (vt == TypeManager.short_type) ||
5756                                               (vt == TypeManager.ushort_type) ||
5757                                               (vt == TypeManager.int32_type) ||
5758                                               (vt == TypeManager.uint32_type) ||    
5759                                               (vt == TypeManager.char_type) ||
5760                                               (vt == TypeManager.float_type) ||
5761                                               (!vt.IsValueType))){
5762                                                 Report.Error (677, Location, "`{0}': A volatile field cannot be of the type `{1}'",
5763                                                         GetSignatureForError (), TypeManager.CSharpName (vt));
5764                                                 return false;
5765                                         }
5766                                 }
5767
5768                                 if ((ModFlags & Modifiers.READONLY) != 0){
5769                                         Report.Error (678, Location, "`{0}': A field cannot be both volatile and readonly",
5770                                                 GetSignatureForError ());
5771                                         return false;
5772                                 }
5773                         }
5774
5775                         FieldAttributes fa = Modifiers.FieldAttr (ModFlags);
5776
5777                         if (ParentContainer.Kind == Kind.Struct && 
5778                             ((fa & FieldAttributes.Static) == 0) &&
5779                             MemberType == Parent.TypeBuilder &&
5780                             !TypeManager.IsBuiltinType (MemberType)){
5781                                 Report.Error (523, Location, "Struct member `" + Parent.Name + "." + Name + 
5782                                               "' causes a cycle in the structure layout");
5783                                 return false;
5784                         }
5785
5786                         try {
5787                                 FieldBuilder = Parent.TypeBuilder.DefineField (
5788                                         Name, MemberType, Modifiers.FieldAttr (ModFlags));
5789
5790                         TypeManager.RegisterFieldBase (FieldBuilder, this);
5791                         }
5792                         catch (ArgumentException) {
5793                                 Report.Warning (-24, 1, Location, "The Microsoft runtime is unable to use [void|void*] as a field type, try using the Mono runtime.");
5794                                 return false;
5795                         }
5796
5797                         return true;
5798                 }
5799
5800                 protected override bool VerifyClsCompliance ()
5801                 {
5802                         if (!base.VerifyClsCompliance ())
5803                                 return false;
5804
5805                         if ((ModFlags & Modifiers.VOLATILE) != 0) {
5806                                 Report.Warning (3026, 1, Location, "CLS-compliant field `{0}' cannot be volatile", GetSignatureForError ());
5807                         }
5808
5809                         return true;
5810                 }
5811         }
5812
5813         //
5814         // `set' and `get' accessors are represented with an Accessor.
5815         // 
5816         public class Accessor : IIteratorContainer {
5817                 //
5818                 // Null if the accessor is empty, or a Block if not
5819                 //
5820                 public const int AllowedModifiers = 
5821                         Modifiers.PUBLIC |
5822                         Modifiers.PROTECTED |
5823                         Modifiers.INTERNAL |
5824                         Modifiers.PRIVATE;
5825                 
5826                 public ToplevelBlock Block;
5827                 public Attributes Attributes;
5828                 public Location Location;
5829                 public int ModFlags;
5830                 public bool Yields;
5831                 
5832                 public Accessor (ToplevelBlock b, int mod, Attributes attrs, Location loc)
5833                 {
5834                         Block = b;
5835                         Attributes = attrs;
5836                         Location = loc;
5837                         ModFlags = Modifiers.Check (AllowedModifiers, mod, 0, loc);
5838                 }
5839
5840                 public void SetYields ()
5841                 {
5842                         Yields = true;
5843                 }
5844         }
5845
5846         // Ooouh Martin, templates are missing here.
5847         // When it will be possible move here a lot of child code and template method type.
5848         public abstract class AbstractPropertyEventMethod : MemberCore, IMethodData {
5849                 protected MethodData method_data;
5850                 protected ToplevelBlock block;
5851                 protected ListDictionary declarative_security;
5852
5853                 // The accessor are created event if they are not wanted.
5854                 // But we need them because their names are reserved.
5855                 // Field says whether accessor will be emited or not
5856                 public readonly bool IsDummy;
5857
5858                 protected readonly string prefix;
5859
5860                 ReturnParameter return_attributes;
5861
5862                 public AbstractPropertyEventMethod (MemberBase member, string prefix)
5863                         : base (member.Parent, SetupName (prefix, member, member.Location), null)
5864                 {
5865                         this.prefix = prefix;
5866                         IsDummy = true;
5867                 }
5868
5869                 public AbstractPropertyEventMethod (MemberBase member, Accessor accessor,
5870                                                     string prefix)
5871                         : base (member.Parent, SetupName (prefix, member, accessor.Location),
5872                                 accessor.Attributes)
5873                 {
5874                         this.prefix = prefix;
5875                         this.block = accessor.Block;
5876                 }
5877
5878                 static MemberName SetupName (string prefix, MemberBase member, Location loc)
5879                 {
5880                         return new MemberName (member.MemberName.Left, prefix + member.ShortName, loc);
5881                 }
5882
5883                 public void UpdateName (MemberBase member)
5884                 {
5885                         SetMemberName (SetupName (prefix, member, Location));
5886                 }
5887
5888                 #region IMethodData Members
5889
5890                 public ToplevelBlock Block {
5891                         get {
5892                                 return block;
5893                         }
5894
5895                         set {
5896                                 block = value;
5897                         }
5898                 }
5899
5900                 public CallingConventions CallingConventions {
5901                         get {
5902                                 return CallingConventions.Standard;
5903                         }
5904                 }
5905
5906                 public bool IsExcluded ()
5907                 {
5908                         return false;
5909                 }
5910
5911                 GenericMethod IMethodData.GenericMethod {
5912                         get {
5913                                 return null;
5914                         }
5915                 }
5916
5917                 public MemberName MethodName {
5918                         get {
5919                                 return MemberName;
5920                         }
5921                 }
5922
5923                 public Type[] ParameterTypes { 
5924                         get {
5925                                 return ParameterInfo.Types;
5926                         }
5927                 }
5928
5929                 public abstract Parameters ParameterInfo { get ; }
5930                 public abstract Type ReturnType { get; }
5931                 public abstract EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig);
5932
5933                 #endregion
5934
5935                 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
5936                 {
5937                         if (a.Type == TypeManager.cls_compliant_attribute_type || a.Type == TypeManager.obsolete_attribute_type ||
5938                                         a.Type == TypeManager.conditional_attribute_type) {
5939                                 Report.Error (1667, a.Location,
5940                                         "Attribute `{0}' is not valid on property or event accessors. It is valid on `{1}' declarations only",
5941                                         TypeManager.CSharpName (a.Type), a.GetValidTargets ());
5942                                 return;
5943                         }
5944
5945                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
5946                                 if (declarative_security == null)
5947                                         declarative_security = new ListDictionary ();
5948                                 a.ExtractSecurityPermissionSet (declarative_security);
5949                                 return;
5950                         }
5951
5952                         if (a.Target == AttributeTargets.Method) {
5953                                 method_data.MethodBuilder.SetCustomAttribute (cb);
5954                                 return;
5955                         }
5956
5957                         if (a.Target == AttributeTargets.ReturnValue) {
5958                                 if (return_attributes == null)
5959                                         return_attributes = new ReturnParameter (method_data.MethodBuilder, Location);
5960
5961                                 return_attributes.ApplyAttributeBuilder (a, cb);
5962                                 return;
5963                         }
5964
5965                         ApplyToExtraTarget (a, cb);
5966                 }
5967
5968                 virtual protected void ApplyToExtraTarget (Attribute a, CustomAttributeBuilder cb)
5969                 {
5970                         System.Diagnostics.Debug.Fail ("You forgot to define special attribute target handling");
5971                 }
5972
5973                 public override bool Define()
5974                 {
5975                         throw new NotSupportedException ();
5976                 }
5977
5978                 public void Emit (DeclSpace parent)
5979                 {
5980                         EmitMethod (parent);
5981
5982                         if (OptAttributes != null)
5983                                 OptAttributes.Emit ();
5984
5985                         if (declarative_security != null) {
5986                                 foreach (DictionaryEntry de in declarative_security) {
5987                                         method_data.MethodBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
5988                                 }
5989                         }
5990
5991                         block = null;
5992                 }
5993
5994                 protected virtual void EmitMethod (DeclSpace parent)
5995                 {
5996                         method_data.Emit (parent);
5997                 }
5998
5999                 public override bool IsClsComplianceRequired()
6000                 {
6001                         return false;
6002                 }
6003
6004                 public bool IsDuplicateImplementation (MethodCore method)
6005                 {
6006                         if (!MemberName.Equals (method.MemberName))
6007                                 return false;
6008
6009                         Type[] param_types = method.ParameterTypes;
6010
6011                         if (param_types.Length != ParameterTypes.Length)
6012                                 return false;
6013
6014                         for (int i = 0; i < param_types.Length; i++)
6015                                 if (param_types [i] != ParameterTypes [i])
6016                                         return false;
6017
6018                         Report.SymbolRelatedToPreviousError (method);
6019                         Report.Error (111, Location, TypeContainer.Error111, method.GetSignatureForError ());
6020                         return true;
6021                 }
6022
6023                 public override bool IsUsed
6024                 {
6025                         get {
6026                                 if (IsDummy)
6027                                         return false;
6028
6029                                 return base.IsUsed;
6030                         }
6031                 }
6032
6033                 public new Location Location { 
6034                         get {
6035                                 return base.Location;
6036                         }
6037                 }
6038
6039                 //
6040                 //   Represents header string for documentation comment.
6041                 //
6042                 public override string DocCommentHeader {
6043                         get { throw new InvalidOperationException ("Unexpected attempt to get doc comment from " + this.GetType () + "."); }
6044                 }
6045
6046         }
6047
6048         //
6049         // Properties and Indexers both generate PropertyBuilders, we use this to share 
6050         // their common bits.
6051         //
6052         abstract public class PropertyBase : MethodCore {
6053
6054                 public class GetMethod : PropertyMethod
6055                 {
6056                         static string[] attribute_targets = new string [] { "method", "return" };
6057
6058                         public GetMethod (MethodCore method):
6059                                 base (method, "get_")
6060                         {
6061                         }
6062
6063                         public GetMethod (MethodCore method, Accessor accessor):
6064                                 base (method, accessor, "get_")
6065                         {
6066                         }
6067
6068                         public override MethodBuilder Define (DeclSpace parent)
6069                         {
6070                                 base.Define (parent);
6071                                 
6072                                 method_data = new MethodData (method, ModFlags, flags, this);
6073
6074                                 if (!method_data.Define (parent))
6075                                         return null;
6076
6077                                 return method_data.MethodBuilder;
6078                         }
6079
6080                         public override Type ReturnType {
6081                                 get {
6082                                         return method.MemberType;
6083                                 }
6084                         }
6085
6086                         public override Parameters ParameterInfo {
6087                                 get {
6088                                         return Parameters.EmptyReadOnlyParameters;
6089                                 }
6090                         }
6091
6092                         public override string[] ValidAttributeTargets {
6093                                 get {
6094                                         return attribute_targets;
6095                                 }
6096                         }
6097                 }
6098
6099                 public class SetMethod : PropertyMethod {
6100
6101                         static string[] attribute_targets = new string [] { "method", "param", "return" };
6102                         ImplicitParameter param_attr;
6103                         protected Parameters parameters;
6104
6105                         public SetMethod (MethodCore method):
6106                                 base (method, "set_")
6107                         {
6108                         }
6109
6110                         public SetMethod (MethodCore method, Accessor accessor):
6111                                 base (method, accessor, "set_")
6112                         {
6113                         }
6114
6115                         protected override void ApplyToExtraTarget(Attribute a, CustomAttributeBuilder cb)
6116                         {
6117                                 if (a.Target == AttributeTargets.Parameter) {
6118                                         if (param_attr == null)
6119                                                 param_attr = new ImplicitParameter (method_data.MethodBuilder);
6120
6121                                         param_attr.ApplyAttributeBuilder (a, cb);
6122                                         return;
6123                                 }
6124
6125                                 base.ApplyAttributeBuilder (a, cb);
6126                         }
6127
6128                         public override Parameters ParameterInfo {
6129                                 get {
6130                                         return parameters;
6131                                 }
6132                         }
6133
6134                         protected virtual void DefineParameters ()
6135                         {
6136                                 parameters = new Parameters (
6137                                         new Parameter[] { new Parameter (method.MemberType, "value", Parameter.Modifier.NONE, null, Location) },
6138                                         new Type[] { method.MemberType });
6139                         }
6140
6141                         public override MethodBuilder Define (DeclSpace parent)
6142                         {
6143                                 DefineParameters ();
6144                                 if (IsDummy)
6145                                         return null;
6146
6147                                 base.Define (parent);
6148
6149                                 method_data = new MethodData (method, ModFlags, flags, this);
6150
6151                                 if (!method_data.Define (parent))
6152                                         return null;
6153
6154                                 return method_data.MethodBuilder;
6155                         }
6156
6157                         public override Type ReturnType {
6158                                 get {
6159                                         return TypeManager.void_type;
6160                                 }
6161                         }
6162
6163                         public override string[] ValidAttributeTargets {
6164                                 get {
6165                                         return attribute_targets;
6166                                 }
6167                         }
6168                 }
6169
6170                 static string[] attribute_targets = new string [] { "property" };
6171
6172                 public abstract class PropertyMethod : AbstractPropertyEventMethod
6173                 {
6174                         protected readonly MethodCore method;
6175                         protected MethodAttributes flags;
6176                         bool yields;
6177
6178                         public PropertyMethod (MethodCore method, string prefix)
6179                                 : base (method, prefix)
6180                         {
6181                                 this.method = method;
6182                         }
6183
6184                         public PropertyMethod (MethodCore method, Accessor accessor,
6185                                                string prefix)
6186                                 : base (method, accessor, prefix)
6187                         {
6188                                 this.method = method;
6189                                 this.ModFlags = accessor.ModFlags;
6190                                 yields = accessor.Yields;
6191
6192                                 if (accessor.ModFlags != 0 && RootContext.Version == LanguageVersion.ISO_1) {
6193                                         Report.FeatureIsNotStandardized (Location, "access modifiers on properties");
6194                                 }
6195                         }
6196
6197                         public override AttributeTargets AttributeTargets {
6198                                 get {
6199                                         return AttributeTargets.Method;
6200                                 }
6201                         }
6202
6203                         public override bool IsClsComplianceRequired ()
6204                         {
6205                                 return method.IsClsComplianceRequired ();
6206                         }
6207
6208                         public virtual MethodBuilder Define (DeclSpace parent)
6209                         {
6210                                 if (!method.CheckAbstractAndExtern (block != null))
6211                                         return null;
6212
6213                                 TypeContainer container = ((TypeContainer) parent).PartialContainer;
6214
6215                                 //
6216                                 // Check for custom access modifier
6217                                 //
6218                                 if (ModFlags == 0) {
6219                                         ModFlags = method.ModFlags;
6220                                         flags = method.flags;
6221                                 } else {
6222                                         if (container.Kind == Kind.Interface)
6223                                                 Report.Error (275, Location, "`{0}': accessibility modifiers may not be used on accessors in an interface",
6224                                                         GetSignatureForError ());
6225
6226                                         if ((method.ModFlags & Modifiers.ABSTRACT) != 0 && (ModFlags & Modifiers.PRIVATE) != 0) {
6227                                                 Report.Error (442, Location, "`{0}': abstract properties cannot have private accessors", GetSignatureForError ());
6228                                         }
6229
6230                                         CheckModifiers (ModFlags);
6231                                         ModFlags |= (method.ModFlags & (~Modifiers.Accessibility));
6232                                         ModFlags |= Modifiers.PROPERTY_CUSTOM;
6233                                         flags = Modifiers.MethodAttr (ModFlags);
6234                                         flags |= (method.flags & (~MethodAttributes.MemberAccessMask));
6235                                 }
6236
6237                                 //
6238                                 // Setup iterator if we are one
6239                                 //
6240                                 if (yields) {
6241                                         Iterator iterator = new Iterator (this, Parent as TypeContainer, null, ModFlags);
6242                                         
6243                                         if (!iterator.DefineIterator ())
6244                                                 return null;
6245                                 }
6246
6247                                 return null;
6248                         }
6249
6250                         public bool HasCustomAccessModifier
6251                         {
6252                                 get {
6253                                         return (ModFlags & Modifiers.PROPERTY_CUSTOM) != 0;
6254                                 }
6255                         }
6256
6257                         public override EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig)
6258                         {
6259                                 return new EmitContext (method,
6260                                         ds, method.ds, method.Location, ig, ReturnType,
6261                                         method.ModFlags, false);
6262                         }
6263
6264                         public override ObsoleteAttribute GetObsoleteAttribute ()
6265                         {
6266                                 return method.GetObsoleteAttribute ();
6267                         }
6268
6269                         public override string GetSignatureForError()
6270                         {
6271                                 return method.GetSignatureForError () + '.' + prefix.Substring (0, 3);
6272                         }
6273
6274                         void CheckModifiers (int modflags)
6275                         {
6276                                 int flags = 0;
6277                                 int mflags = method.ModFlags & Modifiers.Accessibility;
6278
6279                                 if ((mflags & Modifiers.PUBLIC) != 0) {
6280                                         flags |= Modifiers.PROTECTED | Modifiers.INTERNAL | Modifiers.PRIVATE;
6281                                 }
6282                                 else if ((mflags & Modifiers.PROTECTED) != 0) {
6283                                         if ((mflags & Modifiers.INTERNAL) != 0)
6284                                                 flags |= Modifiers.PROTECTED | Modifiers.INTERNAL;
6285
6286                                         flags |= Modifiers.PRIVATE;
6287                                 }
6288                                 else if ((mflags & Modifiers.INTERNAL) != 0)
6289                                         flags |= Modifiers.PRIVATE;
6290
6291                                 if ((mflags == modflags) || (modflags & (~flags)) != 0) {
6292                                         Report.Error (273, Location,
6293                                                 "The accessibility modifier of the `{0}' accessor must be more restrictive than the modifier of the property or indexer `{1}'",
6294                                                 GetSignatureForError (), method.GetSignatureForError ());
6295                                 }
6296                         }
6297
6298                         public override bool MarkForDuplicationCheck ()
6299                         {
6300                                 caching_flags |= Flags.TestMethodDuplication;
6301                                 return true;
6302                         }
6303                 }
6304
6305                 public PropertyMethod Get, Set;
6306                 public PropertyBuilder PropertyBuilder;
6307                 public MethodBuilder GetBuilder, SetBuilder;
6308
6309                 protected EmitContext ec;
6310
6311                 public PropertyBase (DeclSpace parent, Expression type, int mod_flags,
6312                                      int allowed_mod, bool is_iface, MemberName name,
6313                                      Parameters parameters, Attributes attrs)
6314                         : base (parent, null, type, mod_flags, allowed_mod, is_iface, name,
6315                                 attrs, parameters)
6316                 {
6317                 }
6318
6319                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
6320                 {
6321                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
6322                                 a.Error_InvalidSecurityParent ();
6323                                 return;
6324                         }
6325
6326                         PropertyBuilder.SetCustomAttribute (cb);
6327                 }
6328
6329                 public override AttributeTargets AttributeTargets {
6330                         get {
6331                                 return AttributeTargets.Property;
6332                         }
6333                 }
6334
6335                 public override bool Define ()
6336                 {
6337                         if (!DoDefine ())
6338                                 return false;
6339
6340                         if (!IsTypePermitted ())
6341                                 return false;
6342
6343                         return true;
6344                 }
6345
6346                 protected override bool DoDefine ()
6347                 {
6348                         if (!base.DoDefine ())
6349                                 return false;
6350
6351                         //
6352                         // Accessors modifiers check
6353                         //
6354                         if (Get.ModFlags != 0 && Set.ModFlags != 0) {
6355                                 Report.Error (274, Location, "`{0}': Cannot specify accessibility modifiers for both accessors of the property or indexer",
6356                                                 GetSignatureForError ());
6357                                 return false;
6358                         }
6359
6360                         if ((Get.IsDummy || Set.IsDummy)
6361                                         && (Get.ModFlags != 0 || Set.ModFlags != 0) && (ModFlags & Modifiers.OVERRIDE) == 0) {
6362                                 Report.Error (276, Location, 
6363                                         "`{0}': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor",
6364                                         GetSignatureForError ());
6365                                 return false;
6366                         }
6367
6368                         if (MemberType.IsAbstract && MemberType.IsSealed) {
6369                                 Report.Error (722, Location, Error722, TypeManager.CSharpName (MemberType));
6370                                 return false;
6371                         }
6372
6373                         ec = new EmitContext (this, Parent, Location, null, MemberType, ModFlags);
6374                         return true;
6375                 }
6376
6377                 protected override bool CheckForDuplications ()
6378                 {
6379                         ArrayList ar = ParentContainer.Indexers;
6380                         if (ar != null) {
6381                                 int arLen = ar.Count;
6382                                         
6383                                 for (int i = 0; i < arLen; i++) {
6384                                         Indexer m = (Indexer) ar [i];
6385                                         if (IsDuplicateImplementation (m))
6386                                                 return false;
6387                                 }
6388                         }
6389
6390                         ar = ParentContainer.Properties;
6391                         if (ar != null) {
6392                                 int arLen = ar.Count;
6393                                         
6394                                 for (int i = 0; i < arLen; i++) {
6395                                         Property m = (Property) ar [i];
6396                                         if (IsDuplicateImplementation (m))
6397                                                 return false;
6398                                 }
6399                         }
6400
6401                         return true;
6402                 }
6403
6404                 // TODO: rename to Resolve......
6405                 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
6406                 {
6407                         PropertyInfo base_property = ParentContainer.BaseCache.FindMemberToOverride (
6408                                 Parent.TypeBuilder, Name, ParameterTypes, null, true) as PropertyInfo;
6409
6410                         if (base_property == null)
6411                                 return null;
6412
6413                         base_ret_type = base_property.PropertyType;
6414                         MethodInfo get_accessor = base_property.GetGetMethod (true);
6415                         MethodInfo set_accessor = base_property.GetSetMethod (true);
6416                         MethodAttributes get_accessor_access, set_accessor_access;
6417
6418                         if ((ModFlags & Modifiers.OVERRIDE) != 0) {
6419                                 if (Get != null && !Get.IsDummy && get_accessor == null) {
6420                                         Report.SymbolRelatedToPreviousError (base_property);
6421                                         Report.Error (545, Location, "`{0}.get': cannot override because `{1}' does not have an overridable get accessor", GetSignatureForError (), TypeManager.GetFullNameSignature (base_property));
6422                                 }
6423
6424                                 if (Set != null && !Set.IsDummy && set_accessor == null) {
6425                                         Report.SymbolRelatedToPreviousError (base_property);
6426                                         Report.Error (546, Location, "`{0}.set': cannot override because `{1}' does not have an overridable set accessor", GetSignatureForError (), TypeManager.GetFullNameSignature (base_property));
6427                                 }
6428                         }
6429                         
6430                         //
6431                         // Check base class accessors access
6432                         //
6433
6434                         // TODO: rewrite to reuse Get|Set.CheckAccessModifiers and share code there
6435                         get_accessor_access = set_accessor_access = 0;
6436                         if ((ModFlags & Modifiers.NEW) == 0) {
6437                                 if (get_accessor != null) {
6438                                         MethodAttributes get_flags = Modifiers.MethodAttr (Get.ModFlags != 0 ? Get.ModFlags : ModFlags);
6439                                         get_accessor_access = (get_accessor.Attributes & MethodAttributes.MemberAccessMask);
6440
6441                                         if (!Get.IsDummy && !CheckAccessModifiers (get_flags & MethodAttributes.MemberAccessMask, get_accessor_access, get_accessor))
6442                                                 Error_CannotChangeAccessModifiers (get_accessor, get_accessor_access,  ".get");
6443                                 }
6444
6445                                 if (set_accessor != null)  {
6446                                         MethodAttributes set_flags = Modifiers.MethodAttr (Set.ModFlags != 0 ? Set.ModFlags : ModFlags);
6447                                         set_accessor_access = (set_accessor.Attributes & MethodAttributes.MemberAccessMask);
6448
6449                                         if (!Set.IsDummy && !CheckAccessModifiers (set_flags & MethodAttributes.MemberAccessMask, set_accessor_access, set_accessor))
6450                                                 Error_CannotChangeAccessModifiers (set_accessor, set_accessor_access, ".set");
6451                                 }
6452                         }
6453
6454                         //
6455                         // Get the less restrictive access
6456                         //
6457                         return get_accessor_access > set_accessor_access ? get_accessor : set_accessor;
6458                 }
6459
6460                 public override void Emit ()
6461                 {
6462                         //
6463                         // The PropertyBuilder can be null for explicit implementations, in that
6464                         // case, we do not actually emit the ".property", so there is nowhere to
6465                         // put the attribute
6466                         //
6467                         if (PropertyBuilder != null && OptAttributes != null)
6468                                 OptAttributes.Emit ();
6469
6470                         if (!Get.IsDummy)
6471                                 Get.Emit (Parent);
6472
6473                         if (!Set.IsDummy)
6474                                 Set.Emit (Parent);
6475
6476                         base.Emit ();
6477                 }
6478
6479                 /// <summary>
6480                 /// Tests whether accessors are not in collision with some method (CS0111)
6481                 /// </summary>
6482                 public bool AreAccessorsDuplicateImplementation (MethodCore mc)
6483                 {
6484                         return Get.IsDuplicateImplementation (mc) || Set.IsDuplicateImplementation (mc);
6485                 }
6486
6487                 public override bool IsUsed
6488                 {
6489                         get {
6490                                 if (IsExplicitImpl)
6491                                         return true;
6492
6493                                 return Get.IsUsed | Set.IsUsed;
6494                         }
6495                 }
6496
6497                 protected override void SetMemberName (MemberName new_name)
6498                 {
6499                         base.SetMemberName (new_name);
6500
6501                         Get.UpdateName (this);
6502                         Set.UpdateName (this);
6503                 }
6504
6505                 public override string[] ValidAttributeTargets {
6506                         get {
6507                                 return attribute_targets;
6508                         }
6509                 }
6510
6511                 //
6512                 //   Represents header string for documentation comment.
6513                 //
6514                 public override string DocCommentHeader {
6515                         get { return "P:"; }
6516                 }
6517         }
6518                         
6519         public class Property : PropertyBase {
6520                 const int AllowedModifiers =
6521                         Modifiers.NEW |
6522                         Modifiers.PUBLIC |
6523                         Modifiers.PROTECTED |
6524                         Modifiers.INTERNAL |
6525                         Modifiers.PRIVATE |
6526                         Modifiers.STATIC |
6527                         Modifiers.SEALED |
6528                         Modifiers.OVERRIDE |
6529                         Modifiers.ABSTRACT |
6530                         Modifiers.UNSAFE |
6531                         Modifiers.EXTERN |
6532                         Modifiers.METHOD_YIELDS |
6533                         Modifiers.VIRTUAL;
6534
6535                 const int AllowedInterfaceModifiers =
6536                         Modifiers.NEW;
6537
6538                 public Property (DeclSpace parent, Expression type, int mod, bool is_iface,
6539                                  MemberName name, Attributes attrs, Accessor get_block,
6540                                  Accessor set_block)
6541                         : base (parent, type, mod,
6542                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
6543                                 is_iface, name, Parameters.EmptyReadOnlyParameters, attrs)
6544                 {
6545                         if (get_block == null)
6546                                 Get = new GetMethod (this);
6547                         else
6548                                 Get = new GetMethod (this, get_block);
6549
6550                         if (set_block == null)
6551                                 Set = new SetMethod (this);
6552                         else
6553                                 Set = new SetMethod (this, set_block);
6554                 }
6555
6556                 public override bool Define ()
6557                 {
6558                         if (!DoDefineBase ())
6559                                 return false;
6560
6561                         if (!base.Define ())
6562                                 return false;
6563
6564                         if (!CheckBase ())
6565                                 return false;
6566
6567                         flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
6568
6569                         if (!Get.IsDummy) {
6570                                 GetBuilder = Get.Define (Parent);
6571                                 if (GetBuilder == null)
6572                                         return false;
6573                         }
6574
6575                         SetBuilder = Set.Define (Parent);
6576                         if (!Set.IsDummy) {
6577                                 if (SetBuilder == null)
6578                                         return false;
6579                         }
6580
6581                         // FIXME - PropertyAttributes.HasDefault ?
6582
6583                         PropertyBuilder = Parent.TypeBuilder.DefineProperty (
6584                                 MemberName.ToString (), PropertyAttributes.None, MemberType, null);
6585
6586                         if (!Get.IsDummy)
6587                                 PropertyBuilder.SetGetMethod (GetBuilder);
6588
6589                         if (!Set.IsDummy)
6590                                 PropertyBuilder.SetSetMethod (SetBuilder);
6591
6592                         TypeManager.RegisterProperty (PropertyBuilder, this);
6593                         return true;
6594                 }
6595         }
6596
6597         /// </summary>
6598         ///  Gigantic workaround  for lameness in SRE follows :
6599         ///  This class derives from EventInfo and attempts to basically
6600         ///  wrap around the EventBuilder so that FindMembers can quickly
6601         ///  return this in it search for members
6602         /// </summary>
6603         public class MyEventBuilder : EventInfo {
6604                 
6605                 //
6606                 // We use this to "point" to our Builder which is
6607                 // not really a MemberInfo
6608                 //
6609                 EventBuilder MyBuilder;
6610                 
6611                 //
6612                 // We "catch" and wrap these methods
6613                 //
6614                 MethodInfo raise, remove, add;
6615
6616                 EventAttributes attributes;
6617                 Type declaring_type, reflected_type, event_type;
6618                 string name;
6619
6620                 Event my_event;
6621
6622                 public MyEventBuilder (Event ev, TypeBuilder type_builder, string name, EventAttributes event_attr, Type event_type)
6623                 {
6624                         MyBuilder = type_builder.DefineEvent (name, event_attr, event_type);
6625
6626                         // And now store the values in our own fields.
6627                         
6628                         declaring_type = type_builder;
6629
6630                         reflected_type = type_builder;
6631                         
6632                         attributes = event_attr;
6633                         this.name = name;
6634                         my_event = ev;
6635                         this.event_type = event_type;
6636                 }
6637                 
6638                 //
6639                 // Methods that you have to override.  Note that you only need 
6640                 // to "implement" the variants that take the argument (those are
6641                 // the "abstract" methods, the others (GetAddMethod()) are 
6642                 // regular.
6643                 //
6644                 public override MethodInfo GetAddMethod (bool nonPublic)
6645                 {
6646                         return add;
6647                 }
6648                 
6649                 public override MethodInfo GetRemoveMethod (bool nonPublic)
6650                 {
6651                         return remove;
6652                 }
6653                 
6654                 public override MethodInfo GetRaiseMethod (bool nonPublic)
6655                 {
6656                         return raise;
6657                 }
6658                 
6659                 //
6660                 // These methods make "MyEventInfo" look like a Builder
6661                 //
6662                 public void SetRaiseMethod (MethodBuilder raiseMethod)
6663                 {
6664                         raise = raiseMethod;
6665                         MyBuilder.SetRaiseMethod (raiseMethod);
6666                 }
6667
6668                 public void SetRemoveOnMethod (MethodBuilder removeMethod)
6669                 {
6670                         remove = removeMethod;
6671                         MyBuilder.SetRemoveOnMethod (removeMethod);
6672                 }
6673
6674                 public void SetAddOnMethod (MethodBuilder addMethod)
6675                 {
6676                         add = addMethod;
6677                         MyBuilder.SetAddOnMethod (addMethod);
6678                 }
6679
6680                 public void SetCustomAttribute (CustomAttributeBuilder cb)
6681                 {
6682                         MyBuilder.SetCustomAttribute (cb);
6683                 }
6684                 
6685                 public override object [] GetCustomAttributes (bool inherit)
6686                 {
6687                         // FIXME : There's nothing which can be seemingly done here because
6688                         // we have no way of getting at the custom attribute objects of the
6689                         // EventBuilder !
6690                         return null;
6691                 }
6692
6693                 public override object [] GetCustomAttributes (Type t, bool inherit)
6694                 {
6695                         // FIXME : Same here !
6696                         return null;
6697                 }
6698
6699                 public override bool IsDefined (Type t, bool b)
6700                 {
6701                         return true;
6702                 }
6703
6704                 public override EventAttributes Attributes {
6705                         get {
6706                                 return attributes;
6707                         }
6708                 }
6709
6710                 public override string Name {
6711                         get {
6712                                 return name;
6713                         }
6714                 }
6715
6716                 public override Type DeclaringType {
6717                         get {
6718                                 return declaring_type;
6719                         }
6720                 }
6721
6722                 public override Type ReflectedType {
6723                         get {
6724                                 return reflected_type;
6725                         }
6726                 }
6727
6728                 public Type EventType {
6729                         get {
6730                                 return event_type;
6731                         }
6732                 }
6733                 
6734                 public void SetUsed ()
6735                 {
6736                         if (my_event != null) {
6737                                 my_event.SetAssigned ();
6738                                 my_event.SetMemberIsUsed ();
6739                         }
6740                 }
6741         }
6742         
6743         /// <summary>
6744         /// For case when event is declared like property (with add and remove accessors).
6745         /// </summary>
6746         public class EventProperty: Event {
6747
6748                 static string[] attribute_targets = new string [] { "event" }; // "property" target was disabled for 2.0 version
6749
6750                 public EventProperty (DeclSpace parent, Expression type, int mod_flags,
6751                                       bool is_iface, MemberName name,
6752                                       Attributes attrs, Accessor add, Accessor remove)
6753                         : base (parent, type, mod_flags, is_iface, name, attrs)
6754                 {
6755                         Add = new AddDelegateMethod (this, add);
6756                         Remove = new RemoveDelegateMethod (this, remove);
6757
6758                         // For this event syntax we don't report error CS0067
6759                         // because it is hard to do it.
6760                         SetAssigned ();
6761                 }
6762
6763                 public override string[] ValidAttributeTargets {
6764                         get {
6765                                 return attribute_targets;
6766                         }
6767                 }
6768         }
6769
6770         /// <summary>
6771         /// Event is declared like field.
6772         /// </summary>
6773         public class EventField : Event {
6774
6775                 static string[] attribute_targets = new string [] { "event", "field", "method" };
6776                 static string[] attribute_targets_interface = new string[] { "event", "method" };
6777
6778                 public EventField (DeclSpace parent, Expression type, int mod_flags,
6779                                    bool is_iface, MemberName name,
6780                                    Attributes attrs)
6781                         : base (parent, type, mod_flags, is_iface, name, attrs)
6782                 {
6783                         Add = new AddDelegateMethod (this);
6784                         Remove = new RemoveDelegateMethod (this);
6785                 }
6786
6787                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
6788                 {
6789                         if (a.Target == AttributeTargets.Field) {
6790                                 FieldBuilder.SetCustomAttribute (cb);
6791                                 return;
6792                         }
6793
6794                         if (a.Target == AttributeTargets.Method) {
6795                                 Add.ApplyAttributeBuilder (a, cb);
6796                                 Remove.ApplyAttributeBuilder (a, cb);
6797                                 return;
6798                         }
6799
6800                         base.ApplyAttributeBuilder (a, cb);
6801                 }
6802
6803                 public override bool Define()
6804                 {
6805                         if (!base.Define ())
6806                                 return false;
6807
6808                         if (initializer != null) {
6809                                 if (((ModFlags & Modifiers.ABSTRACT) != 0)) {
6810                                         Report.Error (74, Location, "`{0}': abstract event cannot have an initializer",
6811                                                 GetSignatureForError ());
6812                                         return false;
6813                                 }
6814                         }
6815
6816                         return true;
6817                 }
6818
6819                 public override string[] ValidAttributeTargets {
6820                         get {
6821                                 return IsInterface ? attribute_targets_interface : attribute_targets;
6822                         }
6823                 }
6824         }
6825
6826         public abstract class Event : FieldBase {
6827
6828                 protected sealed class AddDelegateMethod: DelegateMethod
6829                 {
6830
6831                         public AddDelegateMethod (Event method):
6832                                 base (method, "add_")
6833                         {
6834                         }
6835
6836                         public AddDelegateMethod (Event method, Accessor accessor):
6837                                 base (method, accessor, "add_")
6838                         {
6839                         }
6840
6841                         protected override MethodInfo DelegateMethodInfo {
6842                                 get {
6843                                         return TypeManager.delegate_combine_delegate_delegate;
6844                                 }
6845                         }
6846
6847                 }
6848
6849                 protected sealed class RemoveDelegateMethod: DelegateMethod
6850                 {
6851                         public RemoveDelegateMethod (Event method):
6852                                 base (method, "remove_")
6853                         {
6854                         }
6855
6856                         public RemoveDelegateMethod (Event method, Accessor accessor):
6857                                 base (method, accessor, "remove_")
6858                         {
6859                         }
6860
6861                         protected override MethodInfo DelegateMethodInfo {
6862                                 get {
6863                                         return TypeManager.delegate_remove_delegate_delegate;
6864                                 }
6865                         }
6866
6867                 }
6868
6869                 public abstract class DelegateMethod : AbstractPropertyEventMethod
6870                 {
6871                         protected readonly Event method;
6872                         ImplicitParameter param_attr;
6873
6874                         static string[] attribute_targets = new string [] { "method", "param", "return" };
6875
6876                         public DelegateMethod (Event method, string prefix)
6877                                 : base (method, prefix)
6878                         {
6879                                 this.method = method;
6880                         }
6881
6882                         public DelegateMethod (Event method, Accessor accessor, string prefix)
6883                                 : base (method, accessor, prefix)
6884                         {
6885                                 this.method = method;
6886                         }
6887
6888                         protected override void ApplyToExtraTarget(Attribute a, CustomAttributeBuilder cb)
6889                         {
6890                                 if (a.Target == AttributeTargets.Parameter) {
6891                                         if (param_attr == null)
6892                                                 param_attr = new ImplicitParameter (method_data.MethodBuilder);
6893
6894                                         param_attr.ApplyAttributeBuilder (a, cb);
6895                                         return;
6896                                 }
6897
6898                                 base.ApplyAttributeBuilder (a, cb);
6899                         }
6900
6901                         public override AttributeTargets AttributeTargets {
6902                                 get {
6903                                         return AttributeTargets.Method;
6904                                 }
6905                         }
6906
6907                         public override bool IsClsComplianceRequired ()
6908                         {
6909                                 return method.IsClsComplianceRequired ();
6910                         }
6911
6912                         public MethodBuilder Define (DeclSpace parent)
6913                         {
6914                                 method_data = new MethodData (method, method.ModFlags,
6915                                         method.flags | MethodAttributes.HideBySig | MethodAttributes.SpecialName, this);
6916
6917                                 if (!method_data.Define (parent))
6918                                         return null;
6919
6920                                 MethodBuilder mb = method_data.MethodBuilder;
6921                                 ParameterInfo.ApplyAttributes (mb);
6922                                 return mb;
6923                         }
6924
6925
6926                         protected override void EmitMethod (DeclSpace parent)
6927                         {
6928                                 if (block != null) {
6929                                         base.EmitMethod (parent);
6930                                         return;
6931                                 }
6932
6933                                 if ((method.ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
6934                                         return;
6935
6936                                 ILGenerator ig = method_data.MethodBuilder.GetILGenerator ();
6937                                 FieldInfo field_info = (FieldInfo)method.FieldBuilder;
6938
6939                                 method_data.MethodBuilder.SetImplementationFlags (MethodImplAttributes.Synchronized);
6940                                 if ((method.ModFlags & Modifiers.STATIC) != 0) {
6941                                         ig.Emit (OpCodes.Ldsfld, field_info);
6942                                         ig.Emit (OpCodes.Ldarg_0);
6943                                         ig.Emit (OpCodes.Call, DelegateMethodInfo);
6944                                         ig.Emit (OpCodes.Castclass, method.MemberType);
6945                                         ig.Emit (OpCodes.Stsfld, field_info);
6946                                 } else {
6947                                         ig.Emit (OpCodes.Ldarg_0);
6948                                         ig.Emit (OpCodes.Ldarg_0);
6949                                         ig.Emit (OpCodes.Ldfld, field_info);
6950                                         ig.Emit (OpCodes.Ldarg_1);
6951                                         ig.Emit (OpCodes.Call, DelegateMethodInfo);
6952                                         ig.Emit (OpCodes.Castclass, method.MemberType);
6953                                         ig.Emit (OpCodes.Stfld, field_info);
6954                                 }
6955                                 ig.Emit (OpCodes.Ret);
6956                         }
6957
6958                         protected abstract MethodInfo DelegateMethodInfo { get; }
6959
6960                         public override Type ReturnType {
6961                                 get {
6962                                         return TypeManager.void_type;
6963                                 }
6964                         }
6965
6966                         public override EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig)
6967                         {
6968                                 return new EmitContext (
6969                                         ds, method.Parent, Location, ig, ReturnType,
6970                                         method.ModFlags, false);
6971                         }
6972
6973                         public override ObsoleteAttribute GetObsoleteAttribute ()
6974                         {
6975                                 return method.GetObsoleteAttribute ();
6976                         }
6977
6978                         public override string[] ValidAttributeTargets {
6979                                 get {
6980                                         return attribute_targets;
6981                                 }
6982                         }
6983
6984                         public override Parameters ParameterInfo {
6985                                 get {
6986                                         return method.parameters;
6987                                 }
6988                         }
6989
6990                 }
6991
6992
6993                 const int AllowedModifiers =
6994                         Modifiers.NEW |
6995                         Modifiers.PUBLIC |
6996                         Modifiers.PROTECTED |
6997                         Modifiers.INTERNAL |
6998                         Modifiers.PRIVATE |
6999                         Modifiers.STATIC |
7000                         Modifiers.VIRTUAL |
7001                         Modifiers.SEALED |
7002                         Modifiers.OVERRIDE |
7003                         Modifiers.UNSAFE |
7004                         Modifiers.ABSTRACT;
7005
7006                 const int AllowedInterfaceModifiers =
7007                         Modifiers.NEW;
7008
7009                 public DelegateMethod Add, Remove;
7010                 public MyEventBuilder     EventBuilder;
7011                 public MethodBuilder AddBuilder, RemoveBuilder;
7012                 Parameters parameters;
7013
7014                 protected Event (DeclSpace parent, Expression type, int mod_flags,
7015                               bool is_iface, MemberName name, Attributes attrs)
7016                         : base (parent, type, mod_flags,
7017                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
7018                                 name, attrs)
7019                 {
7020                         IsInterface = is_iface;
7021                 }
7022
7023                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
7024                 {
7025                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
7026                                 a.Error_InvalidSecurityParent ();
7027                                 return;
7028                         }
7029                         
7030                         EventBuilder.SetCustomAttribute (cb);
7031                 }
7032
7033                 public bool AreAccessorsDuplicateImplementation (MethodCore mc)
7034                 {
7035                         return Add.IsDuplicateImplementation (mc) || Remove.IsDuplicateImplementation (mc);
7036                 }
7037
7038                 public override AttributeTargets AttributeTargets {
7039                         get {
7040                                 return AttributeTargets.Event;
7041                         }
7042                 }
7043   
7044                 public override bool Define ()
7045                 {
7046                         EventAttributes e_attr;
7047                         e_attr = EventAttributes.None;
7048
7049                         if (!DoDefineBase ())
7050                                 return false;
7051
7052                         if (!DoDefine ())
7053                                 return false;
7054
7055                         if (!TypeManager.IsDelegateType (MemberType)) {
7056                                 Report.Error (66, Location, "`{0}': event must be of a delegate type", GetSignatureForError ());
7057                                 return false;
7058                         }
7059
7060                         parameters = new Parameters (
7061                                 new Parameter[] { new Parameter (MemberType, "value", Parameter.Modifier.NONE, null, Location) },
7062                                 new Type[] { MemberType } );
7063
7064                         if (!CheckBase ())
7065                                 return false;
7066
7067                         //
7068                         // Now define the accessors
7069                         //
7070
7071                         AddBuilder = Add.Define (Parent);
7072                         if (AddBuilder == null)
7073                                 return false;
7074
7075                         RemoveBuilder = Remove.Define (Parent);
7076                         if (RemoveBuilder == null)
7077                                 return false;
7078
7079                         EventBuilder = new MyEventBuilder (this, Parent.TypeBuilder, Name, e_attr, MemberType);
7080                         
7081                         if (Add.Block == null && Remove.Block == null && !IsInterface) {
7082                                 FieldBuilder = Parent.TypeBuilder.DefineField (
7083                                         Name, MemberType,
7084                                         FieldAttributes.Private | ((ModFlags & Modifiers.STATIC) != 0 ? FieldAttributes.Static : 0));
7085                                 TypeManager.RegisterPrivateFieldOfEvent (
7086                                         (EventInfo) EventBuilder, FieldBuilder);
7087                                 TypeManager.RegisterFieldBase (FieldBuilder, this);
7088                         }
7089                         
7090                         EventBuilder.SetAddOnMethod (AddBuilder);
7091                         EventBuilder.SetRemoveOnMethod (RemoveBuilder);
7092
7093                         TypeManager.RegisterEvent (EventBuilder, AddBuilder, RemoveBuilder);
7094                         return true;
7095                 }
7096
7097                 protected override bool CheckBase ()
7098                 {
7099                         if (!base.CheckBase ())
7100                                 return false;
7101  
7102                         if (conflict_symbol != null && (ModFlags & Modifiers.NEW) == 0) {
7103                                 if (!(conflict_symbol is EventInfo)) {
7104                                         Report.SymbolRelatedToPreviousError (conflict_symbol);
7105                                         Report.Error (72, Location, "Event `{0}' can override only event", GetSignatureForError ());
7106                                         return false;
7107                                 }
7108                         }
7109  
7110                         return true;
7111                 }
7112
7113                 public override void Emit ()
7114                 {
7115                         if (OptAttributes != null) {
7116                                 OptAttributes.Emit ();
7117                         }
7118
7119                         Add.Emit (Parent);
7120                         Remove.Emit (Parent);
7121
7122                         base.Emit ();
7123                 }
7124
7125                 public override string GetSignatureForError ()
7126                 {
7127                         return base.GetSignatureForError ();
7128                 }
7129
7130                 //
7131                 //   Represents header string for documentation comment.
7132                 //
7133                 public override string DocCommentHeader {
7134                         get { return "E:"; }
7135                 }
7136         }
7137
7138  
7139         public class Indexer : PropertyBase, IIteratorContainer {
7140
7141                 class GetIndexerMethod : GetMethod
7142                 {
7143                         public GetIndexerMethod (MethodCore method):
7144                                 base (method)
7145                         {
7146                         }
7147
7148                         public GetIndexerMethod (MethodCore method, Accessor accessor):
7149                                 base (method, accessor)
7150                         {
7151                         }
7152
7153                         public override Parameters ParameterInfo {
7154                                 get {
7155                                         return method.ParameterInfo;
7156                                 }
7157                         }
7158                 }
7159
7160                 class SetIndexerMethod: SetMethod
7161                 {
7162                         public SetIndexerMethod (MethodCore method):
7163                                 base (method)
7164                         {
7165                         }
7166
7167                         public SetIndexerMethod (MethodCore method, Accessor accessor):
7168                                 base (method, accessor)
7169                         {
7170                         }
7171
7172                         protected override void DefineParameters ()
7173                         {
7174                                 parameters = Parameters.MergeGenerated (method.Parameters,
7175                                         new Parameter (method.MemberType, "value", Parameter.Modifier.NONE, null, method.Location));
7176                         }
7177                 }
7178
7179                 const int AllowedModifiers =
7180                         Modifiers.NEW |
7181                         Modifiers.PUBLIC |
7182                         Modifiers.PROTECTED |
7183                         Modifiers.INTERNAL |
7184                         Modifiers.PRIVATE |
7185                         Modifiers.VIRTUAL |
7186                         Modifiers.SEALED |
7187                         Modifiers.OVERRIDE |
7188                         Modifiers.UNSAFE |
7189                         Modifiers.EXTERN |
7190                         Modifiers.ABSTRACT;
7191
7192                 const int AllowedInterfaceModifiers =
7193                         Modifiers.NEW;
7194
7195                 //
7196                 // Are we implementing an interface ?
7197                 //
7198                 public Indexer (DeclSpace parent, Expression type, MemberName name, int mod,
7199                                 bool is_iface, Parameters parameters, Attributes attrs,
7200                                 Accessor get_block, Accessor set_block)
7201                         : base (parent, type, mod,
7202                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
7203                                 is_iface, name, parameters, attrs)
7204                 {
7205                         if (get_block == null)
7206                                 Get = new GetIndexerMethod (this);
7207                         else
7208                                 Get = new GetIndexerMethod (this, get_block);
7209
7210                         if (set_block == null)
7211                                 Set = new SetIndexerMethod (this);
7212                         else
7213                                 Set = new SetIndexerMethod (this, set_block);
7214                 }
7215                        
7216                 public override bool Define ()
7217                 {
7218                         if (!DoDefineBase ())
7219                                 return false;
7220
7221                         if (!base.Define ())
7222                                 return false;
7223
7224                         if (MemberType == TypeManager.void_type) {
7225                                 Report.Error (620, Location, "Indexers cannot have void type");
7226                                 return false;
7227                         }
7228
7229                         if (OptAttributes != null) {
7230                                 Attribute indexer_attr = OptAttributes.Search (TypeManager.indexer_name_type);
7231                                 if (indexer_attr != null) {
7232                                         // Remove the attribute from the list because it is not emitted
7233                                         OptAttributes.Attrs.Remove (indexer_attr);
7234
7235                                         string name = indexer_attr.GetIndexerAttributeValue ();
7236                                         if (name == null)
7237                                                 return false;
7238
7239                                         ShortName = name;
7240
7241                                         if (IsExplicitImpl) {
7242                                                 Report.Error (415, indexer_attr.Location,
7243                                                               "The `IndexerName' attribute is valid only on an " +
7244                                                               "indexer that is not an explicit interface member declaration");
7245                                                 return false;
7246                                         }
7247
7248                                         if ((ModFlags & Modifiers.OVERRIDE) != 0) {
7249                                                 Report.Error (609, indexer_attr.Location,
7250                                                               "Cannot set the `IndexerName' attribute on an indexer marked override");
7251                                                 return false;
7252                                         }
7253                                 }
7254                         }
7255
7256                         if (InterfaceType != null) {
7257                                 string base_IndexerName = TypeManager.IndexerPropertyName (InterfaceType);
7258                                 if (base_IndexerName != Name)
7259                                         ShortName = base_IndexerName;
7260                         }
7261
7262                         if (!ParentContainer.AddToMemberContainer (this) ||
7263                                 !ParentContainer.AddToMemberContainer (Get) || !ParentContainer.AddToMemberContainer (Set))
7264                                 return false;
7265
7266                         if (!CheckBase ())
7267                                 return false;
7268
7269                         flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
7270                         if (!Get.IsDummy){
7271                                 GetBuilder = Get.Define (Parent);
7272                                 if (GetBuilder == null)
7273                                         return false;
7274
7275                                 //
7276                                 // Setup iterator if we are one
7277                                 //
7278                                 if ((ModFlags & Modifiers.METHOD_YIELDS) != 0){
7279                                         Iterator iterator = new Iterator (
7280                                                 Get, Parent, null, ModFlags);
7281
7282                                         if (!iterator.DefineIterator ())
7283                                                 return false;
7284                                 }
7285                         }
7286                         
7287                         SetBuilder = Set.Define (Parent);
7288                         if (!Set.IsDummy){
7289                                 if (SetBuilder == null)
7290                                         return false;
7291                         }
7292
7293                         //
7294                         // Now name the parameters
7295                         //
7296                         Parameter [] p = Parameters.FixedParameters;
7297                         if (p != null) {
7298                                 // TODO: should be done in parser and it needs to do cycle
7299                                 if ((p [0].ModFlags & Parameter.Modifier.ISBYREF) != 0) {
7300                                         Report.Error (631, Location, "ref and out are not valid in this context");
7301                                         return false;
7302                                 }
7303                         }
7304
7305                         PropertyBuilder = Parent.TypeBuilder.DefineProperty (
7306                                 Name, PropertyAttributes.None, MemberType, ParameterTypes);
7307                         
7308                         if (!Get.IsDummy)
7309                                 PropertyBuilder.SetGetMethod (GetBuilder);
7310
7311                         if (!Set.IsDummy)
7312                                 PropertyBuilder.SetSetMethod (SetBuilder);
7313                                 
7314                         TypeManager.RegisterIndexer (PropertyBuilder, GetBuilder, SetBuilder, ParameterTypes);
7315
7316                         return true;
7317                 }
7318
7319                 public override string GetSignatureForError ()
7320                 {
7321                         StringBuilder sb = new StringBuilder (Parent.GetSignatureForError ());
7322                         if (MemberName.Left != null) {
7323                                 sb.Append ('.');
7324                                 sb.Append (MemberName.Left);
7325                         }
7326
7327                         sb.Append (".this");
7328                         sb.Append (Parameters.GetSignatureForError ().Replace ('(', '[').Replace (')', ']'));
7329                         return sb.ToString ();
7330                 }
7331
7332                 public override bool MarkForDuplicationCheck ()
7333                 {
7334                         caching_flags |= Flags.TestMethodDuplication;
7335                         return true;
7336                 }
7337         }
7338
7339         public class Operator : MethodOrOperator, IIteratorContainer {
7340
7341                 const int AllowedModifiers =
7342                         Modifiers.PUBLIC |
7343                         Modifiers.UNSAFE |
7344                         Modifiers.EXTERN |
7345                         Modifiers.STATIC;
7346
7347                 public enum OpType : byte {
7348
7349                         // Unary operators
7350                         LogicalNot,
7351                         OnesComplement,
7352                         Increment,
7353                         Decrement,
7354                         True,
7355                         False,
7356
7357                         // Unary and Binary operators
7358                         Addition,
7359                         Subtraction,
7360
7361                         UnaryPlus,
7362                         UnaryNegation,
7363                         
7364                         // Binary operators
7365                         Multiply,
7366                         Division,
7367                         Modulus,
7368                         BitwiseAnd,
7369                         BitwiseOr,
7370                         ExclusiveOr,
7371                         LeftShift,
7372                         RightShift,
7373                         Equality,
7374                         Inequality,
7375                         GreaterThan,
7376                         LessThan,
7377                         GreaterThanOrEqual,
7378                         LessThanOrEqual,
7379
7380                         // Implicit and Explicit
7381                         Implicit,
7382                         Explicit,
7383
7384                         // Just because of enum
7385                         TOP
7386                 };
7387
7388                 public readonly OpType OperatorType;
7389                 
7390                 public Operator (DeclSpace parent, OpType type, Expression ret_type,
7391                                  int mod_flags, Parameters parameters,
7392                                  ToplevelBlock block, Attributes attrs, Location loc)
7393                         : base (parent, null, ret_type, mod_flags, AllowedModifiers, false,
7394                                 new MemberName ("op_" + type, loc), attrs, parameters)
7395                 {
7396                         OperatorType = type;
7397                         Block = block;
7398                 }
7399
7400                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb) 
7401                 {
7402                         if (a.Type == TypeManager.conditional_attribute_type) {
7403                                 Error_ConditionalAttributeIsNotValid ();
7404                                 return;
7405                         }
7406
7407                         base.ApplyAttributeBuilder (a, cb);
7408                 }
7409                 
7410                 protected override bool CheckForDuplications ()
7411                 {
7412                         ArrayList ar = ParentContainer.Operators;
7413                         if (ar != null) {
7414                                 int arLen = ar.Count;
7415
7416                                 for (int i = 0; i < arLen; i++) {
7417                                         Operator o = (Operator) ar [i];
7418                                         if (IsDuplicateImplementation (o))
7419                                                 return false;
7420                                 }
7421                         }
7422
7423                         ar = ParentContainer.Methods;
7424                         if (ar != null) {
7425                                 int arLen = ar.Count;
7426
7427                                 for (int i = 0; i < arLen; i++) {
7428                                         Method m = (Method) ar [i];
7429                                         if (IsDuplicateImplementation (m))
7430                                                 return false;
7431                                 }
7432                         }
7433
7434                         return true;
7435                 }
7436
7437                 public override bool Define ()
7438                 {
7439                         const int RequiredModifiers = Modifiers.PUBLIC | Modifiers.STATIC;
7440                         if ((ModFlags & RequiredModifiers) != RequiredModifiers){
7441                                 Report.Error (558, Location, "User-defined operator `{0}' must be declared static and public", GetSignatureForError ());
7442                                 return false;
7443                         }
7444
7445                         if (!base.Define ())
7446                                 return false;
7447
7448                         if (MemberType == TypeManager.void_type) {
7449                                 Report.Error (590, Location, "User-defined operators cannot return void");
7450                                 return false;
7451                         }
7452
7453                         Type declaring_type = MethodData.DeclaringType;
7454                         Type return_type = MemberType;
7455                         Type first_arg_type = ParameterTypes [0];
7456
7457                         // Rules for conversion operators
7458                         
7459                         if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
7460                                 if (first_arg_type == return_type && first_arg_type == declaring_type){
7461                                         Report.Error (555, Location,
7462                                                 "User-defined operator cannot take an object of the enclosing type and convert to an object of the enclosing type");
7463                                         return false;
7464                                 }
7465                                 
7466                                 if (first_arg_type != declaring_type && return_type != declaring_type){
7467                                         Report.Error (
7468                                                 556, Location, 
7469                                                 "User-defined conversion must convert to or from the " +
7470                                                 "enclosing type");
7471                                         return false;
7472                                 }
7473
7474                                 if (first_arg_type.IsInterface || return_type.IsInterface){
7475                                         Report.Error (552, Location, "User-defined conversion `{0}' cannot convert to or from an interface type",
7476                                                 GetSignatureForError ());
7477                                         return false;
7478                                 }
7479                                 
7480                                 if (first_arg_type.IsSubclassOf (return_type) || return_type.IsSubclassOf (first_arg_type)) {
7481                                         if (declaring_type.IsSubclassOf (return_type) || declaring_type.IsSubclassOf (first_arg_type)) {
7482                                                 Report.Error (553, Location, "User-defined conversion `{0}' cannot convert to or from base class",
7483                                                         GetSignatureForError ());
7484                                                 return false;
7485                                         }
7486                                         Report.Error (554, Location, "User-defined conversion `{0}' cannot convert to or from derived class",
7487                                                 GetSignatureForError ());
7488                                         return false;
7489                                 }
7490                         } else if (OperatorType == OpType.LeftShift || OperatorType == OpType.RightShift) {
7491                                 if (first_arg_type != declaring_type || ParameterTypes [1] != TypeManager.int32_type) {
7492                                         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");
7493                                         return false;
7494                                 }
7495                         } else if (Parameters.Count == 1) {
7496                                 // Checks for Unary operators
7497
7498                                 if (OperatorType == OpType.Increment || OperatorType == OpType.Decrement) {
7499                                         if (return_type != declaring_type && !TypeManager.IsSubclassOf (return_type, declaring_type)) {
7500                                                 Report.Error (448, Location,
7501                                                         "The return type for ++ or -- operator must be the containing type or derived from the containing type");
7502                                                 return false;
7503                                         }
7504                                         if (first_arg_type != declaring_type) {
7505                                                 Report.Error (
7506                                                         559, Location, "The parameter type for ++ or -- operator must be the containing type");
7507                                                 return false;
7508                                         }
7509                                 }
7510                                 
7511                                 if (first_arg_type != declaring_type){
7512                                         Report.Error (
7513                                                 562, Location,
7514                                                 "The parameter of a unary operator must be the " +
7515                                                 "containing type");
7516                                         return false;
7517                                 }
7518                                 
7519                                 if (OperatorType == OpType.True || OperatorType == OpType.False) {
7520                                         if (return_type != TypeManager.bool_type){
7521                                                 Report.Error (
7522                                                         215, Location,
7523                                                         "The return type of operator True or False " +
7524                                                         "must be bool");
7525                                                 return false;
7526                                         }
7527                                 }
7528                                 
7529                         } else {
7530                                 // Checks for Binary operators
7531                                 
7532                                 if (first_arg_type != declaring_type &&
7533                                     ParameterTypes [1] != declaring_type){
7534                                         Report.Error (
7535                                                 563, Location,
7536                                                 "One of the parameters of a binary operator must " +
7537                                                 "be the containing type");
7538                                         return false;
7539                                 }
7540                         }
7541
7542                         return true;
7543                 }
7544
7545                 protected override bool DoDefine ()
7546                 {
7547                         if (!base.DoDefine ())
7548                                 return false;
7549
7550                         flags |= MethodAttributes.SpecialName | MethodAttributes.HideBySig;
7551                         return true;
7552                 }
7553                 
7554                 public override void Emit ()
7555                 {
7556                         base.Emit ();
7557
7558                         Parameters.ApplyAttributes (MethodBuilder);
7559
7560                         //
7561                         // abstract or extern methods have no bodies
7562                         //
7563                         if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
7564                                 return;
7565                         
7566                         EmitContext ec;
7567                         if ((flags & MethodAttributes.PinvokeImpl) == 0)
7568                                 ec = CreateEmitContext (Parent, MethodBuilder.GetILGenerator ());
7569                         else
7570                                 ec = CreateEmitContext (Parent, null);
7571                         
7572                         SourceMethod source = SourceMethod.Create (Parent, MethodBuilder, Block);
7573                         ec.EmitTopBlock (this, Block);
7574
7575                         if (source != null)
7576                                 source.CloseMethod ();
7577
7578                         Block = null;
7579                 }
7580
7581                 // Operator cannot be override
7582                 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
7583                 {
7584                         return null;
7585                 }
7586
7587                 public static string GetName (OpType ot)
7588                 {
7589                         switch (ot){
7590                         case OpType.LogicalNot:
7591                                 return "!";
7592                         case OpType.OnesComplement:
7593                                 return "~";
7594                         case OpType.Increment:
7595                                 return "++";
7596                         case OpType.Decrement:
7597                                 return "--";
7598                         case OpType.True:
7599                                 return "true";
7600                         case OpType.False:
7601                                 return "false";
7602                         case OpType.Addition:
7603                                 return "+";
7604                         case OpType.Subtraction:
7605                                 return "-";
7606                         case OpType.UnaryPlus:
7607                                 return "+";
7608                         case OpType.UnaryNegation:
7609                                 return "-";
7610                         case OpType.Multiply:
7611                                 return "*";
7612                         case OpType.Division:
7613                                 return "/";
7614                         case OpType.Modulus:
7615                                 return "%";
7616                         case OpType.BitwiseAnd:
7617                                 return "&";
7618                         case OpType.BitwiseOr:
7619                                 return "|";
7620                         case OpType.ExclusiveOr:
7621                                 return "^";
7622                         case OpType.LeftShift:
7623                                 return "<<";
7624                         case OpType.RightShift:
7625                                 return ">>";
7626                         case OpType.Equality:
7627                                 return "==";
7628                         case OpType.Inequality:
7629                                 return "!=";
7630                         case OpType.GreaterThan:
7631                                 return ">";
7632                         case OpType.LessThan:
7633                                 return "<";
7634                         case OpType.GreaterThanOrEqual:
7635                                 return ">=";
7636                         case OpType.LessThanOrEqual:
7637                                 return "<=";
7638                         case OpType.Implicit:
7639                                 return "implicit";
7640                         case OpType.Explicit:
7641                                 return "explicit";
7642                         default: return "";
7643                         }
7644                 }
7645
7646                 public static OpType GetOperatorType (string name)
7647                 {
7648                         if (name.StartsWith ("op_")){
7649                                 for (int i = 0; i < Unary.oper_names.Length; ++i) {
7650                                         if (Unary.oper_names [i] == name)
7651                                                 return (OpType)i;
7652                                 }
7653
7654                                 for (int i = 0; i < Binary.oper_names.Length; ++i) {
7655                                         if (Binary.oper_names [i] == name)
7656                                                 return (OpType)i;
7657                                 }
7658                         }
7659                         return OpType.TOP;
7660                 }
7661
7662                 public override string GetSignatureForError ()
7663                 {
7664                         StringBuilder sb = new StringBuilder ();
7665                         if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
7666                                 sb.AppendFormat ("{0}.{1} operator {2}", Parent.GetSignatureForError (), GetName (OperatorType), Type.Type == null ? Type.ToString () : TypeManager.CSharpName (Type.Type));
7667                         }
7668                         else {
7669                                 sb.AppendFormat ("{0}.operator {1}", Parent.GetSignatureForError (), GetName (OperatorType));
7670                         }
7671
7672                         sb.Append (Parameters.GetSignatureForError ());
7673                         return sb.ToString ();
7674                 }
7675         }
7676
7677         //
7678         // This is used to compare method signatures
7679         //
7680         struct MethodSignature {
7681                 public string Name;
7682                 public Type RetType;
7683                 public Type [] Parameters;
7684                 
7685                 /// <summary>
7686                 ///    This delegate is used to extract methods which have the
7687                 ///    same signature as the argument
7688                 /// </summary>
7689                 public static MemberFilter method_signature_filter = new MemberFilter (MemberSignatureCompare);
7690                 
7691                 public MethodSignature (string name, Type ret_type, Type [] parameters)
7692                 {
7693                         Name = name;
7694                         RetType = ret_type;
7695
7696                         if (parameters == null)
7697                                 Parameters = Type.EmptyTypes;
7698                         else
7699                                 Parameters = parameters;
7700                 }
7701
7702                 public override string ToString ()
7703                 {
7704                         string pars = "";
7705                         if (Parameters.Length != 0){
7706                                 System.Text.StringBuilder sb = new System.Text.StringBuilder ();
7707                                 for (int i = 0; i < Parameters.Length; i++){
7708                                         sb.Append (Parameters [i]);
7709                                         if (i+1 < Parameters.Length)
7710                                                 sb.Append (", ");
7711                                 }
7712                                 pars = sb.ToString ();
7713                         }
7714
7715                         return String.Format ("{0} {1} ({2})", RetType, Name, pars);
7716                 }
7717                 
7718                 public override int GetHashCode ()
7719                 {
7720                         return Name.GetHashCode ();
7721                 }
7722
7723                 public override bool Equals (Object o)
7724                 {
7725                         MethodSignature other = (MethodSignature) o;
7726
7727                         if (other.Name != Name)
7728                                 return false;
7729
7730                         if (other.RetType != RetType)
7731                                 return false;
7732                         
7733                         if (Parameters == null){
7734                                 if (other.Parameters == null)
7735                                         return true;
7736                                 return false;
7737                         }
7738
7739                         if (other.Parameters == null)
7740                                 return false;
7741                         
7742                         int c = Parameters.Length;
7743                         if (other.Parameters.Length != c)
7744                                 return false;
7745
7746                         for (int i = 0; i < c; i++)
7747                                 if (other.Parameters [i] != Parameters [i])
7748                                         return false;
7749
7750                         return true;
7751                 }
7752
7753                 static bool MemberSignatureCompare (MemberInfo m, object filter_criteria)
7754                 {
7755                         MethodSignature sig = (MethodSignature) filter_criteria;
7756
7757                         if (m.Name != sig.Name)
7758                                 return false;
7759
7760                         Type ReturnType;
7761                         MethodInfo mi = m as MethodInfo;
7762                         PropertyInfo pi = m as PropertyInfo;
7763
7764                         if (mi != null)
7765                                 ReturnType = mi.ReturnType;
7766                         else if (pi != null)
7767                                 ReturnType = pi.PropertyType;
7768                         else
7769                                 return false;
7770                         
7771                         //
7772                         // we use sig.RetType == null to mean `do not check the
7773                         // method return value.  
7774                         //
7775                         if (sig.RetType != null)
7776                                 if (ReturnType != sig.RetType)
7777                                         return false;
7778
7779                         Type [] args;
7780                         if (mi != null)
7781                                 args = TypeManager.GetParameterData (mi).Types;
7782                         else
7783                                 args = TypeManager.GetArgumentTypes (pi);
7784                         Type [] sigp = sig.Parameters;
7785
7786                         if (args.Length != sigp.Length)
7787                                 return false;
7788
7789                         for (int i = args.Length; i > 0; ){
7790                                 i--;
7791                                 if (args [i] != sigp [i])
7792                                         return false;
7793                         }
7794                         return true;
7795                 }
7796         }
7797 }