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