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