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