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