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