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