Reverted r149419.
[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.Generic;
16 using System.Reflection;
17 using System.Reflection.Emit;
18 using System.Runtime.CompilerServices;
19 using System.Runtime.InteropServices;
20 using System.Security;
21 using System.Security.Permissions;
22 using System.Text;
23
24 #if NET_2_1
25 using XmlElement = System.Object;
26 #else
27 using System.Xml;
28 #endif
29
30 using Mono.CompilerServices.SymbolWriter;
31
32 namespace Mono.CSharp {
33
34         public enum Kind {
35                 Root,
36                 Struct,
37                 Class,
38                 Interface,
39                 Enum,
40                 Delegate
41         }
42
43         /// <summary>
44         ///   This is the base class for structs and classes.  
45         /// </summary>
46         public abstract class TypeContainer : DeclSpace, IMemberContainer
47         {
48                 //
49                 // Different context is needed when resolving type container base
50                 // types. Type names come from the parent scope but type parameter
51                 // names from the container scope.
52                 //
53                 struct BaseContext : IMemberContext
54                 {
55                         TypeContainer tc;
56
57                         public BaseContext (TypeContainer tc)
58                         {
59                                 this.tc = tc;
60                         }
61
62                         #region IMemberContext Members
63
64                         public CompilerContext Compiler {
65                                 get { return tc.Compiler; }
66                         }
67
68                         public Type CurrentType {
69                                 get { return tc.Parent.CurrentType; }
70                         }
71
72                         public TypeParameter[] CurrentTypeParameters {
73                                 get { return tc.PartialContainer.CurrentTypeParameters; }
74                         }
75
76                         public TypeContainer CurrentTypeDefinition {
77                                 get { return tc.Parent.CurrentTypeDefinition; }
78                         }
79
80                         public bool IsObsolete {
81                                 get { return tc.IsObsolete; }
82                         }
83
84                         public bool IsUnsafe {
85                                 get { return tc.IsUnsafe; }
86                         }
87
88                         public bool IsStatic {
89                                 get { return tc.IsStatic; }
90                         }
91
92                         public string GetSignatureForError ()
93                         {
94                                 throw new NotImplementedException ();
95                         }
96
97                         public ExtensionMethodGroupExpr LookupExtensionMethod (Type extensionType, string name, Location loc)
98                         {
99                                 return null;
100                         }
101
102                         public FullNamedExpression LookupNamespaceAlias (string name)
103                         {
104                                 return tc.Parent.LookupNamespaceAlias (name);
105                         }
106
107                         public FullNamedExpression LookupNamespaceOrType (string name, Location loc, bool ignore_cs0104)
108                         {
109                                 TypeParameter[] tp = CurrentTypeParameters;
110                                 if (tp != null) {
111                                         TypeParameter t = TypeParameter.FindTypeParameter (tp, name);
112                                         if (t != null)
113                                                 return new TypeParameterExpr (t, loc);
114                                 }
115
116                                 return tc.Parent.LookupNamespaceOrType (name, loc, ignore_cs0104);
117                         }
118
119                         #endregion
120                 }
121
122                 [Flags]
123                 enum CachedMethods
124                 {
125                         Equals                          = 1,
126                         GetHashCode                     = 1 << 1,
127                         HasStaticFieldInitializer       = 1 << 2
128                 }
129
130
131                 // Whether this is a struct, class or interface
132                 public readonly Kind Kind;
133
134                 // Holds a list of classes and structures
135                 protected List<TypeContainer> types;
136
137                 List<MemberCore> ordered_explicit_member_list;
138                 List<MemberCore> ordered_member_list;
139
140                 // Holds the list of properties
141                 List<MemberCore> properties;
142
143                 // Holds the list of delegates
144                 List<TypeContainer> delegates;
145                 
146                 // Holds the list of constructors
147                 protected List<MemberCore> instance_constructors;
148
149                 // Holds the list of fields
150                 protected List<MemberCore> fields;
151
152                 // Holds a list of fields that have initializers
153                 protected List<FieldInitializer> initialized_fields;
154
155                 // Holds a list of static fields that have initializers
156                 protected List<FieldInitializer> initialized_static_fields;
157
158                 // Holds the list of constants
159                 protected List<MemberCore> constants;
160
161                 // Holds the methods.
162                 List<MemberCore> methods;
163
164                 // Holds the events
165                 protected List<MemberCore> events;
166
167                 // Holds the indexers
168                 List<MemberCore> indexers;
169
170                 // Holds the operators
171                 List<MemberCore> operators;
172
173                 // Holds the compiler generated classes
174                 List<CompilerGeneratedClass> compiler_generated;
175
176                 //
177                 // Pointers to the default constructor and the default static constructor
178                 //
179                 protected Constructor default_constructor;
180                 protected Constructor default_static_constructor;
181
182                 //
183                 // Points to the first non-static field added to the container.
184                 //
185                 // This is an arbitrary choice.  We are interested in looking at _some_ non-static field,
186                 // and the first one's as good as any.
187                 //
188                 FieldBase first_nonstatic_field = null;
189
190                 //
191                 // This one is computed after we can distinguish interfaces
192                 // from classes from the arraylist `type_bases' 
193                 //
194                 TypeExpr base_type;
195                 TypeExpr[] iface_exprs;
196                 Type GenericType;
197                 GenericTypeParameterBuilder[] nested_gen_params;
198
199                 protected List<FullNamedExpression> type_bases;
200
201                 protected bool members_defined;
202                 bool members_defined_ok;
203
204                 // The interfaces we implement.
205                 protected Type[] ifaces;
206
207                 // The base member cache and our member cache
208                 MemberCache base_cache;
209                 protected MemberCache member_cache;
210
211                 public const string DefaultIndexerName = "Item";
212
213                 private bool seen_normal_indexers = false;
214                 private string indexer_name = DefaultIndexerName;
215                 protected bool requires_delayed_unmanagedtype_check;
216
217                 private CachedMethods cached_method;
218
219                 List<TypeContainer> partial_parts;
220
221                 /// <remarks>
222                 ///  The pending methods that need to be implemented
223                 //   (interfaces or abstract methods)
224                 /// </remarks>
225                 PendingImplementation pending;
226
227                 public TypeContainer (NamespaceEntry ns, DeclSpace parent, MemberName name,
228                                       Attributes attrs, Kind kind)
229                         : base (ns, parent, name, attrs)
230                 {
231                         if (parent != null && parent.NamespaceEntry != ns)
232                                 throw new InternalErrorException ("A nested type should be in the same NamespaceEntry as its enclosing class");
233
234                         this.Kind = kind;
235                         this.PartialContainer = this;
236                 }
237
238                 public bool AddMember (MemberCore symbol)
239                 {
240                         return AddToContainer (symbol, symbol.MemberName.Basename);
241                 }
242
243                 protected virtual bool AddMemberType (DeclSpace ds)
244                 {
245                         return AddToContainer (ds, ds.Basename);
246                 }
247
248                 protected virtual void RemoveMemberType (DeclSpace ds)
249                 {
250                         RemoveFromContainer (ds.Basename);
251                 }
252
253                 public void AddConstant (Const constant)
254                 {
255                         if (!AddMember (constant))
256                                 return;
257
258                         if (constants == null)
259                                 constants = new List<MemberCore> ();
260                         
261                         constants.Add (constant);
262                 }
263
264                 public TypeContainer AddTypeContainer (TypeContainer tc)
265                 {
266                         if (!AddMemberType (tc))
267                                 return tc;
268
269                         if (types == null)
270                                 types = new List<TypeContainer> ();
271
272                         types.Add (tc);
273                         return tc;
274                 }
275
276                 public virtual TypeContainer AddPartial (TypeContainer next_part)
277                 {
278                         return AddPartial (next_part, next_part.Basename);
279                 }
280
281                 protected TypeContainer AddPartial (TypeContainer next_part, string name)
282                 {
283                         next_part.ModFlags |= Modifiers.PARTIAL;
284                         TypeContainer tc = GetDefinition (name) as TypeContainer;
285                         if (tc == null)
286                                 return AddTypeContainer (next_part);
287
288                         if ((tc.ModFlags & Modifiers.PARTIAL) == 0) {
289                                 Report.SymbolRelatedToPreviousError (next_part);
290                                 Error_MissingPartialModifier (tc);
291                         }
292
293                         if (tc.Kind != next_part.Kind) {
294                                 Report.SymbolRelatedToPreviousError (tc);
295                                 Report.Error (261, next_part.Location,
296                                         "Partial declarations of `{0}' must be all classes, all structs or all interfaces",
297                                         next_part.GetSignatureForError ());
298                         }
299
300                         if ((tc.ModFlags & Modifiers.AccessibilityMask) != (next_part.ModFlags & Modifiers.AccessibilityMask) &&
301                                 ((tc.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) == 0 &&
302                                  (next_part.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) == 0)) {
303                                 Report.SymbolRelatedToPreviousError (tc);
304                                 Report.Error (262, next_part.Location,
305                                         "Partial declarations of `{0}' have conflicting accessibility modifiers",
306                                         next_part.GetSignatureForError ());
307                         }
308
309                         if (tc.partial_parts == null)
310                                 tc.partial_parts = new List<TypeContainer> (1);
311
312                         if ((next_part.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) != 0) {
313                                 tc.ModFlags |= next_part.ModFlags & ~(Modifiers.DEFAULT_ACCESS_MODIFER | Modifiers.AccessibilityMask);
314                         } else if ((tc.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) != 0) {
315                                 tc.ModFlags &= ~(Modifiers.DEFAULT_ACCESS_MODIFER | Modifiers.AccessibilityMask);
316                                 tc.ModFlags |= next_part.ModFlags;
317                         } else {
318                                 tc.ModFlags |= next_part.ModFlags;
319                         }
320
321                         if (next_part.attributes != null) {
322                                 if (tc.attributes == null)
323                                         tc.attributes = next_part.attributes;
324                                 else
325                                         tc.attributes.AddAttributes (next_part.attributes.Attrs);
326                         }
327
328                         next_part.PartialContainer = tc;
329                         tc.partial_parts.Add (next_part);
330                         return tc;
331                 }
332
333                 public virtual void RemoveTypeContainer (TypeContainer next_part)
334                 {
335                         if (types != null)
336                                 types.Remove (next_part);
337                         RemoveMemberType (next_part);
338                 }
339                 
340                 public void AddDelegate (Delegate d)
341                 {
342                         if (!AddMemberType (d))
343                                 return;
344
345                         if (delegates == null)
346                                 delegates = new List<TypeContainer> ();
347
348                         delegates.Add (d);
349                 }
350
351                 private void AddMemberToList (MemberCore mc, List<MemberCore> alist, bool isexplicit)
352                 {
353                         if (ordered_explicit_member_list == null)  {
354                                 ordered_explicit_member_list = new List<MemberCore> ();
355                                 ordered_member_list = new List<MemberCore> ();
356                         }
357
358                         if (isexplicit) {
359                                 if (Kind == Kind.Interface) {
360                                         Report.Error (541, mc.Location,
361                                                 "`{0}': explicit interface declaration can only be declared in a class or struct",
362                                                 mc.GetSignatureForError ());
363                                 }
364
365                                 ordered_explicit_member_list.Add (mc);
366                                 alist.Insert (0, mc);
367                         } else {
368                                 ordered_member_list.Add (mc);
369                                 alist.Add (mc);
370                         }
371
372                 }
373                 
374                 public void AddMethod (MethodOrOperator method)
375                 {
376                         if (!AddToContainer (method, method.MemberName.Basename))
377                                 return;
378                         
379                         if (methods == null)
380                                 methods = new List<MemberCore> ();
381
382                         if (method.MemberName.Left != null) 
383                                 AddMemberToList (method, methods, true);
384                         else 
385                                 AddMemberToList (method, methods, false);
386                 }
387
388                 public void AddConstructor (Constructor c)
389                 {
390                         bool is_static = (c.ModFlags & Modifiers.STATIC) != 0;
391                         if (!AddToContainer (c, is_static ?
392                                 ConstructorBuilder.ConstructorName : ConstructorBuilder.TypeConstructorName))
393                                 return;
394                         
395                         if (is_static && c.Parameters.IsEmpty){
396                                 if (default_static_constructor != null) {
397                                     Report.SymbolRelatedToPreviousError (default_static_constructor);
398                                         Report.Error (111, c.Location,
399                                                 "A member `{0}' is already defined. Rename this member or use different parameter types",
400                                                 c.GetSignatureForError ());
401                                     return;
402                                 }
403
404                                 default_static_constructor = c;
405                         } else {
406                                 if (c.Parameters.IsEmpty)
407                                         default_constructor = c;
408                                 
409                                 if (instance_constructors == null)
410                                         instance_constructors = new List<MemberCore> ();
411                                 
412                                 instance_constructors.Add (c);
413                         }
414                 }
415
416                 public bool AddField (FieldBase field)
417                 {
418                         if (!AddMember (field))
419                                 return false;
420
421                         if (fields == null)
422                                 fields = new List<MemberCore> ();
423
424                         fields.Add (field);
425
426                         if ((field.ModFlags & Modifiers.STATIC) != 0)
427                                 return true;
428
429                         if (first_nonstatic_field == null) {
430                                 first_nonstatic_field = field;
431                                 return true;
432                         }
433
434                         if (Kind == Kind.Struct && first_nonstatic_field.Parent != field.Parent) {
435                                 Report.SymbolRelatedToPreviousError (first_nonstatic_field.Parent);
436                                 Report.Warning (282, 3, field.Location,
437                                         "struct instance field `{0}' found in different declaration from instance field `{1}'",
438                                         field.GetSignatureForError (), first_nonstatic_field.GetSignatureForError ());
439                         }
440                         return true;
441                 }
442
443                 public void AddProperty (Property prop)
444                 {
445                         if (!AddMember (prop) || 
446                                 !AddMember (prop.Get) || !AddMember (prop.Set))
447                                 return;
448
449                         if (properties == null)
450                                 properties = new List<MemberCore> ();
451
452                         if (prop.MemberName.Left != null)
453                                 AddMemberToList (prop, properties, true);
454                         else 
455                                 AddMemberToList (prop, properties, false);
456                 }
457
458                 public void AddEvent (Event e)
459                 {
460                         if (!AddMember (e))
461                                 return;
462
463                         if (e is EventProperty) {
464                                 if (!AddMember (e.Add))
465                                         return;
466
467                                 if (!AddMember (e.Remove))
468                                         return;
469                         }
470
471                         if (events == null)
472                                 events = new List<MemberCore> ();
473
474                         events.Add (e);
475                 }
476
477                 /// <summary>
478                 /// Indexer has special handling in constrast to other AddXXX because the name can be driven by IndexerNameAttribute
479                 /// </summary>
480                 public void AddIndexer (Indexer i)
481                 {
482                         if (indexers == null)
483                                 indexers = new List<MemberCore> ();
484
485                         if (i.IsExplicitImpl)
486                                 AddMemberToList (i, indexers, true);
487                         else 
488                                 AddMemberToList (i, indexers, false);
489                 }
490
491                 public void AddOperator (Operator op)
492                 {
493                         if (!AddMember (op))
494                                 return;
495
496                         if (operators == null)
497                                 operators = new List<MemberCore> ();
498
499                         operators.Add (op);
500                 }
501
502                 public void AddCompilerGeneratedClass (CompilerGeneratedClass c)
503                 {
504                         Report.Debug (64, "ADD COMPILER GENERATED CLASS", this, c);
505
506                         if (compiler_generated == null)
507                                 compiler_generated = new List<CompilerGeneratedClass> ();
508
509                         compiler_generated.Add (c);
510                 }
511
512                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
513                 {
514                         if (a.Type == pa.DefaultMember) {
515                                 if (Indexers != null) {
516                                         Report.Error (646, a.Location, "Cannot specify the `DefaultMember' attribute on type containing an indexer");
517                                         return;
518                                 }
519                         }
520                         
521                         base.ApplyAttributeBuilder (a, cb, pa);
522                 } 
523
524                 public override AttributeTargets AttributeTargets {
525                         get {
526                                 throw new NotSupportedException ();
527                         }
528                 }
529
530                 public IList<TypeContainer> Types {
531                         get {
532                                 return types;
533                         }
534                 }
535
536                 public IList<MemberCore> Methods {
537                         get {
538                                 return methods;
539                         }
540                 }
541
542                 public IList<MemberCore> Constants {
543                         get {
544                                 return constants;
545                         }
546                 }
547
548                 protected virtual Type BaseType {
549                         get {
550                                 return TypeBuilder.BaseType;
551                         }
552                 }
553
554                 public IList<MemberCore> Fields {
555                         get {
556                                 return fields;
557                         }
558                 }
559
560                 public IList<MemberCore> InstanceConstructors {
561                         get {
562                                 return instance_constructors;
563                         }
564                 }
565
566                 public IList<MemberCore> Properties {
567                         get {
568                                 return properties;
569                         }
570                 }
571
572                 public IList<MemberCore> Events {
573                         get {
574                                 return events;
575                         }
576                 }
577                 
578                 public IList<MemberCore> Indexers {
579                         get {
580                                 return indexers;
581                         }
582                 }
583
584                 public IList<MemberCore> Operators {
585                         get {
586                                 return operators;
587                         }
588                 }
589
590                 public IList<TypeContainer> Delegates {
591                         get {
592                                 return delegates;
593                         }
594                 }
595                 
596                 protected override TypeAttributes TypeAttr {
597                         get {
598                                 return ModifiersExtensions.TypeAttr (ModFlags, IsTopLevel) | base.TypeAttr;
599                         }
600                 }
601
602                 public string IndexerName {
603                         get {
604                                 return indexers == null ? DefaultIndexerName : indexer_name;
605                         }
606                 }
607
608                 public bool IsComImport {
609                         get {
610                                 if (OptAttributes == null)
611                                         return false;
612
613                                 return OptAttributes.Contains (PredefinedAttributes.Get.ComImport);
614                         }
615                 }
616
617                 public virtual void RegisterFieldForInitialization (MemberCore field, FieldInitializer expression)
618                 {
619                         if ((field.ModFlags & Modifiers.STATIC) != 0){
620                                 if (initialized_static_fields == null) {
621                                         PartialContainer.HasStaticFieldInitializer = true;
622                                         initialized_static_fields = new List<FieldInitializer> (4);
623                                 }
624
625                                 initialized_static_fields.Add (expression);
626                         } else {
627                                 if (initialized_fields == null)
628                                         initialized_fields = new List<FieldInitializer> (4);
629
630                                 initialized_fields.Add (expression);
631                         }
632                 }
633
634                 public void ResolveFieldInitializers (BlockContext ec)
635                 {
636                         if (partial_parts != null) {
637                                 foreach (TypeContainer part in partial_parts) {
638                                         part.DoResolveFieldInitializers (ec);
639                                 }
640                         }
641                         DoResolveFieldInitializers (ec);
642                 }
643
644                 void DoResolveFieldInitializers (BlockContext ec)
645                 {
646                         if (ec.IsStatic) {
647                                 if (initialized_static_fields == null)
648                                         return;
649
650                                 bool has_complex_initializer = !RootContext.Optimize;
651                                 int i;
652                                 ExpressionStatement [] init = new ExpressionStatement [initialized_static_fields.Count];
653                                 for (i = 0; i < initialized_static_fields.Count; ++i) {
654                                         FieldInitializer fi = initialized_static_fields [i];
655                                         ExpressionStatement s = fi.ResolveStatement (ec);
656                                         if (s == null) {
657                                                 s = EmptyExpressionStatement.Instance;
658                                         } else if (fi.IsComplexInitializer) {
659                                                 has_complex_initializer |= true;
660                                         }
661
662                                         init [i] = s;
663                                 }
664
665                                 for (i = 0; i < initialized_static_fields.Count; ++i) {
666                                         FieldInitializer fi = initialized_static_fields [i];
667                                         //
668                                         // Need special check to not optimize code like this
669                                         // static int a = b = 5;
670                                         // static int b = 0;
671                                         //
672                                         if (!has_complex_initializer && fi.IsDefaultInitializer)
673                                                 continue;
674
675                                         ec.CurrentBlock.AddScopeStatement (new StatementExpression (init [i]));
676                                 }
677
678                                 return;
679                         }
680
681                         if (initialized_fields == null)
682                                 return;
683
684                         for (int i = 0; i < initialized_fields.Count; ++i) {
685                                 FieldInitializer fi = (FieldInitializer) initialized_fields [i];
686                                 ExpressionStatement s = fi.ResolveStatement (ec);
687                                 if (s == null)
688                                         continue;
689
690                                 //
691                                 // Field is re-initialized to its default value => removed
692                                 //
693                                 if (fi.IsDefaultInitializer && RootContext.Optimize)
694                                         continue;
695
696                                 ec.CurrentBlock.AddScopeStatement (new StatementExpression (s));
697                         }
698                 }
699
700                 public override string DocComment {
701                         get {
702                                 return comment;
703                         }
704                         set {
705                                 if (value == null)
706                                         return;
707
708                                 comment += value;
709                         }
710                 }
711
712                 public PendingImplementation PendingImplementations {
713                         get { return pending; }
714                 }
715
716                 public override bool GetClsCompliantAttributeValue ()
717                 {
718                         if (PartialContainer != this)
719                                 return PartialContainer.GetClsCompliantAttributeValue ();
720
721                         return base.GetClsCompliantAttributeValue ();
722                 }
723
724                 public virtual void AddBasesForPart (DeclSpace part, List<FullNamedExpression> bases)
725                 {
726                         // FIXME: get rid of partial_parts and store lists of bases of each part here
727                         // assumed, not verified: 'part' is in 'partial_parts' 
728                         ((TypeContainer) part).type_bases = bases;
729                 }
730
731                 /// <summary>
732                 ///   This function computes the Base class and also the
733                 ///   list of interfaces that the class or struct @c implements.
734                 ///   
735                 ///   The return value is an array (might be null) of
736                 ///   interfaces implemented (as Types).
737                 ///   
738                 ///   The @base_class argument is set to the base object or null
739                 ///   if this is `System.Object'. 
740                 /// </summary>
741                 protected virtual TypeExpr[] ResolveBaseTypes (out TypeExpr base_class)
742                 {
743                         base_class = null;
744                         if (type_bases == null)
745                                 return null;
746
747                         int count = type_bases.Count;
748                         TypeExpr [] ifaces = null;
749                         IMemberContext base_context = new BaseContext (this);
750                         for (int i = 0, j = 0; i < count; i++){
751                                 FullNamedExpression fne = (FullNamedExpression) type_bases [i];
752
753                                 //
754                                 // Standard ResolveAsTypeTerminal cannot be used in this case because
755                                 // it does ObsoleteAttribute and constraint checks which require
756                                 // base type to be set
757                                 //
758                                 TypeExpr fne_resolved = fne.ResolveAsBaseTerminal (base_context, false);
759                                 if (fne_resolved == null)
760                                         continue;
761
762                                 if (i == 0 && Kind == Kind.Class && !fne_resolved.Type.IsInterface) {
763                                         if (fne_resolved is DynamicTypeExpr)
764                                                 Report.Error (1965, Location, "Class `{0}' cannot derive from the dynamic type",
765                                                         GetSignatureForError ());
766                                         else
767                                                 base_class = fne_resolved;
768                                         continue;
769                                 }
770
771                                 if (ifaces == null)
772                                         ifaces = new TypeExpr [count - i];
773
774                                 if (fne_resolved.Type.IsInterface) {
775                                         for (int ii = 0; ii < j; ++ii) {
776                                                 if (TypeManager.IsEqual (fne_resolved.Type, ifaces [ii].Type)) {
777                                                         Report.Error (528, Location, "`{0}' is already listed in interface list",
778                                                                 fne_resolved.GetSignatureForError ());
779                                                         break;
780                                                 }
781                                         }
782
783                                         if (Kind == Kind.Interface && !IsAccessibleAs (fne_resolved.Type)) {
784                                                 Report.Error (61, fne.Location,
785                                                         "Inconsistent accessibility: base interface `{0}' is less accessible than interface `{1}'",
786                                                         fne_resolved.GetSignatureForError (), GetSignatureForError ());
787                                         }
788                                 } else {
789                                         Report.SymbolRelatedToPreviousError (fne_resolved.Type);
790                                         if (Kind != Kind.Class) {
791                                                 Report.Error (527, fne.Location, "Type `{0}' in interface list is not an interface", fne_resolved.GetSignatureForError ());
792                                         } else if (base_class != null)
793                                                 Report.Error (1721, fne.Location, "`{0}': Classes cannot have multiple base classes (`{1}' and `{2}')",
794                                                         GetSignatureForError (), base_class.GetSignatureForError (), fne_resolved.GetSignatureForError ());
795                                         else {
796                                                 Report.Error (1722, fne.Location, "`{0}': Base class `{1}' must be specified as first",
797                                                         GetSignatureForError (), fne_resolved.GetSignatureForError ());
798                                         }
799                                 }
800
801                                 ifaces [j++] = fne_resolved;
802                         }
803
804                         return ifaces;
805                 }
806
807                 TypeExpr[] GetNormalPartialBases (ref TypeExpr base_class)
808                 {
809                         var ifaces = new List<TypeExpr> (0);
810                         if (iface_exprs != null)
811                                 ifaces.AddRange (iface_exprs);
812
813                         foreach (TypeContainer part in partial_parts) {
814                                 TypeExpr new_base_class;
815                                 TypeExpr[] new_ifaces = part.ResolveBaseTypes (out new_base_class);
816                                 if (new_base_class != TypeManager.system_object_expr) {
817                                         if (base_class == TypeManager.system_object_expr)
818                                                 base_class = new_base_class;
819                                         else {
820                                                 if (new_base_class != null && !TypeManager.IsEqual (new_base_class.Type, base_class.Type)) {
821                                                         Report.SymbolRelatedToPreviousError (base_class.Location, "");
822                                                         Report.Error (263, part.Location,
823                                                                 "Partial declarations of `{0}' must not specify different base classes",
824                                                                 part.GetSignatureForError ());
825
826                                                         return null;
827                                                 }
828                                         }
829                                 }
830
831                                 if (new_ifaces == null)
832                                         continue;
833
834                                 foreach (TypeExpr iface in new_ifaces) {
835                                         if (ifaces.Contains (iface))
836                                                 continue;
837
838                                         ifaces.Add (iface);
839                                 }
840                         }
841
842                         if (ifaces.Count == 0)
843                                 return null;
844
845                         return ifaces.ToArray ();
846                 }
847
848                 //
849                 // Checks that some operators come in pairs:
850                 //  == and !=
851                 // > and <
852                 // >= and <=
853                 // true and false
854                 //
855                 // They are matched based on the return type and the argument types
856                 //
857                 void CheckPairedOperators ()
858                 {
859                         bool has_equality_or_inequality = false;
860                         var operators = this.operators.ToArray ();
861                         bool[] has_pair = new bool[operators.Length];
862
863                         for (int i = 0; i < operators.Length; ++i) {
864                                 if (operators[i] == null)
865                                         continue;
866
867                                 Operator o_a = (Operator) operators[i];
868                                 Operator.OpType o_type = o_a.OperatorType;
869                                 if (o_type == Operator.OpType.Equality || o_type == Operator.OpType.Inequality)
870                                         has_equality_or_inequality = true;
871
872                                 Operator.OpType matching_type = o_a.GetMatchingOperator ();
873                                 if (matching_type == Operator.OpType.TOP) {
874                                         operators[i] = null;
875                                         continue;
876                                 }
877
878                                 for (int ii = 0; ii < operators.Length; ++ii) {
879                                         Operator o_b = (Operator) operators[ii];
880                                         if (o_b == null || o_b.OperatorType != matching_type)
881                                                 continue;
882
883                                         if (!TypeManager.IsEqual (o_a.ReturnType, o_b.ReturnType))
884                                                 continue;
885
886                                         if (!TypeManager.IsEqual (o_a.ParameterTypes, o_b.ParameterTypes))
887                                                 continue;
888
889                                         operators[i] = null;
890
891                                         //
892                                         // Used to ignore duplicate user conversions
893                                         //
894                                         has_pair[ii] = true;
895                                 }
896                         }
897
898                         for (int i = 0; i < operators.Length; ++i) {
899                                 if (operators[i] == null || has_pair[i])
900                                         continue;
901
902                                 Operator o = (Operator) operators [i];
903                                 Report.Error (216, o.Location,
904                                         "The operator `{0}' requires a matching operator `{1}' to also be defined",
905                                         o.GetSignatureForError (), Operator.GetName (o.GetMatchingOperator ()));
906                         }
907
908                         if (has_equality_or_inequality) {
909                                 if (Methods == null || !HasEquals)
910                                         Report.Warning (660, 2, Location, "`{0}' defines operator == or operator != but does not override Object.Equals(object o)",
911                                                 GetSignatureForError ());
912
913                                 if (Methods == null || !HasGetHashCode)
914                                         Report.Warning (661, 2, Location, "`{0}' defines operator == or operator != but does not override Object.GetHashCode()",
915                                                 GetSignatureForError ());
916                         }
917                 }
918
919                 bool CheckGenericInterfaces (Type[] ifaces)
920                 {
921                         var already_checked = new List<Type> ();
922
923                         for (int i = 0; i < ifaces.Length; i++) {
924                                 Type iface = ifaces [i];
925                                 foreach (Type t in already_checked) {
926                                         if (iface == t)
927                                                 continue;
928
929                                         Type[] inferred = new Type [CountTypeParameters];
930                                         if (!TypeManager.MayBecomeEqualGenericInstances (iface, t, inferred, null))
931                                                 continue;
932
933                                         Report.Error (695, Location,
934                                                 "`{0}' cannot implement both `{1}' and `{2}' " +
935                                                 "because they may unify for some type parameter substitutions",
936                                                 TypeManager.CSharpName (TypeBuilder), TypeManager.CSharpName (iface),
937                                                 TypeManager.CSharpName (t));
938                                         return false;
939                                 }
940
941                                 already_checked.Add (iface);
942                         }
943
944                         return true;
945                 }
946
947                 bool error = false;
948                 
949                 bool CreateTypeBuilder ()
950                 {
951                         try {
952                                 Type default_parent = null;
953                                 if (Kind == Kind.Struct)
954                                         default_parent = TypeManager.value_type;
955                                 else if (Kind == Kind.Enum)
956                                         default_parent = TypeManager.enum_type;
957                                 else if (Kind == Kind.Delegate)
958                                         default_parent = TypeManager.multicast_delegate_type;
959
960                                 //
961                                 // Sets .size to 1 for structs with no instance fields
962                                 //
963                                 int type_size = Kind == Kind.Struct && first_nonstatic_field == null ? 1 : 0;
964
965                                 if (IsTopLevel){
966                                         if (GlobalRootNamespace.Instance.IsNamespace (Name)) {
967                                                 Report.Error (519, Location, "`{0}' clashes with a predefined namespace", Name);
968                                                 return false;
969                                         }
970
971                                         ModuleBuilder builder = Module.Compiled.Builder;
972                                         TypeBuilder = builder.DefineType (
973                                                 Name, TypeAttr, default_parent, type_size);
974                                 } else {
975                                         TypeBuilder builder = Parent.TypeBuilder;
976
977                                         TypeBuilder = builder.DefineNestedType (
978                                                 Basename, TypeAttr, default_parent, type_size);
979                                 }
980                         } catch (ArgumentException) {
981                                 Report.RuntimeMissingSupport (Location, "static classes");
982                                 return false;
983                         }
984
985                         TypeManager.AddUserType (this);
986
987                         if (IsGeneric) {
988                                 string[] param_names = new string [TypeParameters.Length];
989                                 for (int i = 0; i < TypeParameters.Length; i++)
990                                         param_names [i] = TypeParameters [i].Name;
991
992                                 GenericTypeParameterBuilder[] gen_params = TypeBuilder.DefineGenericParameters (param_names);
993
994                                 int offset = CountTypeParameters;
995                                 if (CurrentTypeParameters != null)
996                                         offset -= CurrentTypeParameters.Length;
997
998                                 if (offset > 0) {
999                                         nested_gen_params = new GenericTypeParameterBuilder [offset];
1000                                         Array.Copy (gen_params, nested_gen_params, offset);
1001                                 }
1002
1003                                 for (int i = offset; i < gen_params.Length; i++)
1004                                         CurrentTypeParameters [i - offset].Define (gen_params [i]);
1005                         }
1006
1007                         return true;
1008                 }
1009
1010                 bool DefineBaseTypes ()
1011                 {
1012                         iface_exprs = ResolveBaseTypes (out base_type);
1013                         if (partial_parts != null) {
1014                                 iface_exprs = GetNormalPartialBases (ref base_type);
1015                         }
1016
1017                         //
1018                         // GetClassBases calls ResolveBaseTypeExpr() on the various type expressions involved,
1019                         // which in turn should have called DefineType()s on base types if necessary.
1020                         //
1021                         // None of the code below should trigger DefineType()s on classes that we depend on.
1022                         // Thus, we are eligible to be on the topological sort `type_container_resolve_order'.
1023                         //
1024                         // Let's do it as soon as possible, since code below can call DefineType() on classes
1025                         // that depend on us to be populated before they are.
1026                         //
1027                         if (!(this is CompilerGeneratedClass) && !(this is Delegate))
1028                                 RootContext.RegisterOrder (this); 
1029
1030                         if (!CheckRecursiveDefinition (this))
1031                                 return false;
1032
1033                         if (base_type != null && base_type.Type != null) {
1034                                 TypeBuilder.SetParent (base_type.Type);
1035                         }
1036
1037                         // add interfaces that were not added at type creation
1038                         if (iface_exprs != null) {
1039                                 ifaces = TypeManager.ExpandInterfaces (iface_exprs);
1040                                 if (ifaces == null)
1041                                         return false;
1042
1043                                 foreach (Type itype in ifaces)
1044                                         TypeBuilder.AddInterfaceImplementation (itype);
1045
1046                                 if (!CheckGenericInterfaces (ifaces))
1047                                         return false;
1048
1049                                 TypeManager.RegisterBuilder (TypeBuilder, ifaces);
1050                         }
1051
1052                         return true;
1053                 }
1054
1055                 //
1056                 // Defines the type in the appropriate ModuleBuilder or TypeBuilder.
1057                 //
1058                 public TypeBuilder CreateType ()
1059                 {
1060                         if (TypeBuilder != null)
1061                                 return TypeBuilder;
1062
1063                         if (error)
1064                                 return null;
1065
1066                         if (!CreateTypeBuilder ()) {
1067                                 error = true;
1068                                 return null;
1069                         }
1070
1071                         if (partial_parts != null) {
1072                                 foreach (TypeContainer part in partial_parts)
1073                                         part.TypeBuilder = TypeBuilder;
1074                         }
1075
1076                         if (Types != null) {
1077                                 foreach (TypeContainer tc in Types) {
1078                                         if (tc.CreateType () == null) {
1079                                                 error = true;
1080                                                 return null;
1081                                         }
1082                                 }
1083                         }
1084
1085                         return TypeBuilder;
1086                 }
1087
1088                 bool type_defined;
1089
1090                 public override TypeBuilder DefineType ()
1091                 {
1092                         if (error)
1093                                 return null;
1094                         if (type_defined)
1095                                 return TypeBuilder;
1096
1097                         type_defined = true;
1098
1099                         if (CreateType () == null) {
1100                                 error = true;
1101                                 return null;
1102                         }
1103
1104                         if (!DefineBaseTypes ()) {
1105                                 error = true;
1106                                 return null;
1107                         }
1108
1109                         if (!DefineNestedTypes ()) {
1110                                 error = true;
1111                                 return null;
1112                         }
1113
1114                         return TypeBuilder;
1115                 }
1116
1117                 public override void SetParameterInfo (List<Constraints> constraints_list)
1118                 {
1119                         base.SetParameterInfo (constraints_list);
1120
1121                         if (!is_generic || PartialContainer == this)
1122                                 return;
1123
1124                         TypeParameter[] tc_names = PartialContainer.TypeParameters;
1125                         for (int i = 0; i < tc_names.Length; ++i) {
1126                                 if (tc_names [i].Name != type_params [i].Name) {
1127                                         Report.SymbolRelatedToPreviousError (PartialContainer.Location, "");
1128                                         Report.Error (264, Location, "Partial declarations of `{0}' must have the same type parameter names in the same order",
1129                                                 GetSignatureForError ());
1130                                         break;
1131                                 }
1132
1133                                 if (tc_names [i].Variance != type_params [i].Variance) {
1134                                         Report.SymbolRelatedToPreviousError (PartialContainer.Location, "");
1135                                         Report.Error (1067, Location, "Partial declarations of `{0}' must have the same type parameter variance modifiers",
1136                                                 GetSignatureForError ());
1137                                         break;
1138                                 }
1139                         }
1140                 }
1141
1142                 void UpdateTypeParameterConstraints (TypeContainer part)
1143                 {
1144                         TypeParameter[] current_params = type_params;
1145                         for (int i = 0; i < current_params.Length; i++) {
1146                                 Constraints c = part.type_params [i].Constraints;
1147                                 if (c == null)
1148                                         continue;
1149
1150                                 if (current_params [i].UpdateConstraints (part, c))
1151                                         continue;
1152
1153                                 Report.SymbolRelatedToPreviousError (Location, "");
1154                                 Report.Error (265, part.Location,
1155                                         "Partial declarations of `{0}' have inconsistent constraints for type parameter `{1}'",
1156                                         GetSignatureForError (), current_params [i].GetSignatureForError ());
1157                         }
1158                 }
1159
1160                 public bool ResolveType ()
1161                 {
1162                         if (!DoResolveType ())
1163                                 return false;
1164
1165                         if (compiler_generated != null) {
1166                                 foreach (CompilerGeneratedClass c in compiler_generated)
1167                                         if (!c.ResolveType ())
1168                                                 return false;
1169                         }
1170
1171                         return true;
1172                 }
1173
1174                 protected virtual bool DoResolveType ()
1175                 {
1176                         if (!IsGeneric)
1177                                 return true;
1178
1179                         if (PartialContainer != this)
1180                                 throw new InternalErrorException ();
1181
1182                         TypeExpr current_type = null;
1183                         if (CurrentTypeParameters != null) {
1184                                 foreach (TypeParameter type_param in CurrentTypeParameters) {
1185                                         if (!type_param.Resolve (this)) {
1186                                                 error = true;
1187                                                 return false;
1188                                         }
1189                                 }
1190
1191                                 if (partial_parts != null) {
1192                                         foreach (TypeContainer part in partial_parts)
1193                                                 UpdateTypeParameterConstraints (part);
1194                                 }
1195                         }
1196
1197                         for (int i = 0; i < TypeParameters.Length; ++i) {
1198                                 //
1199                                 // FIXME: Same should be done for delegates
1200                                 // TODO: Quite ugly way how to propagate constraints to
1201                                 // nested types
1202                                 //
1203                                 if (nested_gen_params != null && i < nested_gen_params.Length) {
1204                                         TypeParameters [i].SetConstraints (nested_gen_params [i]);
1205                                 } else {
1206                                         if (!TypeParameters [i].DefineType (this)) {
1207                                                 error = true;
1208                                                 return false;
1209                                         }
1210                                 }
1211                         }
1212
1213                         // TODO: Very strange, why not simple make generic type from
1214                         // current type parameters
1215                         current_type = new GenericTypeExpr (this, Location);
1216                         current_type = current_type.ResolveAsTypeTerminal (this, false);
1217                         if (current_type == null) {
1218                                 error = true;
1219                                 return false;
1220                         }
1221
1222                         currentType = current_type.Type;
1223                         return true;
1224                 }
1225
1226                 protected virtual bool DefineNestedTypes ()
1227                 {
1228                         if (Types != null) {
1229                                 foreach (TypeContainer tc in Types)
1230                                         if (tc.DefineType () == null)
1231                                                 return false;
1232                         }
1233
1234                         if (Delegates != null) {
1235                                 foreach (Delegate d in Delegates)
1236                                         if (d.DefineType () == null)
1237                                                 return false;
1238                         }
1239
1240                         return true;
1241                 }
1242
1243                 TypeContainer InTransit;
1244
1245                 protected bool CheckRecursiveDefinition (TypeContainer tc)
1246                 {
1247                         if (InTransit != null) {
1248                                 Report.SymbolRelatedToPreviousError (this);
1249                                 if (this is Interface)
1250                                         Report.Error (
1251                                                 529, tc.Location, "Inherited interface `{0}' causes a " +
1252                                                 "cycle in the interface hierarchy of `{1}'",
1253                                                 GetSignatureForError (), tc.GetSignatureForError ());
1254                                 else
1255                                         Report.Error (
1256                                                 146, tc.Location, "Circular base class dependency " +
1257                                                 "involving `{0}' and `{1}'",
1258                                                 tc.GetSignatureForError (), GetSignatureForError ());
1259                                 return false;
1260                         }
1261
1262                         InTransit = tc;
1263
1264                         if (base_type != null && base_type.Type != null) {
1265                                 Type t = TypeManager.DropGenericTypeArguments (base_type.Type);
1266                                 TypeContainer ptc = TypeManager.LookupTypeContainer (t);
1267                                 if ((ptc != null) && !ptc.CheckRecursiveDefinition (this))
1268                                         return false;
1269                         }
1270
1271                         if (iface_exprs != null) {
1272                                 foreach (TypeExpr iface in iface_exprs) {
1273                                         Type itype = TypeManager.DropGenericTypeArguments (iface.Type);
1274                                         TypeContainer ptc = TypeManager.LookupTypeContainer (itype);
1275                                         if ((ptc != null) && !ptc.CheckRecursiveDefinition (this))
1276                                                 return false;
1277                                 }
1278                         }
1279
1280                         if (!IsTopLevel && !Parent.PartialContainer.CheckRecursiveDefinition (this))
1281                                 return false;
1282
1283                         InTransit = null;
1284                         return true;
1285                 }
1286
1287                 public override TypeParameter[] CurrentTypeParameters {
1288                         get {
1289                                 return PartialContainer.type_params;
1290                         }
1291                 }
1292
1293                 /// <summary>
1294                 ///   Populates our TypeBuilder with fields and methods
1295                 /// </summary>
1296                 public sealed override bool Define ()
1297                 {
1298                         if (members_defined)
1299                                 return members_defined_ok;
1300
1301                         members_defined_ok = DoDefineMembers ();
1302                         members_defined = true;
1303
1304                         return members_defined_ok;
1305                 }
1306
1307                 protected virtual bool DoDefineMembers ()
1308                 {
1309                         if (iface_exprs != null) {
1310                                 foreach (TypeExpr iface in iface_exprs) {
1311                                         ObsoleteAttribute oa = AttributeTester.GetObsoleteAttribute (iface.Type);
1312                                         if ((oa != null) && !IsObsolete)
1313                                                 AttributeTester.Report_ObsoleteMessage (
1314                                                         oa, iface.GetSignatureForError (), Location, Report);
1315
1316                                         GenericTypeExpr ct = iface as GenericTypeExpr;
1317                                         if (ct != null) {
1318                                                 // TODO: passing `this' is wrong, should be base type iface instead
1319                                                 TypeManager.CheckTypeVariance (ct.Type, Variance.Covariant, this);
1320
1321                                                 if (!ct.CheckConstraints (this))
1322                                                         return false;
1323
1324                                                 if (ct.HasDynamicArguments ()) {
1325                                                         Report.Error (1966, iface.Location,
1326                                                                 "`{0}': cannot implement a dynamic interface `{1}'",
1327                                                                 GetSignatureForError (), iface.GetSignatureForError ());
1328                                                         return false;
1329                                                 }
1330                                         }
1331                                 }
1332                         }
1333
1334                         if (base_type != null) {
1335                                 ObsoleteAttribute obsolete_attr = AttributeTester.GetObsoleteAttribute (base_type.Type);
1336                                 if (obsolete_attr != null && !IsObsolete)
1337                                         AttributeTester.Report_ObsoleteMessage (obsolete_attr, base_type.GetSignatureForError (), Location, Report);
1338
1339                                 GenericTypeExpr ct = base_type as GenericTypeExpr;
1340                                 if ((ct != null) && !ct.CheckConstraints (this))
1341                                         return false;
1342                                 
1343                                 TypeContainer baseContainer = TypeManager.LookupTypeContainer(base_type.Type);
1344                                 if (baseContainer != null)
1345                                         baseContainer.Define();                         
1346                                 
1347                                 member_cache = new MemberCache (base_type.Type, this);
1348                         } else if (Kind == Kind.Interface) {
1349                                 member_cache = new MemberCache (null, this);
1350                                 Type [] ifaces = TypeManager.GetInterfaces (TypeBuilder);
1351                                 for (int i = 0; i < ifaces.Length; ++i)
1352                                         member_cache.AddInterface (TypeManager.LookupMemberCache (ifaces [i]));
1353                         } else {
1354                                 member_cache = new MemberCache (null, this);
1355                         }
1356
1357                         if (types != null)
1358                                 foreach (TypeContainer tc in types)
1359                                         member_cache.AddNestedType (tc);
1360
1361                         if (delegates != null)
1362                                 foreach (Delegate d in delegates)
1363                                         member_cache.AddNestedType (d);
1364
1365                         if (partial_parts != null) {
1366                                 foreach (TypeContainer part in partial_parts)
1367                                         part.member_cache = member_cache;
1368                         }
1369
1370                         if (!IsTopLevel) {
1371                                 MemberInfo conflict_symbol = Parent.PartialContainer.FindBaseMemberWithSameName (Basename, false);
1372                                 if (conflict_symbol == null) {
1373                                         if ((ModFlags & Modifiers.NEW) != 0)
1374                                                 Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
1375                                 } else {
1376                                         if ((ModFlags & Modifiers.NEW) == 0) {
1377                                                 Report.SymbolRelatedToPreviousError (conflict_symbol);
1378                                                 Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
1379                                                         GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
1380                                         }
1381                                 }
1382                         }
1383
1384                         DefineContainerMembers (constants);
1385                         DefineContainerMembers (fields);
1386
1387                         if (Kind == Kind.Struct || Kind == Kind.Class) {
1388                                 pending = PendingImplementation.GetPendingImplementations (this);
1389
1390                                 if (requires_delayed_unmanagedtype_check) {
1391                                         requires_delayed_unmanagedtype_check = false;
1392                                         foreach (FieldBase f in fields) {
1393                                                 if (f.MemberType != null && f.MemberType.IsPointer)
1394                                                         TypeManager.VerifyUnmanaged (Compiler, f.MemberType, f.Location);
1395                                         }
1396                                 }
1397                         }
1398                 
1399                         //
1400                         // Constructors are not in the defined_names array
1401                         //
1402                         DefineContainerMembers (instance_constructors);
1403                 
1404                         DefineContainerMembers (events);
1405                         DefineContainerMembers (ordered_explicit_member_list);
1406                         DefineContainerMembers (ordered_member_list);
1407
1408                         if (operators != null) {
1409                                 DefineContainerMembers (operators);
1410                                 CheckPairedOperators ();
1411                         }
1412
1413                         DefineContainerMembers (delegates);
1414
1415                         ComputeIndexerName();
1416                         CheckEqualsAndGetHashCode();
1417
1418                         if (CurrentType != null) {
1419                                 GenericType = CurrentType;
1420                         }
1421
1422                         //
1423                         // FIXME: This hack is needed because member cache does not work
1424                         // with generic types, we rely on runtime to inflate dynamic types.
1425                         // TODO: This hack requires member cache refactoring to be removed
1426                         //
1427                         if (TypeManager.IsGenericType (TypeBuilder))
1428                                 member_cache = new MemberCache (this);
1429
1430                         return true;
1431                 }
1432
1433                 protected virtual void DefineContainerMembers (System.Collections.IList mcal) // IList<MemberCore>
1434                 {
1435                         if (mcal != null) {
1436                                 foreach (MemberCore mc in mcal) {
1437                                         try {
1438                                                 mc.Define ();
1439                                         } catch (Exception e) {
1440                                                 throw new InternalErrorException (mc, e);
1441                                         }
1442                                 }
1443                         }
1444                 }
1445                 
1446                 protected virtual void ComputeIndexerName ()
1447                 {
1448                         if (indexers == null)
1449                                 return;
1450
1451                         string class_indexer_name = null;
1452
1453                         //
1454                         // If there's both an explicit and an implicit interface implementation, the
1455                         // explicit one actually implements the interface while the other one is just
1456                         // a normal indexer.  See bug #37714.
1457                         //
1458
1459                         // Invariant maintained by AddIndexer(): All explicit interface indexers precede normal indexers
1460                         foreach (Indexer i in indexers) {
1461                                 if (i.InterfaceType != null) {
1462                                         if (seen_normal_indexers)
1463                                                 throw new Exception ("Internal Error: 'Indexers' array not sorted properly.");
1464                                         continue;
1465                                 }
1466
1467                                 seen_normal_indexers = true;
1468
1469                                 if (class_indexer_name == null) {
1470                                         class_indexer_name = i.ShortName;
1471                                         continue;
1472                                 }
1473
1474                                 if (i.ShortName != class_indexer_name)
1475                                         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");
1476                         }
1477
1478                         if (class_indexer_name != null)
1479                                 indexer_name = class_indexer_name;
1480                 }
1481
1482                 protected virtual void EmitIndexerName ()
1483                 {
1484                         if (!seen_normal_indexers)
1485                                 return;
1486
1487                         PredefinedAttribute pa = PredefinedAttributes.Get.DefaultMember;
1488                         if (pa.Constructor == null &&
1489                                 !pa.ResolveConstructor (Location, TypeManager.string_type))
1490                                 return;
1491
1492                         CustomAttributeBuilder cb = new CustomAttributeBuilder (pa.Constructor, new string [] { IndexerName });
1493                         TypeBuilder.SetCustomAttribute (cb);
1494                 }
1495
1496                 protected virtual void CheckEqualsAndGetHashCode ()
1497                 {
1498                         if (methods == null)
1499                                 return;
1500
1501                         if (HasEquals && !HasGetHashCode) {
1502                                 Report.Warning (659, 3, this.Location, "`{0}' overrides Object.Equals(object) but does not override Object.GetHashCode()", this.GetSignatureForError ());
1503                         }
1504                 }
1505
1506                 public MemberInfo FindBaseMemberWithSameName (string name, bool ignore_methods)
1507                 {
1508                         return BaseCache == null ? null : BaseCache.FindMemberWithSameName (name, ignore_methods, null);
1509                 }
1510
1511                 /// <summary>
1512                 ///   This function is based by a delegate to the FindMembers routine
1513                 /// </summary>
1514                 static bool AlwaysAccept (MemberInfo m, object filterCriteria)
1515                 {
1516                         return true;
1517                 }
1518
1519                 /// <summary>
1520                 ///   This filter is used by FindMembers, and we just keep
1521                 ///   a global for the filter to `AlwaysAccept'
1522                 /// </summary>
1523                 static MemberFilter accepting_filter;
1524
1525                 
1526                 static TypeContainer ()
1527                 {
1528                         accepting_filter = new MemberFilter (AlwaysAccept);
1529                 }
1530
1531                 public MethodInfo[] GetMethods ()
1532                 {
1533                         var members = new List<MethodInfo> ();
1534
1535                         Define ();
1536
1537                         if (methods != null) {
1538                                 int len = methods.Count;
1539                                 for (int i = 0; i < len; i++) {
1540                                         Method m = (Method) methods [i];
1541
1542                                         members.Add (m.MethodBuilder);
1543                                 }
1544                         }
1545
1546                         if (operators != null) {
1547                                 int len = operators.Count;
1548                                 for (int i = 0; i < len; i++) {
1549                                         Operator o = (Operator) operators [i];
1550
1551                                         members.Add (o.MethodBuilder);
1552                                 }
1553                         }
1554
1555                         if (properties != null) {
1556                                 int len = properties.Count;
1557                                 for (int i = 0; i < len; i++) {
1558                                         Property p = (Property) properties [i];
1559
1560                                         if (p.GetBuilder != null)
1561                                                 members.Add (p.GetBuilder);
1562                                         if (p.SetBuilder != null)
1563                                                 members.Add (p.SetBuilder);
1564                                 }
1565                         }
1566                                 
1567                         if (indexers != null) {
1568                                 int len = indexers.Count;
1569                                 for (int i = 0; i < len; i++) {
1570                                         Indexer ix = (Indexer) indexers [i];
1571
1572                                         if (ix.GetBuilder != null)
1573                                                 members.Add (ix.GetBuilder);
1574                                         if (ix.SetBuilder != null)
1575                                                 members.Add (ix.SetBuilder);
1576                                 }
1577                         }
1578
1579                         if (events != null) {
1580                                 int len = events.Count;
1581                                 for (int i = 0; i < len; i++) {
1582                                         Event e = (Event) events [i];
1583
1584                                         if (e.AddBuilder != null)
1585                                                 members.Add (e.AddBuilder);
1586                                         if (e.RemoveBuilder != null)
1587                                                 members.Add (e.RemoveBuilder);
1588                                 }
1589                         }
1590
1591                         return members.ToArray ();
1592                 }
1593                 
1594                 // Indicated whether container has StructLayout attribute set Explicit
1595                 public bool HasExplicitLayout {
1596                         get { return (caching_flags & Flags.HasExplicitLayout) != 0; }
1597                         set { caching_flags |= Flags.HasExplicitLayout; }
1598                 }
1599
1600                 public bool HasStructLayout {
1601                         get { return (caching_flags & Flags.HasStructLayout) != 0; }
1602                         set { caching_flags |= Flags.HasStructLayout; }
1603                 }
1604
1605                 //
1606                 // Return the nested type with name @name.  Ensures that the nested type
1607                 // is defined if necessary.  Do _not_ use this when you have a MemberCache handy.
1608                 //
1609                 public Type FindNestedType (string name)
1610                 {
1611                         if (PartialContainer != this)
1612                                 throw new InternalErrorException ("should not happen");
1613
1614                         var lists = new[] { types, delegates };
1615
1616                         for (int j = 0; j < lists.Length; ++j) {
1617                                 var list = lists [j];
1618                                 if (list == null)
1619                                         continue;
1620                                 
1621                                 int len = list.Count;
1622                                 for (int i = 0; i < len; ++i) {
1623                                         var ds = list [i];
1624                                         if (ds.Basename == name) {
1625                                                 return ds.DefineType ();
1626                                         }
1627                                 }
1628                         }
1629
1630                         return null;
1631                 }
1632
1633                 private void FindMembers_NestedTypes (Modifiers modflags,
1634                                                       BindingFlags bf, MemberFilter filter, object criteria,
1635                                                           ref List<MemberInfo> members)
1636                 {
1637                         var lists = new[] { types, delegates };
1638
1639                         for (int j = 0; j < lists.Length; ++j) {
1640                                 var list = lists [j];
1641                                 if (list == null)
1642                                         continue;
1643                         
1644                                 int len = list.Count;
1645                                 for (int i = 0; i < len; i++) {
1646                                         var ds = list [i];
1647                                         
1648                                         if ((ds.ModFlags & modflags) == 0)
1649                                                 continue;
1650                                         
1651                                         TypeBuilder tb = ds.TypeBuilder;
1652                                         if (tb == null) {
1653                                                 if (!(criteria is string) || ds.Basename.Equals (criteria))
1654                                                         tb = ds.DefineType ();
1655                                         }
1656                                         
1657                                         if (tb != null && (filter (tb, criteria) == true)) {
1658                                                 if (members == null)
1659                                                         members = new List<MemberInfo> ();
1660                                                 
1661                                                 members.Add (tb);
1662                                         }
1663                                 }
1664                         }
1665                 }
1666                 
1667                 /// <summary>
1668                 ///   This method returns the members of this type just like Type.FindMembers would
1669                 ///   Only, we need to use this for types which are _being_ defined because MS' 
1670                 ///   implementation can't take care of that.
1671                 /// </summary>
1672                 //
1673                 // FIXME: return an empty static array instead of null, that cleans up
1674                 // some code and is consistent with some coding conventions I just found
1675                 // out existed ;-)
1676                 //
1677                 //
1678                 // Notice that in various cases we check if our field is non-null,
1679                 // something that would normally mean that there was a bug elsewhere.
1680                 //
1681                 // The problem happens while we are defining p-invoke methods, as those
1682                 // will trigger a FindMembers, but this happens before things are defined
1683                 //
1684                 // Since the whole process is a no-op, it is fine to check for null here.
1685                 //
1686                 // TODO: This approach will be one day completely removed, it's already
1687                 // used at few places only
1688                 //
1689                 //
1690                 public override MemberList FindMembers (MemberTypes mt, BindingFlags bf,
1691                                                         MemberFilter filter, object criteria)
1692                 {
1693                         List<MemberInfo> members = null;
1694
1695                         Modifiers modflags = 0;
1696                         if ((bf & BindingFlags.Public) != 0)
1697                                 modflags |= Modifiers.PUBLIC | Modifiers.PROTECTED |
1698                                         Modifiers.INTERNAL;
1699                         if ((bf & BindingFlags.NonPublic) != 0)
1700                                 modflags |= Modifiers.PRIVATE;
1701
1702                         Modifiers static_mask = 0, static_flags = 0;
1703                         switch (bf & (BindingFlags.Static | BindingFlags.Instance)) {
1704                         case BindingFlags.Static:
1705                                 static_mask = static_flags = Modifiers.STATIC;
1706                                 break;
1707
1708                         case BindingFlags.Instance:
1709                                 static_mask = Modifiers.STATIC;
1710                                 static_flags = 0;
1711                                 break;
1712
1713                         default:
1714                                 static_mask = static_flags = 0;
1715                                 break;
1716                         }
1717
1718                         Timer.StartTimer (TimerType.TcFindMembers);
1719
1720                         if (filter == null)
1721                                 filter = accepting_filter; 
1722
1723                         if ((mt & MemberTypes.Field) != 0) {
1724                                 if (fields != null) {
1725                                         int len = fields.Count;
1726                                         for (int i = 0; i < len; i++) {
1727                                                 FieldBase f = (FieldBase) fields [i];
1728                                                 
1729                                                 if ((f.ModFlags & modflags) == 0)
1730                                                         continue;
1731                                                 if ((f.ModFlags & static_mask) != static_flags)
1732                                                         continue;
1733
1734                                                 FieldBuilder fb = f.FieldBuilder;
1735                                                 if (fb != null && filter (fb, criteria) == true) {
1736                                                         if (members == null)
1737                                                                 members = new List<MemberInfo> ();
1738                                                         
1739                                                         members.Add (fb);
1740                                                 }
1741                                         }
1742                                 }
1743
1744                                 if (constants != null) {
1745                                         int len = constants.Count;
1746                                         for (int i = 0; i < len; i++) {
1747                                                 Const con = (Const) constants [i];
1748                                                 
1749                                                 if ((con.ModFlags & modflags) == 0)
1750                                                         continue;
1751                                                 if ((con.ModFlags & static_mask) != static_flags)
1752                                                         continue;
1753
1754                                                 FieldBuilder fb = con.FieldBuilder;
1755                                                 if (fb == null) {
1756                                                         // Define parent and not member, otherwise membercache can be null
1757                                                         if (con.Parent.Define ())
1758                                                                 fb = con.FieldBuilder;
1759                                                 }
1760                                                 if (fb != null && filter (fb, criteria) == true) {
1761                                                         if (members == null)
1762                                                                 members = new List<MemberInfo> ();
1763                                                         
1764                                                         members.Add (fb);
1765                                                 }
1766                                         }
1767                                 }
1768                         }
1769
1770                         if ((mt & MemberTypes.Method) != 0) {
1771                                 if (methods != null) {
1772                                         int len = methods.Count;
1773                                         for (int i = 0; i < len; i++) {
1774                                                 MethodOrOperator m = (MethodOrOperator) methods [i];
1775                                                 
1776                                                 if ((m.ModFlags & modflags) == 0)
1777                                                         continue;
1778                                                 if ((m.ModFlags & static_mask) != static_flags)
1779                                                         continue;
1780                                                 
1781                                                 MethodBuilder mb = m.MethodBuilder;
1782
1783                                                 if (mb != null && filter (mb, criteria) == true) {
1784                                                         if (members == null)
1785                                                                 members = new List<MemberInfo> ();
1786
1787                                                         members.Add (mb);
1788                                                 }
1789                                         }
1790                                 }
1791
1792                                 if (operators != null) {
1793                                         int len = operators.Count;
1794                                         for (int i = 0; i < len; i++) {
1795                                                 Operator o = (Operator) operators [i];
1796                                                 
1797                                                 if ((o.ModFlags & modflags) == 0)
1798                                                         continue;
1799                                                 if ((o.ModFlags & static_mask) != static_flags)
1800                                                         continue;
1801                                                 
1802                                                 MethodBuilder ob = o.MethodBuilder;
1803                                                 if (ob != null && filter (ob, criteria) == true) {
1804                                                         if (members == null)
1805                                                                 members = new List<MemberInfo> ();
1806                                                         
1807                                                         members.Add (ob);
1808                                                 }
1809                                         }
1810                                 }
1811
1812                                 if (events != null) {
1813                                         foreach (Event e in events) {
1814                                                 if ((e.ModFlags & modflags) == 0)
1815                                                         continue;
1816                                                 if ((e.ModFlags & static_mask) != static_flags)
1817                                                         continue;
1818
1819                                                 MethodBuilder b = e.AddBuilder;
1820                                                 if (b != null && filter (b, criteria)) {
1821                                                         if (members == null)
1822                                                                 members = new List<MemberInfo> ();
1823
1824                                                         members.Add (b);
1825                                                 }
1826
1827                                                 b = e.RemoveBuilder;
1828                                                 if (b != null && filter (b, criteria)) {
1829                                                         if (members == null)
1830                                                                 members = new List<MemberInfo> ();
1831
1832                                                         members.Add (b);
1833                                                 }
1834                                         }
1835                                 }
1836
1837                                 if (properties != null) {
1838                                         int len = properties.Count;
1839                                         for (int i = 0; i < len; i++) {
1840                                                 Property p = (Property) properties [i];
1841                                                 
1842                                                 if ((p.ModFlags & modflags) == 0)
1843                                                         continue;
1844                                                 if ((p.ModFlags & static_mask) != static_flags)
1845                                                         continue;
1846                                                 
1847                                                 MethodBuilder b;
1848
1849                                                 b = p.GetBuilder;
1850                                                 if (b != null && filter (b, criteria) == true) {
1851                                                         if (members == null)
1852                                                                 members = new List<MemberInfo> ();
1853                                                         
1854                                                         members.Add (b);
1855                                                 }
1856
1857                                                 b = p.SetBuilder;
1858                                                 if (b != null && filter (b, criteria) == true) {
1859                                                         if (members == null)
1860                                                                 members = new List<MemberInfo> ();
1861                                                         
1862                                                         members.Add (b);
1863                                                 }
1864                                         }
1865                                 }
1866                                 
1867                                 if (indexers != null) {
1868                                         int len = indexers.Count;
1869                                         for (int i = 0; i < len; i++) {
1870                                                 Indexer ix = (Indexer) indexers [i];
1871                                                 
1872                                                 if ((ix.ModFlags & modflags) == 0)
1873                                                         continue;
1874                                                 if ((ix.ModFlags & static_mask) != static_flags)
1875                                                         continue;
1876                                                 
1877                                                 MethodBuilder b;
1878
1879                                                 b = ix.GetBuilder;
1880                                                 if (b != null && filter (b, criteria) == true) {
1881                                                         if (members == null)
1882                                                                 members = new List<MemberInfo> ();
1883                                                         
1884                                                         members.Add (b);
1885                                                 }
1886
1887                                                 b = ix.SetBuilder;
1888                                                 if (b != null && filter (b, criteria) == true) {
1889                                                         if (members == null)
1890                                                                 members = new List<MemberInfo> ();
1891                                                         
1892                                                         members.Add (b);
1893                                                 }
1894                                         }
1895                                 }
1896                         }
1897
1898                         if ((mt & MemberTypes.Event) != 0) {
1899                                 if (events != null) {
1900                                         int len = events.Count;
1901                                         for (int i = 0; i < len; i++) {
1902                                                 Event e = (Event) events [i];
1903                                                 
1904                                                 if ((e.ModFlags & modflags) == 0)
1905                                                         continue;
1906                                                 if ((e.ModFlags & static_mask) != static_flags)
1907                                                         continue;
1908
1909                                                 MemberInfo eb = e.EventBuilder;
1910                                                 if (eb != null && filter (eb, criteria) == true) {
1911                                                         if (members == null)
1912                                                                 members = new List<MemberInfo> ();
1913
1914                                                         members.Add (e.EventBuilder);
1915                                                 }
1916                                         }
1917                                 }
1918                         }
1919                         
1920                         if ((mt & MemberTypes.Property) != 0){
1921                                 if (properties != null) {
1922                                         int len = properties.Count;
1923                                         for (int i = 0; i < len; i++) {
1924                                                 Property p = (Property) properties [i];
1925                                                 
1926                                                 if ((p.ModFlags & modflags) == 0)
1927                                                         continue;
1928                                                 if ((p.ModFlags & static_mask) != static_flags)
1929                                                         continue;
1930
1931                                                 MemberInfo pb = p.PropertyBuilder;
1932                                                 if (pb != null && filter (pb, criteria) == true) {
1933                                                         if (members == null)
1934                                                                 members = new List<MemberInfo> ();
1935                                                         
1936                                                         members.Add (p.PropertyBuilder);
1937                                                 }
1938                                         }
1939                                 }
1940
1941                                 if (indexers != null) {
1942                                         int len = indexers.Count;
1943                                         for (int i = 0; i < len; i++) {
1944                                                 Indexer ix = (Indexer) indexers [i];
1945                                                 
1946                                                 if ((ix.ModFlags & modflags) == 0)
1947                                                         continue;
1948                                                 if ((ix.ModFlags & static_mask) != static_flags)
1949                                                         continue;
1950
1951                                                 MemberInfo ib = ix.PropertyBuilder;
1952                                                 if (ib != null && filter (ib, criteria) == true) {
1953                                                         if (members == null)
1954                                                                 members = new List<MemberInfo> ();
1955                                                         
1956                                                         members.Add (ix.PropertyBuilder);
1957                                                 }
1958                                         }
1959                                 }
1960                         }
1961                         
1962                         if ((mt & MemberTypes.NestedType) != 0)
1963                                 FindMembers_NestedTypes (modflags, bf, filter, criteria, ref members);
1964
1965                         if ((mt & MemberTypes.Constructor) != 0){
1966                                 if (((bf & BindingFlags.Instance) != 0) && (instance_constructors != null)){
1967                                         int len = instance_constructors.Count;
1968                                         for (int i = 0; i < len; i++) {
1969                                                 Constructor c = (Constructor) instance_constructors [i];
1970                                                 
1971                                                 ConstructorBuilder cb = c.ConstructorBuilder;
1972                                                 if (cb != null && filter (cb, criteria) == true) {
1973                                                         if (members == null)
1974                                                                 members = new List<MemberInfo> ();
1975
1976                                                         members.Add (cb);
1977                                                 }
1978                                         }
1979                                 }
1980
1981                                 if (((bf & BindingFlags.Static) != 0) && (default_static_constructor != null)){
1982                                         ConstructorBuilder cb =
1983                                                 default_static_constructor.ConstructorBuilder;
1984                                         
1985                                         if (cb != null && filter (cb, criteria) == true) {
1986                                                 if (members == null)
1987                                                         members = new List<MemberInfo> ();
1988                                                 
1989                                                 members.Add (cb);
1990                                         }
1991                                 }
1992                         }
1993
1994                         //
1995                         // Lookup members in base if requested.
1996                         //
1997                         if ((bf & BindingFlags.DeclaredOnly) == 0) {
1998                                 if (TypeBuilder.BaseType != null) {
1999                                         MemberList list = FindMembers (TypeBuilder.BaseType, mt, bf, filter, criteria);
2000                                         if (list.Count > 0) {
2001                                                 if (members == null)
2002                                                         members = new List<MemberInfo> ();
2003                                         
2004                                                 members.AddRange (list);
2005                                         }
2006                                 }
2007                         }
2008
2009                         Timer.StopTimer (TimerType.TcFindMembers);
2010
2011                         if (members == null)
2012                                 return MemberList.Empty;
2013                         else
2014                                 return new MemberList (members);
2015                 }
2016
2017                 public override MemberCache MemberCache {
2018                         get {
2019                                 return member_cache;
2020                         }
2021                 }
2022
2023                 public static MemberList FindMembers (Type t, MemberTypes mt, BindingFlags bf,
2024                                                       MemberFilter filter, object criteria)
2025                 {
2026                         DeclSpace ds = TypeManager.LookupDeclSpace (t);
2027
2028                         if (ds != null)
2029                                 return ds.FindMembers (mt, bf, filter, criteria);
2030                         else
2031                                 return new MemberList (t.FindMembers (mt, bf, filter, criteria));
2032                 }
2033
2034                 /// <summary>
2035                 ///   Emits the values for the constants
2036                 /// </summary>
2037                 public void EmitConstants ()
2038                 {
2039                         if (constants != null)
2040                                 foreach (Const con in constants)
2041                                         con.Emit ();
2042                         return;
2043                 }
2044
2045                 void CheckMemberUsage (List<MemberCore> al, string member_type)
2046                 {
2047                         if (al == null)
2048                                 return;
2049
2050                         foreach (MemberCore mc in al) {
2051                                 if ((mc.ModFlags & Modifiers.AccessibilityMask) != Modifiers.PRIVATE)
2052                                         continue;
2053
2054                                 if (!mc.IsUsed && (mc.caching_flags & Flags.Excluded) == 0) {
2055                                         Report.Warning (169, 3, mc.Location, "The private {0} `{1}' is never used", member_type, mc.GetSignatureForError ());
2056                                 }
2057                         }
2058                 }
2059
2060                 public virtual void VerifyMembers ()
2061                 {
2062                         //
2063                         // Check for internal or private fields that were never assigned
2064                         //
2065                         if (Report.WarningLevel >= 3) {
2066                                 CheckMemberUsage (properties, "property");
2067                                 CheckMemberUsage (methods, "method");
2068                                 CheckMemberUsage (constants, "constant");
2069
2070                                 if (fields != null){
2071                                         bool is_type_exposed = Kind == Kind.Struct || IsExposedFromAssembly ();
2072                                         foreach (FieldBase f in fields) {
2073                                                 if ((f.ModFlags & Modifiers.AccessibilityMask) != Modifiers.PRIVATE) {
2074                                                         if (is_type_exposed)
2075                                                                 continue;
2076
2077                                                         f.SetMemberIsUsed ();
2078                                                 }                               
2079                                                 
2080                                                 if (!f.IsUsed){
2081                                                         if ((f.caching_flags & Flags.IsAssigned) == 0)
2082                                                                 Report.Warning (169, 3, f.Location, "The private field `{0}' is never used", f.GetSignatureForError ());
2083                                                         else {
2084                                                                 Report.Warning (414, 3, f.Location, "The private field `{0}' is assigned but its value is never used",
2085                                                                         f.GetSignatureForError ());
2086                                                         }
2087                                                         continue;
2088                                                 }
2089                                                 
2090                                                 //
2091                                                 // Only report 649 on level 4
2092                                                 //
2093                                                 if (Report.WarningLevel < 4)
2094                                                         continue;
2095                                                 
2096                                                 if ((f.caching_flags & Flags.IsAssigned) != 0)
2097                                                         continue;
2098
2099                                                 //
2100                                                 // Don't be pendatic over serializable attributes
2101                                                 //
2102                                                 if (f.OptAttributes != null || PartialContainer.HasStructLayout)
2103                                                         continue;
2104                                                 
2105                                                 Constant c = New.Constantify (f.MemberType);
2106                                                 Report.Warning (649, 4, f.Location, "Field `{0}' is never assigned to, and will always have its default value `{1}'",
2107                                                         f.GetSignatureForError (), c == null ? "null" : c.AsString ());
2108                                         }
2109                                 }
2110                         }
2111                 }
2112
2113                 // TODO: move to ClassOrStruct
2114                 void EmitConstructors ()
2115                 {
2116                         if (instance_constructors == null)
2117                                 return;
2118
2119                         if (TypeBuilder.IsSubclassOf (TypeManager.attribute_type) && RootContext.VerifyClsCompliance && IsClsComplianceRequired ()) {
2120                                 bool has_compliant_args = false;
2121
2122                                 foreach (Constructor c in instance_constructors) {
2123                                         try {
2124                                                 c.Emit ();
2125                                         }
2126                                         catch (Exception e) {
2127                                                 throw new InternalErrorException (c, e);
2128                                         }
2129
2130                                         if (has_compliant_args)
2131                                                 continue;
2132
2133                                         has_compliant_args = c.HasCompliantArgs;
2134                                 }
2135                                 if (!has_compliant_args)
2136                                         Report.Warning (3015, 1, Location, "`{0}' has no accessible constructors which use only CLS-compliant types", GetSignatureForError ());
2137                         } else {
2138                                 foreach (Constructor c in instance_constructors) {
2139                                         try {
2140                                                 c.Emit ();
2141                                         }
2142                                         catch (Exception e) {
2143                                                 throw new InternalErrorException (c, e);
2144                                         }
2145                                 }
2146                         }
2147                 }
2148
2149                 /// <summary>
2150                 ///   Emits the code, this step is performed after all
2151                 ///   the types, enumerations, constructors
2152                 /// </summary>
2153                 public virtual void EmitType ()
2154                 {
2155                         if (OptAttributes != null)
2156                                 OptAttributes.Emit ();
2157
2158                         Emit ();
2159
2160                         EmitConstructors ();
2161
2162                         // Can not continue if constants are broken
2163                         EmitConstants ();
2164                         if (Report.Errors > 0)
2165                                 return;
2166
2167                         if (default_static_constructor != null)
2168                                 default_static_constructor.Emit ();
2169                         
2170                         if (operators != null)
2171                                 foreach (Operator o in operators)
2172                                         o.Emit ();
2173
2174                         if (properties != null)
2175                                 foreach (Property p in properties)
2176                                         p.Emit ();
2177
2178                         if (indexers != null) {
2179                                 foreach (Indexer indx in indexers)
2180                                         indx.Emit ();
2181                                 EmitIndexerName ();
2182                         }
2183
2184                         if (events != null){
2185                                 foreach (Event e in Events)
2186                                         e.Emit ();
2187                         }
2188
2189                         if (methods != null) {
2190                                 for (int i = 0; i < methods.Count; ++i)
2191                                         ((MethodOrOperator) methods [i]).Emit ();
2192                         }
2193                         
2194                         if (fields != null)
2195                                 foreach (FieldBase f in fields)
2196                                         f.Emit ();
2197
2198                         if (delegates != null) {
2199                                 foreach (Delegate d in Delegates) {
2200                                         d.Emit ();
2201                                 }
2202                         }
2203
2204                         if (pending != null)
2205                                 pending.VerifyPendingMethods (Report);
2206
2207                         if (Report.Errors > 0)
2208                                 return;
2209
2210                         if (compiler_generated != null) {
2211                                 for (int i = 0; i < compiler_generated.Count; ++i)
2212                                         ((CompilerGeneratedClass) compiler_generated [i]).EmitType ();
2213                         }
2214                 }
2215                 
2216                 public override void CloseType ()
2217                 {
2218                         if ((caching_flags & Flags.CloseTypeCreated) != 0)
2219                                 return;
2220
2221                         try {
2222                                 caching_flags |= Flags.CloseTypeCreated;
2223                                 TypeBuilder.CreateType ();
2224                         } catch (TypeLoadException){
2225                                 //
2226                                 // This is fine, the code still created the type
2227                                 //
2228 //                              Report.Warning (-20, "Exception while creating class: " + TypeBuilder.Name);
2229 //                              Console.WriteLine (e.Message);
2230                         } catch (Exception e) {
2231                                 throw new InternalErrorException (this, e);
2232                         }
2233                         
2234                         if (Types != null){
2235                                 foreach (TypeContainer tc in Types)
2236                                         if (tc.Kind == Kind.Struct)
2237                                                 tc.CloseType ();
2238
2239                                 foreach (TypeContainer tc in Types)
2240                                         if (tc.Kind != Kind.Struct)
2241                                                 tc.CloseType ();
2242                         }
2243
2244                         if (Delegates != null)
2245                                 foreach (Delegate d in Delegates)
2246                                         d.CloseType ();
2247
2248                         if (compiler_generated != null)
2249                                 foreach (CompilerGeneratedClass c in compiler_generated)
2250                                         c.CloseType ();
2251                         
2252                         PartialContainer = null;
2253                         types = null;
2254 //                      properties = null;
2255                         delegates = null;
2256                         fields = null;
2257                         initialized_fields = null;
2258                         initialized_static_fields = null;
2259                         constants = null;
2260                         ordered_explicit_member_list = null;
2261                         ordered_member_list = null;
2262                         methods = null;
2263                         events = null;
2264                         indexers = null;
2265                         operators = null;
2266                         compiler_generated = null;
2267                         default_constructor = null;
2268                         default_static_constructor = null;
2269                         type_bases = null;
2270                         OptAttributes = null;
2271                         ifaces = null;
2272                         base_cache = null;
2273                         member_cache = null;
2274                 }
2275
2276                 //
2277                 // Performs the validation on a Method's modifiers (properties have
2278                 // the same properties).
2279                 //
2280                 public bool MethodModifiersValid (MemberCore mc)
2281                 {
2282                         const Modifiers vao = (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE);
2283                         const Modifiers va = (Modifiers.VIRTUAL | Modifiers.ABSTRACT);
2284                         const Modifiers nv = (Modifiers.NEW | Modifiers.VIRTUAL);
2285                         bool ok = true;
2286                         var flags = mc.ModFlags;
2287                         
2288                         //
2289                         // At most one of static, virtual or override
2290                         //
2291                         if ((flags & Modifiers.STATIC) != 0){
2292                                 if ((flags & vao) != 0){
2293                                         Report.Error (112, mc.Location, "A static member `{0}' cannot be marked as override, virtual or abstract",
2294                                                 mc.GetSignatureForError ());
2295                                         ok = false;
2296                                 }
2297                         }
2298
2299                         if (Kind == Kind.Struct){
2300                                 if ((flags & va) != 0){
2301                                         ModifiersExtensions.Error_InvalidModifier (mc.Location, "virtual or abstract", Report);
2302                                         ok = false;
2303                                 }
2304                         }
2305
2306                         if ((flags & Modifiers.OVERRIDE) != 0 && (flags & nv) != 0){
2307                                 Report.Error (113, mc.Location, "A member `{0}' marked as override cannot be marked as new or virtual",
2308                                         mc.GetSignatureForError ());
2309                                 ok = false;
2310                         }
2311
2312                         //
2313                         // If the declaration includes the abstract modifier, then the
2314                         // declaration does not include static, virtual or extern
2315                         //
2316                         if ((flags & Modifiers.ABSTRACT) != 0){
2317                                 if ((flags & Modifiers.EXTERN) != 0){
2318                                         Report.Error (
2319                                                 180, mc.Location, "`{0}' cannot be both extern and abstract", mc.GetSignatureForError ());
2320                                         ok = false;
2321                                 }
2322
2323                                 if ((flags & Modifiers.SEALED) != 0) {
2324                                         Report.Error (502, mc.Location, "`{0}' cannot be both abstract and sealed", mc.GetSignatureForError ());
2325                                         ok = false;
2326                                 }
2327
2328                                 if ((flags & Modifiers.VIRTUAL) != 0){
2329                                         Report.Error (503, mc.Location, "The abstract method `{0}' cannot be marked virtual", mc.GetSignatureForError ());
2330                                         ok = false;
2331                                 }
2332
2333                                 if ((ModFlags & Modifiers.ABSTRACT) == 0){
2334                                         Report.SymbolRelatedToPreviousError (this);
2335                                         Report.Error (513, mc.Location, "`{0}' is abstract but it is declared in the non-abstract class `{1}'",
2336                                                 mc.GetSignatureForError (), GetSignatureForError ());
2337                                         ok = false;
2338                                 }
2339                         }
2340
2341                         if ((flags & Modifiers.PRIVATE) != 0){
2342                                 if ((flags & vao) != 0){
2343                                         Report.Error (621, mc.Location, "`{0}': virtual or abstract members cannot be private", mc.GetSignatureForError ());
2344                                         ok = false;
2345                                 }
2346                         }
2347
2348                         if ((flags & Modifiers.SEALED) != 0){
2349                                 if ((flags & Modifiers.OVERRIDE) == 0){
2350                                         Report.Error (238, mc.Location, "`{0}' cannot be sealed because it is not an override", mc.GetSignatureForError ());
2351                                         ok = false;
2352                                 }
2353                         }
2354
2355                         return ok;
2356                 }
2357
2358                 public Constructor DefaultStaticConstructor {
2359                         get { return default_static_constructor; }
2360                 }
2361
2362                 protected override bool VerifyClsCompliance ()
2363                 {
2364                         if (!base.VerifyClsCompliance ())
2365                                 return false;
2366
2367                         VerifyClsName ();
2368
2369                         Type base_type = TypeBuilder.BaseType;
2370                         if (base_type != null && !AttributeTester.IsClsCompliant (base_type)) {
2371                                 Report.Warning (3009, 1, Location, "`{0}': base type `{1}' is not CLS-compliant", GetSignatureForError (), TypeManager.CSharpName (base_type));
2372                         }
2373                         return true;
2374                 }
2375
2376
2377                 /// <summary>
2378                 /// Checks whether container name is CLS Compliant
2379                 /// </summary>
2380                 void VerifyClsName ()
2381                 {
2382                         Dictionary<string, object> base_members = base_cache == null ?
2383                                 new Dictionary<string, object> () :
2384                                 base_cache.GetPublicMembers ();
2385                         var this_members = new Dictionary<string, object> ();
2386
2387                         foreach (var entry in defined_names) {
2388                                 MemberCore mc = entry.Value;
2389                                 if (!mc.IsClsComplianceRequired ())
2390                                         continue;
2391
2392                                 string name = entry.Key;
2393                                 string basename = name.Substring (name.LastIndexOf ('.') + 1);
2394
2395                                 string lcase = basename.ToLower (System.Globalization.CultureInfo.InvariantCulture);
2396                                 object found;
2397                                 if (!base_members.TryGetValue (lcase, out found)) {
2398                                         if (!this_members.TryGetValue (lcase, out found)) {
2399                                                 this_members.Add (lcase, mc);
2400                                                 continue;
2401                                         }
2402                                 }
2403
2404                                 if ((mc.ModFlags & Modifiers.OVERRIDE) != 0)
2405                                         continue;                                       
2406
2407                                 if (found is MemberInfo) {
2408                                         if (basename == ((MemberInfo) found).Name)
2409                                                 continue;
2410                                         Report.SymbolRelatedToPreviousError ((MemberInfo) found);
2411                                 } else {
2412                                         Report.SymbolRelatedToPreviousError ((MemberCore) found);
2413                                 }
2414
2415                                 Report.Warning (3005, 1, mc.Location, "Identifier `{0}' differing only in case is not CLS-compliant", mc.GetSignatureForError ());
2416                         }
2417                 }
2418
2419
2420                 /// <summary>
2421                 ///   Performs checks for an explicit interface implementation.  First it
2422                 ///   checks whether the `interface_type' is a base inteface implementation.
2423                 ///   Then it checks whether `name' exists in the interface type.
2424                 /// </summary>
2425                 public bool VerifyImplements (InterfaceMemberBase mb)
2426                 {
2427                         if (ifaces != null) {
2428                                 foreach (Type t in ifaces){
2429                                         if (TypeManager.IsEqual (t, mb.InterfaceType))
2430                                                 return true;
2431                                 }
2432                         }
2433                         
2434                         Report.SymbolRelatedToPreviousError (mb.InterfaceType);
2435                         Report.Error (540, mb.Location, "`{0}': containing type does not implement interface `{1}'",
2436                                 mb.GetSignatureForError (), TypeManager.CSharpName (mb.InterfaceType));
2437                         return false;
2438                 }
2439
2440                 public override Type LookupAnyGeneric (string typeName)
2441                 {
2442                         if (types != null) {
2443                                 foreach (TypeContainer tc in types) {
2444                                         if (!tc.IsGeneric)
2445                                                 continue;
2446
2447                                         int pos = tc.Basename.LastIndexOf ('`');
2448                                         if (pos == typeName.Length && String.Compare (typeName, 0, tc.Basename, 0, pos) == 0)
2449                                                 return tc.TypeBuilder;
2450                                 }
2451                         }
2452
2453                         return base.LookupAnyGeneric (typeName);
2454                 }
2455
2456                 public void Mark_HasEquals ()
2457                 {
2458                         cached_method |= CachedMethods.Equals;
2459                 }
2460
2461                 public void Mark_HasGetHashCode ()
2462                 {
2463                         cached_method |= CachedMethods.GetHashCode;
2464                 }
2465
2466                 /// <summary>
2467                 /// Method container contains Equals method
2468                 /// </summary>
2469                 public bool HasEquals {
2470                         get {
2471                                 return (cached_method & CachedMethods.Equals) != 0;
2472                         }
2473                 }
2474  
2475                 /// <summary>
2476                 /// Method container contains GetHashCode method
2477                 /// </summary>
2478                 public bool HasGetHashCode {
2479                         get {
2480                                 return (cached_method & CachedMethods.GetHashCode) != 0;
2481                         }
2482                 }
2483
2484                 public bool HasStaticFieldInitializer {
2485                         get {
2486                                 return (cached_method & CachedMethods.HasStaticFieldInitializer) != 0;
2487                         }
2488                         set {
2489                                 if (value)
2490                                         cached_method |= CachedMethods.HasStaticFieldInitializer;
2491                                 else
2492                                         cached_method &= ~CachedMethods.HasStaticFieldInitializer;
2493                         }
2494                 }
2495
2496                 //
2497                 // IMemberContainer
2498                 //
2499
2500                 string IMemberContainer.Name {
2501                         get {
2502                                 return Name;
2503                         }
2504                 }
2505
2506                 Type IMemberContainer.Type {
2507                         get {
2508                                 return TypeBuilder;
2509                         }
2510                 }
2511
2512                 bool IMemberContainer.IsInterface {
2513                         get {
2514                                 return Kind == Kind.Interface;
2515                         }
2516                 }
2517
2518                 MemberList IMemberContainer.GetMembers (MemberTypes mt, BindingFlags bf)
2519                 {
2520                         BindingFlags new_bf = bf | BindingFlags.DeclaredOnly;
2521
2522                         if (GenericType != null)
2523                                 return TypeManager.FindMembers (GenericType, mt, new_bf,
2524                                                                 null, null);
2525                         else
2526                                 return FindMembers (mt, new_bf, null, null);
2527                 }
2528
2529                 //
2530                 // Generates xml doc comments (if any), and if required,
2531                 // handle warning report.
2532                 //
2533                 internal override void GenerateDocComment (DeclSpace ds)
2534                 {
2535                         DocUtil.GenerateTypeDocComment (this, ds, Report);
2536                 }
2537
2538                 public override string DocCommentHeader {
2539                         get { return "T:"; }
2540                 }
2541
2542                 public MemberCache BaseCache {
2543                         get {
2544                                 if (base_cache != null)
2545                                         return base_cache;
2546                                 if (TypeBuilder.BaseType != null)
2547                                         base_cache = TypeManager.LookupMemberCache (TypeBuilder.BaseType);
2548                                 if (TypeBuilder.IsInterface)
2549                                         base_cache = TypeManager.LookupBaseInterfacesCache (TypeBuilder);
2550                                 return base_cache;
2551                         }
2552                 }
2553         }
2554
2555         public abstract class ClassOrStruct : TypeContainer
2556         {
2557                 Dictionary<SecurityAction, PermissionSet> declarative_security;
2558
2559                 public ClassOrStruct (NamespaceEntry ns, DeclSpace parent,
2560                                       MemberName name, Attributes attrs, Kind kind)
2561                         : base (ns, parent, name, attrs, kind)
2562                 {
2563                 }
2564
2565                 protected override bool AddToContainer (MemberCore symbol, string name)
2566                 {
2567                         if (name == MemberName.Name) {
2568                                 if (symbol is TypeParameter) {
2569                                         Report.Error (694, symbol.Location,
2570                                                 "Type parameter `{0}' has same name as containing type, or method",
2571                                                 symbol.GetSignatureForError ());
2572                                         return false;
2573                                 }
2574
2575                                 InterfaceMemberBase imb = symbol as InterfaceMemberBase;
2576                                 if (imb == null || !imb.IsExplicitImpl) {
2577                                         Report.SymbolRelatedToPreviousError (this);
2578                                         Report.Error (542, symbol.Location, "`{0}': member names cannot be the same as their enclosing type",
2579                                                 symbol.GetSignatureForError ());
2580                                         return false;
2581                                 }
2582                         }
2583
2584                         return base.AddToContainer (symbol, name);
2585                 }
2586
2587                 public override void VerifyMembers ()
2588                 {
2589                         base.VerifyMembers ();
2590
2591                         if ((events != null) && Report.WarningLevel >= 3) {
2592                                 foreach (Event e in events){
2593                                         // Note: The event can be assigned from same class only, so we can report
2594                                         // this warning for all accessibility modes
2595                                         if ((e.caching_flags & Flags.IsUsed) == 0)
2596                                                 Report.Warning (67, 3, e.Location, "The event `{0}' is never used", e.GetSignatureForError ());
2597                                 }
2598                         }
2599                 }
2600
2601                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
2602                 {
2603                         if (a.IsValidSecurityAttribute ()) {
2604                                 if (declarative_security == null)
2605                                         declarative_security = new Dictionary<SecurityAction, PermissionSet> ();
2606
2607                                 a.ExtractSecurityPermissionSet (declarative_security);
2608                                 return;
2609                         }
2610
2611                         if (a.Type == pa.StructLayout) {
2612                                 PartialContainer.HasStructLayout = true;
2613
2614                                 if (a.GetLayoutKindValue () == LayoutKind.Explicit)
2615                                         PartialContainer.HasExplicitLayout = true;
2616                         }
2617
2618                         if (a.Type == pa.Dynamic) {
2619                                 a.Error_MisusedDynamicAttribute ();
2620                                 return;
2621                         }
2622
2623                         base.ApplyAttributeBuilder (a, cb, pa);
2624                 }
2625
2626                 /// <summary>
2627                 /// Defines the default constructors 
2628                 /// </summary>
2629                 protected void DefineDefaultConstructor (bool is_static)
2630                 {
2631                         // The default instance constructor is public
2632                         // If the class is abstract, the default constructor is protected
2633                         // The default static constructor is private
2634
2635                         Modifiers mods;
2636                         if (is_static) {
2637                                 mods = Modifiers.STATIC | Modifiers.PRIVATE;
2638                         } else {
2639                                 mods = ((ModFlags & Modifiers.ABSTRACT) != 0) ? Modifiers.PROTECTED : Modifiers.PUBLIC;
2640                         }
2641
2642                         Constructor c = new Constructor (this, MemberName.Name, mods,
2643                                 null, ParametersCompiled.EmptyReadOnlyParameters,
2644                                 new GeneratedBaseInitializer (Location),
2645                                 Location);
2646                         
2647                         AddConstructor (c);
2648                         c.Block = new ToplevelBlock (Compiler, ParametersCompiled.EmptyReadOnlyParameters, Location);
2649                 }
2650
2651                 protected override bool DoDefineMembers ()
2652                 {
2653                         CheckProtectedModifier ();
2654
2655                         base.DoDefineMembers ();
2656
2657                         if (default_static_constructor != null)
2658                                 default_static_constructor.Define ();
2659
2660                         return true;
2661                 }
2662
2663                 public override void Emit ()
2664                 {
2665                         if (default_static_constructor == null && PartialContainer.HasStaticFieldInitializer) {
2666                                 DefineDefaultConstructor (true);
2667                                 default_static_constructor.Define ();
2668                         }
2669
2670                         base.Emit ();
2671
2672                         if (declarative_security != null) {
2673                                 foreach (var de in declarative_security) {
2674                                         TypeBuilder.AddDeclarativeSecurity (de.Key, de.Value);
2675                                 }
2676                         }
2677                 }
2678
2679                 public override ExtensionMethodGroupExpr LookupExtensionMethod (Type extensionType, string name, Location loc)
2680                 {
2681                         DeclSpace top_level = Parent;
2682                         if (top_level != null) {
2683                                 while (top_level.Parent != null)
2684                                         top_level = top_level.Parent;
2685
2686                                 var candidates = NamespaceEntry.NS.LookupExtensionMethod (extensionType, this, name);
2687                                 if (candidates != null)
2688                                         return new ExtensionMethodGroupExpr (candidates, NamespaceEntry, extensionType, loc);
2689                         }
2690
2691                         return NamespaceEntry.LookupExtensionMethod (extensionType, name, loc);
2692                 }
2693
2694                 protected override TypeAttributes TypeAttr {
2695                         get {
2696                                 if (default_static_constructor == null)
2697                                         return base.TypeAttr | TypeAttributes.BeforeFieldInit;
2698
2699                                 return base.TypeAttr;
2700                         }
2701                 }
2702         }
2703
2704
2705         // TODO: should be sealed
2706         public class Class : ClassOrStruct {
2707                 const Modifiers AllowedModifiers =
2708                         Modifiers.NEW |
2709                         Modifiers.PUBLIC |
2710                         Modifiers.PROTECTED |
2711                         Modifiers.INTERNAL |
2712                         Modifiers.PRIVATE |
2713                         Modifiers.ABSTRACT |
2714                         Modifiers.SEALED |
2715                         Modifiers.STATIC |
2716                         Modifiers.UNSAFE;
2717
2718                 public const TypeAttributes StaticClassAttribute = TypeAttributes.Abstract | TypeAttributes.Sealed;
2719
2720                 public Class (NamespaceEntry ns, DeclSpace parent, MemberName name, Modifiers mod,
2721                               Attributes attrs)
2722                         : base (ns, parent, name, attrs, Kind.Class)
2723                 {
2724                         var accmods = Parent.Parent == null ? Modifiers.INTERNAL : Modifiers.PRIVATE;
2725                         this.ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, accmods, Location, Report);
2726
2727                         if (IsStatic && RootContext.Version == LanguageVersion.ISO_1) {
2728                                 Report.FeatureIsNotAvailable (Location, "static classes");
2729                         }
2730                 }
2731
2732                 public override void AddBasesForPart (DeclSpace part, List<FullNamedExpression> bases)
2733                 {
2734                         if (part.Name == "System.Object")
2735                                 Report.Error (537, part.Location,
2736                                         "The class System.Object cannot have a base class or implement an interface.");
2737                         base.AddBasesForPart (part, bases);
2738                 }
2739
2740                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
2741                 {
2742                         if (a.Type == pa.AttributeUsage) {
2743                                 if (!TypeManager.IsAttributeType (BaseType) &&
2744                                         TypeBuilder.FullName != "System.Attribute") {
2745                                         Report.Error (641, a.Location, "Attribute `{0}' is only valid on classes derived from System.Attribute", a.GetSignatureForError ());
2746                                 }
2747                         }
2748
2749                         if (a.Type == pa.Conditional && !TypeManager.IsAttributeType (BaseType)) {
2750                                 Report.Error (1689, a.Location, "Attribute `System.Diagnostics.ConditionalAttribute' is only valid on methods or attribute classes");
2751                                 return;
2752                         }
2753
2754                         if (a.Type == pa.ComImport && !attributes.Contains (pa.Guid)) {
2755                                 a.Error_MissingGuidAttribute ();
2756                                 return;
2757                         }
2758
2759                         if (a.Type == pa.Extension) {
2760                                 a.Error_MisusedExtensionAttribute ();
2761                                 return;
2762                         }
2763
2764                         if (AttributeTester.IsAttributeExcluded (a.Type, Location))
2765                                 return;
2766
2767                         base.ApplyAttributeBuilder (a, cb, pa);
2768                 }
2769
2770                 public override AttributeTargets AttributeTargets {
2771                         get {
2772                                 return AttributeTargets.Class;
2773                         }
2774                 }
2775
2776                 protected override void DefineContainerMembers (System.Collections.IList list)
2777                 {
2778                         if (list == null)
2779                                 return;
2780
2781                         if (!IsStatic) {
2782                                 base.DefineContainerMembers (list);
2783                                 return;
2784                         }
2785
2786                         foreach (MemberCore m in list) {
2787                                 if (m is Operator) {
2788                                         Report.Error (715, m.Location, "`{0}': Static classes cannot contain user-defined operators", m.GetSignatureForError ());
2789                                         continue;
2790                                 }
2791
2792                                 if (m is Destructor) {
2793                                         Report.Error (711, m.Location, "`{0}': Static classes cannot contain destructor", GetSignatureForError ());
2794                                         continue;
2795                                 }
2796
2797                                 if (m is Indexer) {
2798                                         Report.Error (720, m.Location, "`{0}': cannot declare indexers in a static class", m.GetSignatureForError ());
2799                                         continue;
2800                                 }
2801
2802                                 if ((m.ModFlags & Modifiers.STATIC) != 0 || m is Enum || m is Delegate)
2803                                         continue;
2804
2805                                 if (m is Constructor) {
2806                                         Report.Error (710, m.Location, "`{0}': Static classes cannot have instance constructors", GetSignatureForError ());
2807                                         continue;
2808                                 }
2809
2810                                 Method method = m as Method;
2811                                 if (method != null && method.Parameters.HasExtensionMethodType) {
2812                                         Report.Error (1105, m.Location, "`{0}': Extension methods must be declared static", m.GetSignatureForError ());
2813                                         continue;
2814                                 }
2815
2816                                 Report.Error (708, m.Location, "`{0}': cannot declare instance members in a static class", m.GetSignatureForError ());
2817                         }
2818
2819                         base.DefineContainerMembers (list);
2820                 }
2821
2822                 protected override bool DoDefineMembers ()
2823                 {
2824                         if ((ModFlags & Modifiers.ABSTRACT) == Modifiers.ABSTRACT && (ModFlags & (Modifiers.SEALED | Modifiers.STATIC)) != 0) {
2825                                 Report.Error (418, Location, "`{0}': an abstract class cannot be sealed or static", GetSignatureForError ());
2826                         }
2827
2828                         if ((ModFlags & (Modifiers.SEALED | Modifiers.STATIC)) == (Modifiers.SEALED | Modifiers.STATIC)) {
2829                                 Report.Error (441, Location, "`{0}': a class cannot be both static and sealed", GetSignatureForError ());
2830                         }
2831
2832                         if (InstanceConstructors == null && !IsStatic)
2833                                 DefineDefaultConstructor (false);
2834
2835                         return base.DoDefineMembers ();
2836                 }
2837
2838                 public override void Emit ()
2839                 {
2840                         base.Emit ();
2841
2842                         if ((ModFlags & Modifiers.METHOD_EXTENSION) != 0)
2843                                 PredefinedAttributes.Get.Extension.EmitAttribute (TypeBuilder);
2844                 }
2845
2846                 protected override TypeExpr[] ResolveBaseTypes (out TypeExpr base_class)
2847                 {
2848                         TypeExpr[] ifaces = base.ResolveBaseTypes (out base_class);
2849
2850                         if (base_class == null) {
2851                                 if (RootContext.StdLib)
2852                                         base_class = TypeManager.system_object_expr;
2853                                 else if (Name != "System.Object")
2854                                         base_class = TypeManager.system_object_expr;
2855                         } else {
2856                                 if (Kind == Kind.Class && TypeManager.IsGenericParameter (base_class.Type)){
2857                                         Report.Error (
2858                                                 689, base_class.Location,
2859                                                 "Cannot derive from `{0}' because it is a type parameter",
2860                                                 base_class.GetSignatureForError ());
2861                                         return ifaces;
2862                                 }
2863
2864                                 if (IsGeneric && TypeManager.IsAttributeType (base_class.Type)) {
2865                                         Report.Error (698, base_class.Location,
2866                                                 "A generic type cannot derive from `{0}' because it is an attribute class",
2867                                                 base_class.GetSignatureForError ());
2868                                 }
2869
2870                                 if (base_class.IsSealed){
2871                                         Report.SymbolRelatedToPreviousError (base_class.Type);
2872                                         if (base_class.Type.IsAbstract) {
2873                                                 Report.Error (709, Location, "`{0}': Cannot derive from static class `{1}'",
2874                                                         GetSignatureForError (), TypeManager.CSharpName (base_class.Type));
2875                                         } else {
2876                                                 Report.Error (509, Location, "`{0}': cannot derive from sealed type `{1}'",
2877                                                         GetSignatureForError (), TypeManager.CSharpName (base_class.Type));
2878                                         }
2879                                         return ifaces;
2880                                 }
2881
2882                                 if (!base_class.CanInheritFrom ()){
2883                                         Report.Error (644, Location, "`{0}' cannot derive from special class `{1}'",
2884                                                 GetSignatureForError (), base_class.GetSignatureForError ());
2885                                         return ifaces;
2886                                 }
2887
2888                                 if (!IsAccessibleAs (base_class.Type)) {
2889                                         Report.SymbolRelatedToPreviousError (base_class.Type);
2890                                         Report.Error (60, Location, "Inconsistent accessibility: base class `{0}' is less accessible than class `{1}'", 
2891                                                 TypeManager.CSharpName (base_class.Type), GetSignatureForError ());
2892                                 }
2893                         }
2894
2895                         if (PartialContainer.IsStaticClass) {
2896                                 if (base_class.Type != TypeManager.object_type) {
2897                                         Report.Error (713, Location, "Static class `{0}' cannot derive from type `{1}'. Static classes must derive from object",
2898                                                 GetSignatureForError (), base_class.GetSignatureForError ());
2899                                         return ifaces;
2900                                 }
2901
2902                                 if (ifaces != null) {
2903                                         foreach (TypeExpr t in ifaces)
2904                                                 Report.SymbolRelatedToPreviousError (t.Type);
2905                                         Report.Error (714, Location, "Static class `{0}' cannot implement interfaces", GetSignatureForError ());
2906                                 }
2907                         }
2908
2909                         return ifaces;
2910                 }
2911
2912                 /// Search for at least one defined condition in ConditionalAttribute of attribute class
2913                 /// Valid only for attribute classes.
2914                 public bool IsExcluded ()
2915                 {
2916                         if ((caching_flags & Flags.Excluded_Undetected) == 0)
2917                                 return (caching_flags & Flags.Excluded) != 0;
2918
2919                         caching_flags &= ~Flags.Excluded_Undetected;
2920
2921                         if (OptAttributes == null)
2922                                 return false;
2923
2924                         Attribute[] attrs = OptAttributes.SearchMulti (PredefinedAttributes.Get.Conditional);
2925                         if (attrs == null)
2926                                 return false;
2927
2928                         foreach (Attribute a in attrs) {
2929                                 string condition = a.GetConditionalAttributeValue ();
2930                                 if (Location.CompilationUnit.IsConditionalDefined (condition))
2931                                         return false;
2932                         }
2933
2934                         caching_flags |= Flags.Excluded;
2935                         return true;
2936                 }
2937
2938                 //
2939                 // FIXME: How do we deal with the user specifying a different
2940                 // layout?
2941                 //
2942                 protected override TypeAttributes TypeAttr {
2943                         get {
2944                                 TypeAttributes ta = base.TypeAttr | TypeAttributes.AutoLayout | TypeAttributes.Class;
2945                                 if (IsStatic)
2946                                         ta |= StaticClassAttribute;
2947                                 return ta;
2948                         }
2949                 }
2950         }
2951
2952         public sealed class Struct : ClassOrStruct {
2953
2954                 bool is_unmanaged, has_unmanaged_check_done;
2955
2956                 // <summary>
2957                 //   Modifiers allowed in a struct declaration
2958                 // </summary>
2959                 const Modifiers AllowedModifiers =
2960                         Modifiers.NEW       |
2961                         Modifiers.PUBLIC    |
2962                         Modifiers.PROTECTED |
2963                         Modifiers.INTERNAL  |
2964                         Modifiers.UNSAFE    |
2965                         Modifiers.PRIVATE;
2966
2967                 public Struct (NamespaceEntry ns, DeclSpace parent, MemberName name,
2968                                Modifiers mod, Attributes attrs)
2969                         : base (ns, parent, name, attrs, Kind.Struct)
2970                 {
2971                         var accmods = parent.Parent == null ? Modifiers.INTERNAL : Modifiers.PRIVATE;
2972                         
2973                         this.ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, accmods, Location, Report);
2974
2975                         this.ModFlags |= Modifiers.SEALED;
2976                 }
2977
2978                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
2979                 {
2980                         base.ApplyAttributeBuilder (a, cb, pa);
2981
2982                         //
2983                         // When struct constains fixed fixed and struct layout has explicitly
2984                         // set CharSet, its value has to be propagated to compiler generated
2985                         // fixed field types
2986                         //
2987                         if (a.Type == pa.StructLayout && Fields != null && a.HasField ("CharSet")) {
2988                                 for (int i = 0; i < Fields.Count; ++i) {
2989                                         FixedField ff = Fields [i] as FixedField;
2990                                         if (ff != null)
2991                                                 ff.SetCharSet (TypeBuilder.Attributes);
2992                                 }
2993                         }
2994                 }
2995
2996                 public override AttributeTargets AttributeTargets {
2997                         get {
2998                                 return AttributeTargets.Struct;
2999                         }
3000                 }
3001
3002                 public override bool IsUnmanagedType ()
3003                 {
3004                         if (fields == null)
3005                                 return true;
3006
3007                         if (requires_delayed_unmanagedtype_check)
3008                                 return true;
3009
3010                         if (has_unmanaged_check_done)
3011                                 return is_unmanaged;
3012
3013                         has_unmanaged_check_done = true;
3014
3015                         foreach (FieldBase f in fields) {
3016                                 if ((f.ModFlags & Modifiers.STATIC) != 0)
3017                                         continue;
3018
3019                                 // It can happen when recursive unmanaged types are defined
3020                                 // struct S { S* s; }
3021                                 Type mt = f.MemberType;
3022                                 if (mt == null) {
3023                                         has_unmanaged_check_done = false;
3024                                         requires_delayed_unmanagedtype_check = true;
3025                                         return true;
3026                                 }
3027
3028                                 // TODO: Remove when pointer types are under mcs control
3029                                 while (mt.IsPointer)
3030                                         mt = TypeManager.GetElementType (mt);
3031                                 if (TypeManager.IsEqual (mt, TypeBuilder))
3032                                         continue;
3033
3034                                 if (TypeManager.IsUnmanagedType (mt))
3035                                         continue;
3036
3037                                 return false;
3038                         }
3039
3040                         is_unmanaged = true;
3041                         return true;
3042                 }
3043
3044                 protected override TypeExpr[] ResolveBaseTypes (out TypeExpr base_class)
3045                 {
3046                         TypeExpr[] ifaces = base.ResolveBaseTypes (out base_class);
3047                         //
3048                         // If we are compiling our runtime,
3049                         // and we are defining ValueType, then our
3050                         // base is `System.Object'.
3051                         //
3052                         if (base_class == null) {
3053                                 if (!RootContext.StdLib && Name == "System.ValueType")
3054                                         base_class = TypeManager.system_object_expr;
3055                                 else
3056                                         base_class = TypeManager.system_valuetype_expr;
3057                         }
3058
3059                         return ifaces;
3060                 }
3061
3062                 //
3063                 // FIXME: Allow the user to specify a different set of attributes
3064                 // in some cases (Sealed for example is mandatory for a class,
3065                 // but what SequentialLayout can be changed
3066                 //
3067                 protected override TypeAttributes TypeAttr {
3068                         get {
3069                                 const TypeAttributes DefaultTypeAttributes =
3070                                         TypeAttributes.SequentialLayout |
3071                                         TypeAttributes.Sealed;
3072
3073                                 return base.TypeAttr | DefaultTypeAttributes;
3074                         }
3075                 }
3076
3077                 public override void RegisterFieldForInitialization (MemberCore field, FieldInitializer expression)
3078                 {
3079                         if ((field.ModFlags & Modifiers.STATIC) == 0) {
3080                                 Report.Error (573, field.Location, "`{0}': Structs cannot have instance field initializers",
3081                                         field.GetSignatureForError ());
3082                                 return;
3083                         }
3084                         base.RegisterFieldForInitialization (field, expression);
3085                 }
3086
3087         }
3088
3089         /// <summary>
3090         ///   Interfaces
3091         /// </summary>
3092         public sealed class Interface : TypeContainer, IMemberContainer {
3093
3094                 /// <summary>
3095                 ///   Modifiers allowed in a class declaration
3096                 /// </summary>
3097                 public const Modifiers AllowedModifiers =
3098                         Modifiers.NEW       |
3099                         Modifiers.PUBLIC    |
3100                         Modifiers.PROTECTED |
3101                         Modifiers.INTERNAL  |
3102                         Modifiers.UNSAFE    |
3103                         Modifiers.PRIVATE;
3104
3105                 public Interface (NamespaceEntry ns, DeclSpace parent, MemberName name, Modifiers mod,
3106                                   Attributes attrs)
3107                         : base (ns, parent, name, attrs, Kind.Interface)
3108                 {
3109                         var accmods = parent.Parent == null ? Modifiers.INTERNAL : Modifiers.PRIVATE;
3110
3111                         this.ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, accmods, name.Location, Report);
3112                 }
3113
3114                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
3115                 {
3116                         if (a.Type == pa.ComImport && !attributes.Contains (pa.Guid)) {
3117                                 a.Error_MissingGuidAttribute ();
3118                                 return;
3119                         }
3120
3121                         base.ApplyAttributeBuilder (a, cb, pa);
3122                 }
3123
3124
3125                 public override AttributeTargets AttributeTargets {
3126                         get {
3127                                 return AttributeTargets.Interface;
3128                         }
3129                 }
3130
3131                 protected override TypeAttributes TypeAttr {
3132                         get {
3133                                 const TypeAttributes DefaultTypeAttributes =
3134                                         TypeAttributes.AutoLayout |
3135                                         TypeAttributes.Abstract |
3136                                         TypeAttributes.Interface;
3137
3138                                 return base.TypeAttr | DefaultTypeAttributes;
3139                         }
3140                 }
3141
3142                 protected override bool VerifyClsCompliance ()
3143                 {
3144                         if (!base.VerifyClsCompliance ())
3145                                 return false;
3146
3147                         if (ifaces != null) {
3148                                 foreach (Type t in ifaces) {
3149                                         if (AttributeTester.IsClsCompliant (t))
3150                                                 continue;
3151
3152                                         Report.SymbolRelatedToPreviousError (t);
3153                                         Report.Warning (3027, 1, Location, "`{0}' is not CLS-compliant because base interface `{1}' is not CLS-compliant",
3154                                                 GetSignatureForError (), TypeManager.CSharpName (t));
3155                                 }
3156                         }
3157
3158                         return true;
3159                 }
3160         }
3161
3162         // It is used as a base class for all property based members
3163         // This includes properties, indexers, and events
3164         public abstract class PropertyBasedMember : InterfaceMemberBase
3165         {
3166                 public PropertyBasedMember (DeclSpace parent, GenericMethod generic,
3167                         FullNamedExpression type, Modifiers mod, Modifiers allowed_mod,
3168                         MemberName name, Attributes attrs)
3169                         : base (parent, generic, type, mod, allowed_mod, name, attrs)
3170                 {
3171                 }
3172
3173                 protected override bool VerifyClsCompliance ()
3174                 {
3175                         if (!base.VerifyClsCompliance ())
3176                                 return false;
3177
3178                         if (!AttributeTester.IsClsCompliant (MemberType)) {
3179                                 Report.Warning (3003, 1, Location, "Type of `{0}' is not CLS-compliant",
3180                                         GetSignatureForError ());
3181                         }
3182                         return true;
3183                 }
3184
3185         }
3186
3187         public abstract class InterfaceMemberBase : MemberBase {
3188                 //
3189                 // Whether this is an interface member.
3190                 //
3191                 public bool IsInterface;
3192
3193                 //
3194                 // If true, this is an explicit interface implementation
3195                 //
3196                 public bool IsExplicitImpl;
3197
3198                 protected bool is_external_implementation;
3199
3200                 //
3201                 // The interface type we are explicitly implementing
3202                 //
3203                 public Type InterfaceType;
3204
3205                 //
3206                 // The method we're overriding if this is an override method.
3207                 //
3208                 protected MethodInfo base_method;
3209
3210                 readonly Modifiers explicit_mod_flags;
3211                 public MethodAttributes flags;
3212
3213                 public InterfaceMemberBase (DeclSpace parent, GenericMethod generic,
3214                                    FullNamedExpression type, Modifiers mod, Modifiers allowed_mod,
3215                                    MemberName name, Attributes attrs)
3216                         : base (parent, generic, type, mod, allowed_mod, Modifiers.PRIVATE,
3217                                 name, attrs)
3218                 {
3219                         IsInterface = parent.PartialContainer.Kind == Kind.Interface;
3220                         IsExplicitImpl = (MemberName.Left != null);
3221                         explicit_mod_flags = mod;
3222                 }
3223                 
3224                 protected override bool CheckBase ()
3225                 {
3226                         if (!base.CheckBase ())
3227                                 return false;
3228
3229                         if ((caching_flags & Flags.MethodOverloadsExist) != 0)
3230                                 CheckForDuplications ();
3231                         
3232                         if (IsExplicitImpl)
3233                                 return true;
3234
3235                         // Is null for System.Object while compiling corlib and base interfaces
3236                         if (Parent.PartialContainer.BaseCache == null) {
3237                                 if ((ModFlags & Modifiers.NEW) != 0) {
3238                                         Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
3239                                 }
3240                                 return true;
3241                         }
3242
3243                         Type base_ret_type = null;
3244                         base_method = FindOutBaseMethod (ref base_ret_type);
3245
3246                         // method is override
3247                         if (base_method != null) {
3248                                 if (!CheckMethodAgainstBase (base_ret_type))
3249                                         return false;
3250
3251                                 if ((ModFlags & Modifiers.OVERRIDE) != 0) {
3252                                         ObsoleteAttribute oa = AttributeTester.GetMethodObsoleteAttribute (base_method);
3253                                         if (oa != null) {
3254                                                 if (OptAttributes == null || !OptAttributes.Contains (PredefinedAttributes.Get.Obsolete)) {
3255                                                         Report.SymbolRelatedToPreviousError (base_method);
3256                                                                 Report.Warning (672, 1, Location, "Member `{0}' overrides obsolete member `{1}'. Add the Obsolete attribute to `{0}'",
3257                                                                         GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3258                                                 }
3259                                         } else {
3260                                                 if (OptAttributes != null && OptAttributes.Contains (PredefinedAttributes.Get.Obsolete)) {
3261                                                         Report.SymbolRelatedToPreviousError (base_method);
3262                                                         Report.Warning (809, 1, Location, "Obsolete member `{0}' overrides non-obsolete member `{1}'",
3263                                                                 GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3264                                                 }
3265                                         }
3266                                 }
3267                                 return true;
3268                         }
3269
3270                         MemberInfo conflict_symbol = Parent.PartialContainer.FindBaseMemberWithSameName (Name, !((this is Event) || (this is Property)));
3271                         if ((ModFlags & Modifiers.OVERRIDE) != 0) {
3272                                 if (conflict_symbol != null) {
3273                                         Report.SymbolRelatedToPreviousError (conflict_symbol);
3274                                         if (this is Event)
3275                                                 Report.Error (72, Location, "`{0}': cannot override because `{1}' is not an event", GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
3276                                         else if (this is PropertyBase)
3277                                                 Report.Error (544, Location, "`{0}': cannot override because `{1}' is not a property", GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
3278                                         else
3279                                                 Report.Error (505, Location, "`{0}': cannot override because `{1}' is not a method", GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
3280                                 } else {
3281                                         Report.Error (115, Location, "`{0}' is marked as an override but no suitable {1} found to override",
3282                                                 GetSignatureForError (), SimpleName.GetMemberType (this));
3283                                 }
3284                                 return false;
3285                         }
3286
3287                         if (conflict_symbol == null) {
3288                                 if ((ModFlags & Modifiers.NEW) != 0) {
3289                                         Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
3290                                 }
3291                                 return true;
3292                         }
3293
3294                         if ((ModFlags & Modifiers.NEW) == 0) {
3295                                 if (this is MethodOrOperator && conflict_symbol.MemberType == MemberTypes.Method)
3296                                         return true;
3297
3298                                 Report.SymbolRelatedToPreviousError (conflict_symbol);
3299                                 Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
3300                                         GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
3301                         }
3302
3303                         return true;
3304                 }
3305
3306                 protected virtual bool CheckForDuplications ()
3307                 {
3308                         return Parent.MemberCache.CheckExistingMembersOverloads (
3309                                 this, GetFullName (MemberName), ParametersCompiled.EmptyReadOnlyParameters, Report);
3310                 }
3311
3312                 //
3313                 // Performs various checks on the MethodInfo `mb' regarding the modifier flags
3314                 // that have been defined.
3315                 //
3316                 // `name' is the user visible name for reporting errors (this is used to
3317                 // provide the right name regarding method names and properties)
3318                 //
3319                 bool CheckMethodAgainstBase (Type base_method_type)
3320                 {
3321                         bool ok = true;
3322
3323                         if ((ModFlags & Modifiers.OVERRIDE) != 0){
3324                                 if (!(base_method.IsAbstract || base_method.IsVirtual)){
3325                                         Report.SymbolRelatedToPreviousError (base_method);
3326                                         Report.Error (506, Location,
3327                                                 "`{0}': cannot override inherited member `{1}' because it is not marked virtual, abstract or override",
3328                                                  GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3329                                         ok = false;
3330                                 }
3331                                 
3332                                 // Now we check that the overriden method is not final
3333                                 
3334                                 if (base_method.IsFinal) {
3335                                         Report.SymbolRelatedToPreviousError (base_method);
3336                                         Report.Error (239, Location, "`{0}': cannot override inherited member `{1}' because it is sealed",
3337                                                               GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3338                                         ok = false;
3339                                 }
3340                                 //
3341                                 // Check that the permissions are not being changed
3342                                 //
3343                                 MethodAttributes thisp = flags & MethodAttributes.MemberAccessMask;
3344                                 MethodAttributes base_classp = base_method.Attributes & MethodAttributes.MemberAccessMask;
3345
3346                                 if (!CheckAccessModifiers (thisp, base_classp, base_method)) {
3347                                         Error_CannotChangeAccessModifiers (Location, base_method, base_classp, null);
3348                                         ok = false;
3349                                 }
3350
3351                                 if (!TypeManager.IsEqual (MemberType, TypeManager.TypeToCoreType (base_method_type))) {
3352                                         Report.SymbolRelatedToPreviousError (base_method);
3353                                         if (this is PropertyBasedMember) {
3354                                                 Report.Error (1715, Location, "`{0}': type must be `{1}' to match overridden member `{2}'", 
3355                                                         GetSignatureForError (), TypeManager.CSharpName (base_method_type), TypeManager.CSharpSignature (base_method));
3356                                         }
3357                                         else {
3358                                                 Report.Error (508, Location, "`{0}': return type must be `{1}' to match overridden member `{2}'",
3359                                                         GetSignatureForError (), TypeManager.CSharpName (base_method_type), TypeManager.CSharpSignature (base_method));
3360                                         }
3361                                         ok = false;
3362                                 }
3363                         }
3364
3365                         if ((ModFlags & Modifiers.NEW) == 0) {
3366                                 if ((ModFlags & Modifiers.OVERRIDE) == 0) {
3367                                         ModFlags |= Modifiers.NEW;
3368                                         Report.SymbolRelatedToPreviousError (base_method);
3369                                         if (!IsInterface && (base_method.IsVirtual || base_method.IsAbstract)) {
3370                                                 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",
3371                                                         GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3372                                                 if (base_method.IsAbstract){
3373                                                         Report.Error (533, Location, "`{0}' hides inherited abstract member `{1}'",
3374                                                                       GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3375                                                         ok = false;
3376                                                 }
3377                                         } else {
3378                                                 Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
3379                                                         GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3380                                         }
3381                                 }
3382                         } else {
3383                                 if (base_method.IsAbstract && !IsInterface) {
3384                                         Report.SymbolRelatedToPreviousError (base_method);
3385                                         Report.Error (533, Location, "`{0}' hides inherited abstract member `{1}'",
3386                                                 GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3387                                         return ok = false;
3388                                 }
3389                         }
3390
3391                         return ok;
3392                 }
3393                 
3394                 protected bool CheckAccessModifiers (MethodAttributes thisp, MethodAttributes base_classp, MethodInfo base_method)
3395                 {
3396                         if ((base_classp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
3397                                 //
3398                                 // when overriding protected internal, the method can be declared
3399                                 // protected internal only within the same assembly or assembly
3400                                 // which has InternalsVisibleTo
3401                                 //
3402                                 if ((thisp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
3403                                         return TypeManager.IsThisOrFriendAssembly (Parent.Module.Assembly, base_method.DeclaringType.Assembly);
3404                                 } else if ((thisp & MethodAttributes.Family) != MethodAttributes.Family) {
3405                                         //
3406                                         // if it's not "protected internal", it must be "protected"
3407                                         //
3408
3409                                         return false;
3410                                 } else if (Parent.TypeBuilder.Assembly == base_method.DeclaringType.Assembly) {
3411                                         //
3412                                         // protected within the same assembly - an error
3413                                         //
3414                                         return false;
3415                                 } else if ((thisp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem)) != 
3416                                            (base_classp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem))) {
3417                                         //
3418                                         // protected ok, but other attributes differ - report an error
3419                                         //
3420                                         return false;
3421                                 }
3422                                 return true;
3423                         } else {
3424                                 return (thisp == base_classp);
3425                         }
3426                 }
3427
3428                 public override bool Define ()
3429                 {
3430                         if (IsInterface) {
3431                                 ModFlags = Modifiers.PUBLIC | Modifiers.ABSTRACT |
3432                                         Modifiers.VIRTUAL | (ModFlags & (Modifiers.UNSAFE | Modifiers.NEW));
3433
3434                                 flags = MethodAttributes.Public |
3435                                         MethodAttributes.Abstract |
3436                                         MethodAttributes.HideBySig |
3437                                         MethodAttributes.NewSlot |
3438                                         MethodAttributes.Virtual;
3439                         } else {
3440                                 Parent.PartialContainer.MethodModifiersValid (this);
3441
3442                                 flags = ModifiersExtensions.MethodAttr (ModFlags);
3443                         }
3444
3445                         if (IsExplicitImpl) {
3446                                 TypeExpr iface_texpr = MemberName.Left.GetTypeExpression ().ResolveAsTypeTerminal (this, false);
3447                                 if (iface_texpr == null)
3448                                         return false;
3449
3450                                 if ((ModFlags & Modifiers.PARTIAL) != 0) {
3451                                         Report.Error (754, Location, "A partial method `{0}' cannot explicitly implement an interface",
3452                                                 GetSignatureForError ());
3453                                 }
3454
3455                                 InterfaceType = iface_texpr.Type;
3456
3457                                 if (!InterfaceType.IsInterface) {
3458                                         Report.SymbolRelatedToPreviousError (InterfaceType);
3459                                         Report.Error (538, Location, "The type `{0}' in explicit interface declaration is not an interface",
3460                                                 TypeManager.CSharpName (InterfaceType));
3461                                 } else {
3462                                         Parent.PartialContainer.VerifyImplements (this);
3463                                 }
3464
3465                                 ModifiersExtensions.Check (Modifiers.AllowedExplicitImplFlags, explicit_mod_flags, 0, Location, Report);
3466                         }
3467
3468                         return base.Define ();
3469                 }
3470
3471                 protected bool DefineParameters (ParametersCompiled parameters)
3472                 {
3473                         if (!parameters.Resolve (this))
3474                                 return false;
3475
3476                         bool error = false;
3477                         for (int i = 0; i < parameters.Count; ++i) {
3478                                 Parameter p = parameters [i];
3479
3480                                 if (p.HasDefaultValue && (IsExplicitImpl || this is Operator || (this is Indexer && parameters.Count == 1)))
3481                                         p.Warning_UselessOptionalParameter (Report);
3482
3483                                 if (p.CheckAccessibility (this))
3484                                         continue;
3485
3486                                 Type t = parameters.Types [i];
3487                                 Report.SymbolRelatedToPreviousError (t);
3488                                 if (this is Indexer)
3489                                         Report.Error (55, Location,
3490                                                       "Inconsistent accessibility: parameter type `{0}' is less accessible than indexer `{1}'",
3491                                                       TypeManager.CSharpName (t), GetSignatureForError ());
3492                                 else if (this is Operator)
3493                                         Report.Error (57, Location,
3494                                                       "Inconsistent accessibility: parameter type `{0}' is less accessible than operator `{1}'",
3495                                                       TypeManager.CSharpName (t), GetSignatureForError ());
3496                                 else
3497                                         Report.Error (51, Location,
3498                                                 "Inconsistent accessibility: parameter type `{0}' is less accessible than method `{1}'",
3499                                                 TypeManager.CSharpName (t), GetSignatureForError ());
3500                                 error = true;
3501                         }
3502                         return !error;
3503                 }
3504
3505                 public override void Emit()
3506                 {
3507                         // for extern static method must be specified either DllImport attribute or MethodImplAttribute.
3508                         // We are more strict than csc and report this as an error because SRE does not allow emit that
3509                         if ((ModFlags & Modifiers.EXTERN) != 0 && !is_external_implementation) {
3510                                 if (this is Constructor) {
3511                                         Report.Error (824, Location,
3512                                                 "Constructor `{0}' is marked `external' but has no external implementation specified", GetSignatureForError ());
3513                                 } else {
3514                                         Report.Error (626, Location,
3515                                                 "`{0}' is marked as an external but has no DllImport attribute. Consider adding a DllImport attribute to specify the external implementation",
3516                                                 GetSignatureForError ());
3517                                 }
3518                         }
3519
3520                         base.Emit ();
3521                 }
3522
3523                 public override bool EnableOverloadChecks (MemberCore overload)
3524                 {
3525                         //
3526                         // Two members can differ in their explicit interface
3527                         // type parameter only
3528                         //
3529                         InterfaceMemberBase imb = overload as InterfaceMemberBase;
3530                         if (imb != null && imb.IsExplicitImpl) {
3531                                 if (IsExplicitImpl) {
3532                                         caching_flags |= Flags.MethodOverloadsExist;
3533                                 }
3534                                 return true;
3535                         }
3536
3537                         return IsExplicitImpl;
3538                 }
3539
3540                 protected void Error_CannotChangeAccessModifiers (Location loc, MemberInfo base_method, MethodAttributes ma, string suffix)
3541                 {
3542                         Report.SymbolRelatedToPreviousError (base_method);
3543                         string base_name = TypeManager.GetFullNameSignature (base_method);
3544                         string this_name = GetSignatureForError ();
3545                         if (suffix != null) {
3546                                 base_name += suffix;
3547                                 this_name += suffix;
3548                         }
3549
3550                         Report.Error (507, loc, "`{0}': cannot change access modifiers when overriding `{1}' inherited member `{2}'",
3551                                 this_name, ModifiersExtensions.GetDescription (ma), base_name);
3552                 }
3553
3554                 protected static string Error722 {
3555                         get {
3556                                 return "`{0}': static types cannot be used as return types";
3557                         }
3558                 }
3559
3560                 /// <summary>
3561                 /// Gets base method and its return type
3562                 /// </summary>
3563                 protected abstract MethodInfo FindOutBaseMethod (ref Type base_ret_type);
3564
3565                 //
3566                 // The "short" name of this property / indexer / event.  This is the
3567                 // name without the explicit interface.
3568                 //
3569                 public string ShortName 
3570                 {
3571                         get { return MemberName.Name; }
3572                         set { SetMemberName (new MemberName (MemberName.Left, value, Location)); }
3573                 }
3574                 
3575                 //
3576                 // Returns full metadata method name
3577                 //
3578                 public string GetFullName (MemberName name)
3579                 {
3580                         if (!IsExplicitImpl)
3581                                 return name.Name;
3582
3583                         //
3584                         // When dealing with explicit members a full interface type
3585                         // name is added to member name to avoid possible name conflicts
3586                         //
3587                         // We use CSharpName which gets us full name with benefit of
3588                         // replacing predefined names which saves some space and name
3589                         // is still unique
3590                         //
3591                         return TypeManager.CSharpName (InterfaceType) + "." + name.Name;
3592                 }
3593
3594                 protected override bool VerifyClsCompliance ()
3595                 {
3596                         if (!base.VerifyClsCompliance ()) {
3597                                 if (IsInterface && HasClsCompliantAttribute && Parent.IsClsComplianceRequired ()) {
3598                                         Report.Warning (3010, 1, Location, "`{0}': CLS-compliant interfaces must have only CLS-compliant members", GetSignatureForError ());
3599                                 }
3600
3601                                 if ((ModFlags & Modifiers.ABSTRACT) != 0 && Parent.TypeBuilder.IsClass && IsExposedFromAssembly () && Parent.IsClsComplianceRequired ()) {
3602                                         Report.Warning (3011, 1, Location, "`{0}': only CLS-compliant members can be abstract", GetSignatureForError ());
3603                                 }
3604                                 return false;
3605                         }
3606
3607                         if (GenericMethod != null)
3608                                 GenericMethod.VerifyClsCompliance ();
3609
3610                         return true;
3611                 }
3612
3613                 public override bool IsUsed 
3614                 {
3615                         get { return IsExplicitImpl || base.IsUsed; }
3616                 }
3617
3618         }
3619
3620         public abstract class MemberBase : MemberCore
3621         {
3622                 protected FullNamedExpression type_name;
3623                 protected Type member_type;
3624
3625                 public readonly DeclSpace ds;
3626                 public readonly GenericMethod GenericMethod;
3627
3628                 protected MemberBase (DeclSpace parent, GenericMethod generic,
3629                                           FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, Modifiers def_mod,
3630                                       MemberName name, Attributes attrs)
3631                         : base (parent, name, attrs)
3632                 {
3633                         this.ds = generic != null ? generic : (DeclSpace) parent;
3634                         this.type_name = type;
3635                         ModFlags = ModifiersExtensions.Check (allowed_mod, mod, def_mod, Location, Report);
3636                         GenericMethod = generic;
3637                         if (GenericMethod != null)
3638                                 GenericMethod.ModFlags = ModFlags;
3639                 }
3640
3641                 //
3642                 // Main member define entry
3643                 //
3644                 public override bool Define ()
3645                 {
3646                         DoMemberTypeIndependentChecks ();
3647
3648                         //
3649                         // Returns false only when type resolution failed
3650                         //
3651                         if (!ResolveMemberType ())
3652                                 return false;
3653
3654                         DoMemberTypeDependentChecks ();
3655                         return true;
3656                 }
3657
3658                 //
3659                 // Any type_name independent checks
3660                 //
3661                 protected virtual void DoMemberTypeIndependentChecks ()
3662                 {
3663                         if ((Parent.ModFlags & Modifiers.SEALED) != 0 &&
3664                                 (ModFlags & (Modifiers.VIRTUAL | Modifiers.ABSTRACT)) != 0) {
3665                                 Report.Error (549, Location, "New virtual member `{0}' is declared in a sealed class `{1}'",
3666                                         GetSignatureForError (), Parent.GetSignatureForError ());
3667                         }
3668                 }
3669
3670                 //
3671                 // Any type_name dependent checks
3672                 //
3673                 protected virtual void DoMemberTypeDependentChecks ()
3674                 {
3675                         // verify accessibility
3676                         if (!IsAccessibleAs (MemberType)) {
3677                                 Report.SymbolRelatedToPreviousError (MemberType);
3678                                 if (this is Property)
3679                                         Report.Error (53, Location,
3680                                                       "Inconsistent accessibility: property type `" +
3681                                                       TypeManager.CSharpName (MemberType) + "' is less " +
3682                                                       "accessible than property `" + GetSignatureForError () + "'");
3683                                 else if (this is Indexer)
3684                                         Report.Error (54, Location,
3685                                                       "Inconsistent accessibility: indexer return type `" +
3686                                                       TypeManager.CSharpName (MemberType) + "' is less " +
3687                                                       "accessible than indexer `" + GetSignatureForError () + "'");
3688                                 else if (this is MethodCore) {
3689                                         if (this is Operator)
3690                                                 Report.Error (56, Location,
3691                                                               "Inconsistent accessibility: return type `" +
3692                                                               TypeManager.CSharpName (MemberType) + "' is less " +
3693                                                               "accessible than operator `" + GetSignatureForError () + "'");
3694                                         else
3695                                                 Report.Error (50, Location,
3696                                                               "Inconsistent accessibility: return type `" +
3697                                                               TypeManager.CSharpName (MemberType) + "' is less " +
3698                                                               "accessible than method `" + GetSignatureForError () + "'");
3699                                 } else {
3700                                         Report.Error (52, Location,
3701                                                       "Inconsistent accessibility: field type `" +
3702                                                       TypeManager.CSharpName (MemberType) + "' is less " +
3703                                                       "accessible than field `" + GetSignatureForError () + "'");
3704                                 }
3705                         }
3706
3707                         Variance variance = this is Event ? Variance.Contravariant : Variance.Covariant;
3708                         TypeManager.CheckTypeVariance (MemberType, variance, this);
3709                 }
3710
3711                 protected bool IsTypePermitted ()
3712                 {
3713                         if (TypeManager.IsSpecialType (MemberType)) {
3714                                 Report.Error (610, Location, "Field or property cannot be of type `{0}'", TypeManager.CSharpName (MemberType));
3715                                 return false;
3716                         }
3717                         return true;
3718                 }
3719
3720                 protected virtual bool CheckBase ()
3721                 {
3722                         CheckProtectedModifier ();
3723
3724                         return true;
3725                 }
3726
3727                 public Type MemberType {
3728                         get { return member_type; }
3729                 }
3730
3731                 protected virtual bool ResolveMemberType ()
3732                 {
3733                         if (member_type != null)
3734                                 throw new InternalErrorException ("Multi-resolve");
3735
3736                         TypeExpr te = type_name.ResolveAsTypeTerminal (this, false);
3737                         if (te == null)
3738                                 return false;
3739                         
3740                         //
3741                         // Replace original type name, error reporting can use fully resolved name
3742                         //
3743                         type_name = te;
3744
3745                         member_type = te.Type;
3746                         return true;
3747                 }
3748         }
3749
3750         //
3751         // `set' and `get' accessors are represented with an Accessor.
3752         // 
3753         public class Accessor {
3754                 //
3755                 // Null if the accessor is empty, or a Block if not
3756                 //
3757                 public const Modifiers AllowedModifiers = 
3758                         Modifiers.PUBLIC |
3759                         Modifiers.PROTECTED |
3760                         Modifiers.INTERNAL |
3761                         Modifiers.PRIVATE;
3762                 
3763                 public ToplevelBlock Block;
3764                 public Attributes Attributes;
3765                 public Location Location;
3766                 public Modifiers ModFlags;
3767                 public ParametersCompiled Parameters;
3768                 
3769                 public Accessor (ToplevelBlock b, Modifiers mod, Attributes attrs, ParametersCompiled p, Location loc)
3770                 {
3771                         Block = b;
3772                         Attributes = attrs;
3773                         Location = loc;
3774                         Parameters = p;
3775                         ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, 0, loc, RootContext.ToplevelTypes.Compiler.Report);
3776                 }
3777         }
3778
3779         //
3780         // Properties and Indexers both generate PropertyBuilders, we use this to share 
3781         // their common bits.
3782         //
3783         abstract public class PropertyBase : PropertyBasedMember {
3784
3785                 public class GetMethod : PropertyMethod
3786                 {
3787                         static string[] attribute_targets = new string [] { "method", "return" };
3788
3789                         public GetMethod (PropertyBase method):
3790                                 base (method, "get_")
3791                         {
3792                         }
3793
3794                         public GetMethod (PropertyBase method, Accessor accessor):
3795                                 base (method, accessor, "get_")
3796                         {
3797                         }
3798
3799                         public override MethodBuilder Define (DeclSpace parent)
3800                         {
3801                                 base.Define (parent);
3802
3803                                 if (IsDummy)
3804                                         return null;
3805                                 
3806                                 method_data = new MethodData (method, ModFlags, flags, this);
3807
3808                                 if (!method_data.Define (parent, method.GetFullName (MemberName), Report))
3809                                         return null;
3810
3811                                 return method_data.MethodBuilder;
3812                         }
3813
3814                         public override Type ReturnType {
3815                                 get {
3816                                         return method.MemberType;
3817                                 }
3818                         }
3819
3820                         public override ParametersCompiled ParameterInfo {
3821                                 get {
3822                                         return ParametersCompiled.EmptyReadOnlyParameters;
3823                                 }
3824                         }
3825
3826                         public override string[] ValidAttributeTargets {
3827                                 get {
3828                                         return attribute_targets;
3829                                 }
3830                         }
3831                 }
3832
3833                 public class SetMethod : PropertyMethod {
3834
3835                         static string[] attribute_targets = new string [] { "method", "param", "return" };
3836                         ImplicitParameter param_attr;
3837                         protected ParametersCompiled parameters;
3838
3839                         public SetMethod (PropertyBase method) :
3840                                 base (method, "set_")
3841                         {
3842                                 parameters = new ParametersCompiled (Compiler,
3843                                         new Parameter (method.type_name, "value", Parameter.Modifier.NONE, null, Location));
3844                         }
3845
3846                         public SetMethod (PropertyBase method, Accessor accessor):
3847                                 base (method, accessor, "set_")
3848                         {
3849                                 this.parameters = accessor.Parameters;
3850                         }
3851
3852                         protected override void ApplyToExtraTarget (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
3853                         {
3854                                 if (a.Target == AttributeTargets.Parameter) {
3855                                         if (param_attr == null)
3856                                                 param_attr = new ImplicitParameter (method_data.MethodBuilder);
3857
3858                                         param_attr.ApplyAttributeBuilder (a, cb, pa);
3859                                         return;
3860                                 }
3861
3862                                 base.ApplyAttributeBuilder (a, cb, pa);
3863                         }
3864
3865                         public override ParametersCompiled ParameterInfo {
3866                             get {
3867                                 return parameters;
3868                             }
3869                         }
3870
3871                         public override MethodBuilder Define (DeclSpace parent)
3872                         {
3873                                 parameters.Resolve (this);
3874                                 
3875                                 base.Define (parent);
3876
3877                                 if (IsDummy)
3878                                         return null;
3879
3880                                 method_data = new MethodData (method, ModFlags, flags, this);
3881
3882                                 if (!method_data.Define (parent, method.GetFullName (MemberName), Report))
3883                                         return null;
3884
3885                                 return method_data.MethodBuilder;
3886                         }
3887
3888                         public override Type ReturnType {
3889                                 get {
3890                                         return TypeManager.void_type;
3891                                 }
3892                         }
3893
3894                         public override string[] ValidAttributeTargets {
3895                                 get {
3896                                         return attribute_targets;
3897                                 }
3898                         }
3899                 }
3900
3901                 static string[] attribute_targets = new string [] { "property" };
3902
3903                 public abstract class PropertyMethod : AbstractPropertyEventMethod
3904                 {
3905                         protected readonly PropertyBase method;
3906                         protected MethodAttributes flags;
3907
3908                         public PropertyMethod (PropertyBase method, string prefix)
3909                                 : base (method, prefix)
3910                         {
3911                                 this.method = method;
3912                                 this.ModFlags = method.ModFlags & (Modifiers.STATIC | Modifiers.UNSAFE);                                
3913                         }
3914
3915                         public PropertyMethod (PropertyBase method, Accessor accessor,
3916                                                string prefix)
3917                                 : base (method, accessor, prefix)
3918                         {
3919                                 this.method = method;
3920                                 this.ModFlags = accessor.ModFlags | (method.ModFlags & (Modifiers.STATIC | Modifiers.UNSAFE));
3921
3922                                 if (accessor.ModFlags != 0 && RootContext.Version == LanguageVersion.ISO_1) {
3923                                         Report.FeatureIsNotAvailable (Location, "access modifiers on properties");
3924                                 }
3925                         }
3926
3927                         public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
3928                         {
3929                                 if (a.IsInternalMethodImplAttribute) {
3930                                         method.is_external_implementation = true;
3931                                 }
3932
3933                                 base.ApplyAttributeBuilder (a, cb, pa);
3934                         }
3935
3936                         public override AttributeTargets AttributeTargets {
3937                                 get {
3938                                         return AttributeTargets.Method;
3939                                 }
3940                         }
3941
3942                         public override bool IsClsComplianceRequired ()
3943                         {
3944                                 return method.IsClsComplianceRequired ();
3945                         }
3946
3947                         public virtual MethodBuilder Define (DeclSpace parent)
3948                         {
3949                                 CheckForDuplications ();
3950
3951                                 if (IsDummy) {
3952                                         if (method.InterfaceType != null && parent.PartialContainer.PendingImplementations != null) {
3953                                                 MethodInfo mi = parent.PartialContainer.PendingImplementations.IsInterfaceMethod (
3954                                                         MethodName.Name, method.InterfaceType, new MethodData (method, ModFlags, flags, this));
3955                                                 if (mi != null) {
3956                                                         Report.SymbolRelatedToPreviousError (mi);
3957                                                         Report.Error (551, Location, "Explicit interface implementation `{0}' is missing accessor `{1}'",
3958                                                                 method.GetSignatureForError (), TypeManager.CSharpSignature (mi, true));
3959                                                 }
3960                                         }
3961                                         return null;
3962                                 }
3963
3964                                 TypeContainer container = parent.PartialContainer;
3965
3966                                 //
3967                                 // Check for custom access modifier
3968                                 //
3969                                 if ((ModFlags & Modifiers.AccessibilityMask) == 0) {
3970                                         ModFlags |= method.ModFlags;
3971                                         flags = method.flags;
3972                                 } else {
3973                                         if (container.Kind == Kind.Interface)
3974                                                 Report.Error (275, Location, "`{0}': accessibility modifiers may not be used on accessors in an interface",
3975                                                         GetSignatureForError ());
3976
3977                                         if ((method.ModFlags & Modifiers.ABSTRACT) != 0 && (ModFlags & Modifiers.PRIVATE) != 0) {
3978                                                 Report.Error (442, Location, "`{0}': abstract properties cannot have private accessors", GetSignatureForError ());
3979                                         }
3980
3981                                         CheckModifiers (ModFlags);
3982                                         ModFlags |= (method.ModFlags & (~Modifiers.AccessibilityMask));
3983                                         ModFlags |= Modifiers.PROPERTY_CUSTOM;
3984                                         flags = ModifiersExtensions.MethodAttr (ModFlags);
3985                                         flags |= (method.flags & (~MethodAttributes.MemberAccessMask));
3986                                 }
3987
3988                                 CheckAbstractAndExtern (block != null);
3989                                 CheckProtectedModifier ();
3990
3991                                 if (block != null && block.IsIterator)
3992                                         Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags, Compiler);
3993
3994                                 return null;
3995                         }
3996
3997                         public bool HasCustomAccessModifier {
3998                                 get {
3999                                         return (ModFlags & Modifiers.PROPERTY_CUSTOM) != 0;
4000                                 }
4001                         }
4002
4003                         public PropertyBase Property {
4004                                 get {
4005                                         return method;
4006                                 }
4007                         }
4008
4009                         public override ObsoleteAttribute GetObsoleteAttribute ()
4010                         {
4011                                 return method.GetObsoleteAttribute ();
4012                         }
4013
4014                         public override string GetSignatureForError()
4015                         {
4016                                 return method.GetSignatureForError () + '.' + prefix.Substring (0, 3);
4017                         }
4018
4019                         void CheckModifiers (Modifiers modflags)
4020                         {
4021                                 modflags &= Modifiers.AccessibilityMask;
4022                                 Modifiers flags = 0;
4023                                 Modifiers mflags = method.ModFlags & Modifiers.AccessibilityMask;
4024
4025                                 if ((mflags & Modifiers.PUBLIC) != 0) {
4026                                         flags |= Modifiers.PROTECTED | Modifiers.INTERNAL | Modifiers.PRIVATE;
4027                                 }
4028                                 else if ((mflags & Modifiers.PROTECTED) != 0) {
4029                                         if ((mflags & Modifiers.INTERNAL) != 0)
4030                                                 flags |= Modifiers.PROTECTED | Modifiers.INTERNAL;
4031
4032                                         flags |= Modifiers.PRIVATE;
4033                                 } else if ((mflags & Modifiers.INTERNAL) != 0)
4034                                         flags |= Modifiers.PRIVATE;
4035
4036                                 if ((mflags == modflags) || (modflags & (~flags)) != 0) {
4037                                         Report.Error (273, Location,
4038                                                 "The accessibility modifier of the `{0}' accessor must be more restrictive than the modifier of the property or indexer `{1}'",
4039                                                 GetSignatureForError (), method.GetSignatureForError ());
4040                                 }
4041                         }
4042
4043                         protected bool CheckForDuplications ()
4044                         {
4045                                 if ((caching_flags & Flags.MethodOverloadsExist) == 0)
4046                                         return true;
4047
4048                                 return Parent.MemberCache.CheckExistingMembersOverloads (this, Name, ParameterInfo, Report);
4049                         }
4050                 }
4051
4052                 public PropertyMethod Get, Set;
4053                 public PropertyBuilder PropertyBuilder;
4054                 public MethodBuilder GetBuilder, SetBuilder;
4055
4056                 protected bool define_set_first = false;
4057
4058                 public PropertyBase (DeclSpace parent, FullNamedExpression type, Modifiers mod_flags,
4059                                      Modifiers allowed_mod, MemberName name,
4060                                      Attributes attrs, bool define_set_first)
4061                         : base (parent, null, type, mod_flags, allowed_mod, name, attrs)
4062                 {
4063                          this.define_set_first = define_set_first;
4064                 }
4065
4066                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
4067                 {
4068                         if (a.HasSecurityAttribute) {
4069                                 a.Error_InvalidSecurityParent ();
4070                                 return;
4071                         }
4072
4073                         if (a.Type == pa.Dynamic) {
4074                                 a.Error_MisusedDynamicAttribute ();
4075                                 return;
4076                         }
4077
4078                         PropertyBuilder.SetCustomAttribute (cb);
4079                 }
4080
4081                 public override AttributeTargets AttributeTargets {
4082                         get {
4083                                 return AttributeTargets.Property;
4084                         }
4085                 }
4086
4087                 protected override void DoMemberTypeDependentChecks ()
4088                 {
4089                         base.DoMemberTypeDependentChecks ();
4090
4091                         IsTypePermitted ();
4092 #if MS_COMPATIBLE
4093                         if (MemberType.IsGenericParameter)
4094                                 return;
4095 #endif
4096
4097                         if ((MemberType.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute) {
4098                                 Report.Error (722, Location, Error722, TypeManager.CSharpName (MemberType));
4099                         }
4100                 }
4101
4102                 protected override void DoMemberTypeIndependentChecks ()
4103                 {
4104                         base.DoMemberTypeIndependentChecks ();
4105
4106                         //
4107                         // Accessors modifiers check
4108                         //
4109                         if ((Get.ModFlags & Modifiers.AccessibilityMask) != 0 &&
4110                                 (Set.ModFlags & Modifiers.AccessibilityMask) != 0) {
4111                                 Report.Error (274, Location, "`{0}': Cannot specify accessibility modifiers for both accessors of the property or indexer",
4112                                                 GetSignatureForError ());
4113                         }
4114
4115                         if ((ModFlags & Modifiers.OVERRIDE) == 0 && 
4116                                 (Get.IsDummy && (Set.ModFlags & Modifiers.AccessibilityMask) != 0) ||
4117                                 (Set.IsDummy && (Get.ModFlags & Modifiers.AccessibilityMask) != 0)) {
4118                                 Report.Error (276, Location, 
4119                                               "`{0}': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor",
4120                                               GetSignatureForError ());
4121                         }
4122                 }
4123
4124                 bool DefineGet ()
4125                 {
4126                         GetBuilder = Get.Define (Parent);
4127                         return (Get.IsDummy) ? true : GetBuilder != null;
4128                 }
4129
4130                 bool DefineSet (bool define)
4131                 {
4132                         if (!define)
4133                                 return true;
4134
4135                         SetBuilder = Set.Define (Parent);
4136                         return (Set.IsDummy) ? true : SetBuilder != null;
4137                 }
4138
4139                 protected bool DefineAccessors ()
4140                 {
4141                         return DefineSet (define_set_first) &&
4142                                 DefineGet () &&
4143                                 DefineSet (!define_set_first);
4144                 }
4145
4146                 protected abstract PropertyInfo ResolveBaseProperty ();
4147
4148                 // TODO: rename to Resolve......
4149                 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
4150                 {
4151                         PropertyInfo base_property = ResolveBaseProperty ();
4152                         if (base_property == null)
4153                                 return null;
4154
4155                         base_ret_type = base_property.PropertyType;
4156                         MethodInfo get_accessor = base_property.GetGetMethod (true);
4157                         MethodInfo set_accessor = base_property.GetSetMethod (true);
4158                         MethodAttributes get_accessor_access = 0, set_accessor_access = 0;
4159
4160                         //
4161                         // Check base property accessors conflict
4162                         //
4163                         if ((ModFlags & (Modifiers.OVERRIDE | Modifiers.NEW)) == Modifiers.OVERRIDE) {
4164                                 if (get_accessor == null) {
4165                                         if (Get != null && !Get.IsDummy) {
4166                                                 Report.SymbolRelatedToPreviousError (base_property);
4167                                                 Report.Error (545, Location,
4168                                                         "`{0}.get': cannot override because `{1}' does not have an overridable get accessor",
4169                                                         GetSignatureForError (), TypeManager.GetFullNameSignature (base_property));
4170                                         }
4171                                 } else {
4172                                         get_accessor_access = get_accessor.Attributes & MethodAttributes.MemberAccessMask;
4173
4174                                         if (!Get.IsDummy && !CheckAccessModifiers (
4175                                                 ModifiersExtensions.MethodAttr (Get.ModFlags) & MethodAttributes.MemberAccessMask, get_accessor_access, get_accessor))
4176                                                 Error_CannotChangeAccessModifiers (Get.Location, get_accessor, get_accessor_access, ".get");
4177                                 }
4178
4179                                 if (set_accessor == null) {
4180                                         if (Set != null && !Set.IsDummy) {
4181                                                 Report.SymbolRelatedToPreviousError (base_property);
4182                                                 Report.Error (546, Location,
4183                                                         "`{0}.set': cannot override because `{1}' does not have an overridable set accessor",
4184                                                         GetSignatureForError (), TypeManager.GetFullNameSignature (base_property));
4185                                         }
4186                                 } else {
4187                                         set_accessor_access = set_accessor.Attributes & MethodAttributes.MemberAccessMask;
4188
4189                                         if (!Set.IsDummy && !CheckAccessModifiers (
4190                                                 ModifiersExtensions.MethodAttr (Set.ModFlags) & MethodAttributes.MemberAccessMask, set_accessor_access, set_accessor))
4191                                                 Error_CannotChangeAccessModifiers (Set.Location, set_accessor, set_accessor_access, ".set");
4192                                 }
4193                         }
4194
4195                         // When one accessor does not exist and property hides base one
4196                         // we need to propagate this upwards
4197                         if (set_accessor == null)
4198                                 set_accessor = get_accessor;
4199
4200                         //
4201                         // Get the less restrictive access
4202                         //
4203                         return get_accessor_access > set_accessor_access ? get_accessor : set_accessor;
4204                 }
4205
4206                 public override void Emit ()
4207                 {
4208                         //
4209                         // The PropertyBuilder can be null for explicit implementations, in that
4210                         // case, we do not actually emit the ".property", so there is nowhere to
4211                         // put the attribute
4212                         //
4213                         if (PropertyBuilder != null) {
4214                                 if (OptAttributes != null)
4215                                         OptAttributes.Emit ();
4216
4217                                 if (TypeManager.IsDynamicType (member_type)) {
4218                                         PredefinedAttributes.Get.Dynamic.EmitAttribute (PropertyBuilder);
4219                                 } else {
4220                                         var trans_flags = TypeManager.HasDynamicTypeUsed (member_type);
4221                                         if (trans_flags != null) {
4222                                                 var pa = PredefinedAttributes.Get.DynamicTransform;
4223                                                 if (pa.Constructor != null || pa.ResolveConstructor (Location, TypeManager.bool_type.MakeArrayType ())) {
4224                                                         PropertyBuilder.SetCustomAttribute (
4225                                                                 new CustomAttributeBuilder (pa.Constructor, new object [] { trans_flags }));
4226                                                 }
4227                                         }
4228                                 }
4229                         }
4230
4231                         if (!Get.IsDummy)
4232                                 Get.Emit (Parent);
4233
4234                         if (!Set.IsDummy)
4235                                 Set.Emit (Parent);
4236
4237                         base.Emit ();
4238                 }
4239
4240                 /// <summary>
4241                 /// Tests whether accessors are not in collision with some method (CS0111)
4242                 /// </summary>
4243                 public bool AreAccessorsDuplicateImplementation (MethodCore mc)
4244                 {
4245                         return Get.IsDuplicateImplementation (mc) || Set.IsDuplicateImplementation (mc);
4246                 }
4247
4248                 public override bool IsUsed
4249                 {
4250                         get {
4251                                 if (IsExplicitImpl)
4252                                         return true;
4253
4254                                 return Get.IsUsed | Set.IsUsed;
4255                         }
4256                 }
4257
4258                 protected override void SetMemberName (MemberName new_name)
4259                 {
4260                         base.SetMemberName (new_name);
4261
4262                         Get.UpdateName (this);
4263                         Set.UpdateName (this);
4264                 }
4265
4266                 public override string[] ValidAttributeTargets {
4267                         get {
4268                                 return attribute_targets;
4269                         }
4270                 }
4271
4272                 //
4273                 //   Represents header string for documentation comment.
4274                 //
4275                 public override string DocCommentHeader {
4276                         get { return "P:"; }
4277                 }
4278         }
4279                         
4280         public class Property : PropertyBase
4281         {
4282                 public sealed class BackingField : Field
4283                 {
4284                         readonly Property property;
4285
4286                         public BackingField (Property p)
4287                                 : base (p.Parent, p.type_name,
4288                                 Modifiers.BACKING_FIELD | Modifiers.COMPILER_GENERATED | Modifiers.PRIVATE | (p.ModFlags & (Modifiers.STATIC | Modifiers.UNSAFE)),
4289                                 new MemberName ("<" + p.GetFullName (p.MemberName) + ">k__BackingField", p.Location), null)
4290                         {
4291                                 this.property = p;
4292                         }
4293
4294                         public override string GetSignatureForError ()
4295                         {
4296                                 return property.GetSignatureForError ();
4297                         }
4298                 }
4299
4300                 const Modifiers AllowedModifiers =
4301                         Modifiers.NEW |
4302                         Modifiers.PUBLIC |
4303                         Modifiers.PROTECTED |
4304                         Modifiers.INTERNAL |
4305                         Modifiers.PRIVATE |
4306                         Modifiers.STATIC |
4307                         Modifiers.SEALED |
4308                         Modifiers.OVERRIDE |
4309                         Modifiers.ABSTRACT |
4310                         Modifiers.UNSAFE |
4311                         Modifiers.EXTERN |
4312                         Modifiers.VIRTUAL;
4313
4314                 const Modifiers AllowedInterfaceModifiers =
4315                         Modifiers.NEW;
4316
4317                 public Property (DeclSpace parent, FullNamedExpression type, Modifiers mod,
4318                                  MemberName name, Attributes attrs, Accessor get_block,
4319                                  Accessor set_block, bool define_set_first)
4320                         : this (parent, type, mod, name, attrs, get_block, set_block,
4321                                 define_set_first, null)
4322                 {
4323                 }
4324                 
4325                 public Property (DeclSpace parent, FullNamedExpression type, Modifiers mod,
4326                                  MemberName name, Attributes attrs, Accessor get_block,
4327                                  Accessor set_block, bool define_set_first, Block current_block)
4328                         : base (parent, type, mod,
4329                                 parent.PartialContainer.Kind == Kind.Interface ? AllowedInterfaceModifiers : AllowedModifiers,
4330                                 name, attrs, define_set_first)
4331                 {
4332                         if (get_block == null)
4333                                 Get = new GetMethod (this);
4334                         else
4335                                 Get = new GetMethod (this, get_block);
4336
4337                         if (set_block == null)
4338                                 Set = new SetMethod (this);
4339                         else
4340                                 Set = new SetMethod (this, set_block);
4341
4342                         if (!IsInterface && (mod & (Modifiers.ABSTRACT | Modifiers.EXTERN)) == 0 &&
4343                                 get_block != null && get_block.Block == null &&
4344                                 set_block != null && set_block.Block == null) {
4345                                 if (RootContext.Version <= LanguageVersion.ISO_2)
4346                                         Report.FeatureIsNotAvailable (Location, "automatically implemented properties");
4347
4348                                 Get.ModFlags |= Modifiers.COMPILER_GENERATED;
4349                                 Set.ModFlags |= Modifiers.COMPILER_GENERATED;
4350                         }
4351                 }
4352
4353                 void CreateAutomaticProperty ()
4354                 {
4355                         // Create backing field
4356                         Field field = new BackingField (this);
4357                         if (!field.Define ())
4358                                 return;
4359
4360                         Parent.PartialContainer.AddField (field);
4361
4362                         FieldExpr fe = new FieldExpr (field, Location);
4363                         if ((field.ModFlags & Modifiers.STATIC) == 0)
4364                                 fe.InstanceExpression = new CompilerGeneratedThis (fe.Type, Location);
4365
4366                         // Create get block
4367                         Get.Block = new ToplevelBlock (Compiler, ParametersCompiled.EmptyReadOnlyParameters, Location);
4368                         Return r = new Return (fe, Location);
4369                         Get.Block.AddStatement (r);
4370
4371                         // Create set block
4372                         Set.Block = new ToplevelBlock (Compiler, Set.ParameterInfo, Location);
4373                         Assign a = new SimpleAssign (fe, new SimpleName ("value", Location));
4374                         Set.Block.AddStatement (new StatementExpression (a));
4375                 }
4376
4377                 public override bool Define ()
4378                 {
4379                         if (!base.Define ())
4380                                 return false;
4381
4382                         flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
4383
4384                         if ((Get.ModFlags & Modifiers.COMPILER_GENERATED) != 0)
4385                                 CreateAutomaticProperty ();
4386
4387                         if (!DefineAccessors ())
4388                                 return false;
4389
4390                         if (!CheckBase ())
4391                                 return false;
4392
4393                         // FIXME - PropertyAttributes.HasDefault ?
4394
4395                         PropertyBuilder = Parent.TypeBuilder.DefineProperty (
4396                                 GetFullName (MemberName), PropertyAttributes.None, MemberType, null);
4397
4398                         if (!Get.IsDummy) {
4399                                 PropertyBuilder.SetGetMethod (GetBuilder);
4400                                 Parent.MemberCache.AddMember (GetBuilder, Get);
4401                         }
4402
4403                         if (!Set.IsDummy) {
4404                                 PropertyBuilder.SetSetMethod (SetBuilder);
4405                                 Parent.MemberCache.AddMember (SetBuilder, Set);
4406                         }
4407                         
4408                         TypeManager.RegisterProperty (PropertyBuilder, this);
4409                         Parent.MemberCache.AddMember (PropertyBuilder, this);
4410                         return true;
4411                 }
4412
4413                 public override void Emit ()
4414                 {
4415                         if (((Set.ModFlags | Get.ModFlags) & (Modifiers.STATIC | Modifiers.COMPILER_GENERATED)) == Modifiers.COMPILER_GENERATED && Parent.PartialContainer.HasExplicitLayout) {
4416                                 Report.Error (842, Location,
4417                                         "Automatically implemented property `{0}' cannot be used inside a type with an explicit StructLayout attribute",
4418                                         GetSignatureForError ());
4419                         }
4420
4421                         base.Emit ();
4422                 }
4423
4424                 protected override PropertyInfo ResolveBaseProperty ()
4425                 {
4426                         return Parent.PartialContainer.BaseCache.FindMemberToOverride (
4427                                 Parent.TypeBuilder, Name, ParametersCompiled.EmptyReadOnlyParameters, null, true) as PropertyInfo;
4428                 }
4429         }
4430
4431         /// </summary>
4432         ///  Gigantic workaround  for lameness in SRE follows :
4433         ///  This class derives from EventInfo and attempts to basically
4434         ///  wrap around the EventBuilder so that FindMembers can quickly
4435         ///  return this in it search for members
4436         /// </summary>
4437         public class MyEventBuilder : EventInfo {
4438                 
4439                 //
4440                 // We use this to "point" to our Builder which is
4441                 // not really a MemberInfo
4442                 //
4443                 EventBuilder MyBuilder;
4444                 
4445                 //
4446                 // We "catch" and wrap these methods
4447                 //
4448                 MethodInfo raise, remove, add;
4449
4450                 EventAttributes attributes;
4451                 Type declaring_type, reflected_type, event_type;
4452                 string name;
4453
4454                 Event my_event;
4455
4456                 public MyEventBuilder (Event ev, TypeBuilder type_builder, string name, EventAttributes event_attr, Type event_type)
4457                 {
4458                         MyBuilder = type_builder.DefineEvent (name, event_attr, event_type);
4459
4460                         // And now store the values in our own fields.
4461                         
4462                         declaring_type = type_builder;
4463
4464                         reflected_type = type_builder;
4465                         
4466                         attributes = event_attr;
4467                         this.name = name;
4468                         my_event = ev;
4469                         this.event_type = event_type;
4470                 }
4471                 
4472                 //
4473                 // Methods that you have to override.  Note that you only need 
4474                 // to "implement" the variants that take the argument (those are
4475                 // the "abstract" methods, the others (GetAddMethod()) are 
4476                 // regular.
4477                 //
4478                 public override MethodInfo GetAddMethod (bool nonPublic)
4479                 {
4480                         return add;
4481                 }
4482                 
4483                 public override MethodInfo GetRemoveMethod (bool nonPublic)
4484                 {
4485                         return remove;
4486                 }
4487                 
4488                 public override MethodInfo GetRaiseMethod (bool nonPublic)
4489                 {
4490                         return raise;
4491                 }
4492                 
4493                 //
4494                 // These methods make "MyEventInfo" look like a Builder
4495                 //
4496                 public void SetRaiseMethod (MethodBuilder raiseMethod)
4497                 {
4498                         raise = raiseMethod;
4499                         MyBuilder.SetRaiseMethod (raiseMethod);
4500                 }
4501
4502                 public void SetRemoveOnMethod (MethodBuilder removeMethod)
4503                 {
4504                         remove = removeMethod;
4505                         MyBuilder.SetRemoveOnMethod (removeMethod);
4506                 }
4507
4508                 public void SetAddOnMethod (MethodBuilder addMethod)
4509                 {
4510                         add = addMethod;
4511                         MyBuilder.SetAddOnMethod (addMethod);
4512                 }
4513
4514                 public void SetCustomAttribute (CustomAttributeBuilder cb)
4515                 {
4516                         MyBuilder.SetCustomAttribute (cb);
4517                 }
4518                 
4519                 public override object [] GetCustomAttributes (bool inherit)
4520                 {
4521                         // FIXME : There's nothing which can be seemingly done here because
4522                         // we have no way of getting at the custom attribute objects of the
4523                         // EventBuilder !
4524                         return null;
4525                 }
4526
4527                 public override object [] GetCustomAttributes (Type t, bool inherit)
4528                 {
4529                         // FIXME : Same here !
4530                         return null;
4531                 }
4532
4533                 public override bool IsDefined (Type t, bool b)
4534                 {
4535                         return true;
4536                 }
4537
4538                 public override EventAttributes Attributes {
4539                         get {
4540                                 return attributes;
4541                         }
4542                 }
4543
4544                 public override string Name {
4545                         get {
4546                                 return name;
4547                         }
4548                 }
4549
4550                 public override Type DeclaringType {
4551                         get {
4552                                 return declaring_type;
4553                         }
4554                 }
4555
4556                 public override Type ReflectedType {
4557                         get {
4558                                 return reflected_type;
4559                         }
4560                 }
4561
4562                 public Type EventType {
4563                         get {
4564                                 return event_type;
4565                         }
4566                 }
4567                 
4568                 public void SetUsed ()
4569                 {
4570                         if (my_event != null) {
4571 //                              my_event.SetAssigned ();
4572                                 my_event.SetMemberIsUsed ();
4573                         }
4574                 }
4575         }
4576         
4577         /// <summary>
4578         /// For case when event is declared like property (with add and remove accessors).
4579         /// </summary>
4580         public class EventProperty: Event {
4581                 abstract class AEventPropertyAccessor : AEventAccessor
4582                 {
4583                         protected AEventPropertyAccessor (EventProperty method, Accessor accessor, string prefix)
4584                                 : base (method, accessor, prefix)
4585                         {
4586                         }
4587
4588                         public override MethodBuilder Define (DeclSpace ds)
4589                         {
4590                                 CheckAbstractAndExtern (block != null);
4591                                 return base.Define (ds);
4592                         }
4593                         
4594                         public override string GetSignatureForError ()
4595                         {
4596                                 return method.GetSignatureForError () + "." + prefix.Substring (0, prefix.Length - 1);
4597                         }
4598                 }
4599
4600                 sealed class AddDelegateMethod: AEventPropertyAccessor
4601                 {
4602                         public AddDelegateMethod (EventProperty method, Accessor accessor):
4603                                 base (method, accessor, AddPrefix)
4604                         {
4605                         }
4606                 }
4607
4608                 sealed class RemoveDelegateMethod: AEventPropertyAccessor
4609                 {
4610                         public RemoveDelegateMethod (EventProperty method, Accessor accessor):
4611                                 base (method, accessor, RemovePrefix)
4612                         {
4613                         }
4614                 }
4615
4616
4617                 static readonly string[] attribute_targets = new string [] { "event" }; // "property" target was disabled for 2.0 version
4618
4619                 public EventProperty (DeclSpace parent, FullNamedExpression type, Modifiers mod_flags,
4620                                       MemberName name,
4621                                       Attributes attrs, Accessor add, Accessor remove)
4622                         : base (parent, type, mod_flags, name, attrs)
4623                 {
4624                         Add = new AddDelegateMethod (this, add);
4625                         Remove = new RemoveDelegateMethod (this, remove);
4626                 }
4627
4628                 public override bool Define()
4629                 {
4630                         if (!base.Define ())
4631                                 return false;
4632
4633                         SetMemberIsUsed ();
4634                         return true;
4635                 }
4636
4637                 public override string[] ValidAttributeTargets {
4638                         get {
4639                                 return attribute_targets;
4640                         }
4641                 }
4642         }
4643
4644         /// <summary>
4645         /// Event is declared like field.
4646         /// </summary>
4647         public class EventField : Event {
4648                 abstract class EventFieldAccessor : AEventAccessor
4649                 {
4650                         protected EventFieldAccessor (EventField method, string prefix)
4651                                 : base (method, prefix)
4652                         {
4653                         }
4654
4655                         public override void Emit (DeclSpace parent)
4656                         {
4657                                 if ((method.ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) == 0) {
4658                                         if (parent is Class) {
4659                                                 MethodBuilder mb = method_data.MethodBuilder;
4660                                                 mb.SetImplementationFlags (mb.GetMethodImplementationFlags () | MethodImplAttributes.Synchronized);
4661                                         }
4662
4663                                         var field_info = ((EventField) method).BackingField;
4664                                         FieldExpr f_expr = new FieldExpr (field_info, Location);
4665                                         if ((method.ModFlags & Modifiers.STATIC) == 0)
4666                                                 f_expr.InstanceExpression = new CompilerGeneratedThis (field_info.Spec.FieldType, Location);
4667
4668                                         block = new ToplevelBlock (Compiler, ParameterInfo, Location);
4669                                         block.AddStatement (new StatementExpression (
4670                                                 new CompoundAssign (Operation,
4671                                                         f_expr,
4672                                                         block.GetParameterReference (ParameterInfo[0].Name, Location))));
4673                                 }
4674
4675                                 base.Emit (parent);
4676                         }
4677
4678                         protected abstract Binary.Operator Operation { get; }
4679                 }
4680
4681                 sealed class AddDelegateMethod: EventFieldAccessor
4682                 {
4683                         public AddDelegateMethod (EventField method):
4684                                 base (method, AddPrefix)
4685                         {
4686                         }
4687
4688                         protected override Binary.Operator Operation {
4689                                 get { return Binary.Operator.Addition; }
4690                         }
4691                 }
4692
4693                 sealed class RemoveDelegateMethod: EventFieldAccessor
4694                 {
4695                         public RemoveDelegateMethod (EventField method):
4696                                 base (method, RemovePrefix)
4697                         {
4698                         }
4699
4700                         protected override Binary.Operator Operation {
4701                                 get { return Binary.Operator.Subtraction; }
4702                         }
4703                 }
4704
4705
4706                 static readonly string[] attribute_targets = new string [] { "event", "field", "method" };
4707                 static readonly string[] attribute_targets_interface = new string[] { "event", "method" };
4708
4709                 public Field BackingField;
4710                 public Expression Initializer;
4711
4712                 public EventField (DeclSpace parent, FullNamedExpression type, Modifiers mod_flags, MemberName name, Attributes attrs)
4713                         : base (parent, type, mod_flags, name, attrs)
4714                 {
4715                         Add = new AddDelegateMethod (this);
4716                         Remove = new RemoveDelegateMethod (this);
4717                 }
4718
4719                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
4720                 {
4721                         if (a.Target == AttributeTargets.Field) {
4722                                 BackingField.ApplyAttributeBuilder (a, cb, pa);
4723                                 return;
4724                         }
4725
4726                         if (a.Target == AttributeTargets.Method) {
4727                                 int errors = Report.Errors;
4728                                 Add.ApplyAttributeBuilder (a, cb, pa);
4729                                 if (errors == Report.Errors)
4730                                         Remove.ApplyAttributeBuilder (a, cb, pa);
4731                                 return;
4732                         }
4733
4734                         base.ApplyAttributeBuilder (a, cb, pa);
4735                 }
4736
4737                 public override bool Define()
4738                 {
4739                         if (!base.Define ())
4740                                 return false;
4741
4742                         if (Initializer != null && (ModFlags & Modifiers.ABSTRACT) != 0) {
4743                                 Report.Error (74, Location, "`{0}': abstract event cannot have an initializer",
4744                                         GetSignatureForError ());
4745                         }
4746
4747                         if (!HasBackingField) {
4748                                 SetMemberIsUsed ();
4749                                 return true;
4750                         }
4751
4752                         // FIXME: We are unable to detect whether generic event is used because
4753                         // we are using FieldExpr instead of EventExpr for event access in that
4754                         // case.  When this issue will be fixed this hack can be removed.
4755                         if (TypeManager.IsGenericType (MemberType) || Parent.IsGeneric)
4756                                 SetMemberIsUsed ();
4757
4758                         if (Add.IsInterfaceImplementation)
4759                                 SetMemberIsUsed ();
4760
4761                         TypeManager.RegisterEventField (EventBuilder, this);
4762
4763                         BackingField = new Field (Parent,
4764                                 new TypeExpression (MemberType, Location),
4765                                 Modifiers.BACKING_FIELD | Modifiers.COMPILER_GENERATED | Modifiers.PRIVATE | (ModFlags & (Modifiers.STATIC | Modifiers.UNSAFE)),
4766                                 MemberName, null);
4767
4768                         Parent.PartialContainer.AddField (BackingField);
4769                         BackingField.Initializer = Initializer;
4770                         BackingField.ModFlags &= ~Modifiers.COMPILER_GENERATED;
4771
4772                         // Call define because we passed fields definition
4773                         return BackingField.Define ();
4774                 }
4775
4776                 bool HasBackingField {
4777                         get {
4778                                 return !IsInterface && (ModFlags & Modifiers.ABSTRACT) == 0;
4779                         }
4780                 }
4781
4782                 public override string[] ValidAttributeTargets 
4783                 {
4784                         get {
4785                                 return HasBackingField ? attribute_targets : attribute_targets_interface;
4786                         }
4787                 }
4788         }
4789
4790         public abstract class Event : PropertyBasedMember {
4791                 public abstract class AEventAccessor : AbstractPropertyEventMethod
4792                 {
4793                         protected readonly Event method;
4794                         ImplicitParameter param_attr;
4795
4796                         static readonly string[] attribute_targets = new string [] { "method", "param", "return" };
4797
4798                         public const string AddPrefix = "add_";
4799                         public const string RemovePrefix = "remove_";
4800
4801                         protected AEventAccessor (Event method, string prefix)
4802                                 : base (method, prefix)
4803                         {
4804                                 this.method = method;
4805                                 this.ModFlags = method.ModFlags;
4806                         }
4807
4808                         protected AEventAccessor (Event method, Accessor accessor, string prefix)
4809                                 : base (method, accessor, prefix)
4810                         {
4811                                 this.method = method;
4812                                 this.ModFlags = method.ModFlags;
4813                         }
4814
4815                         public bool IsInterfaceImplementation {
4816                                 get { return method_data.implementing != null; }
4817                         }
4818
4819                         public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
4820                         {
4821                                 if (a.IsInternalMethodImplAttribute) {
4822                                         method.is_external_implementation = true;
4823                                 }
4824
4825                                 base.ApplyAttributeBuilder (a, cb, pa);
4826                         }
4827
4828                         protected override void ApplyToExtraTarget (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
4829                         {
4830                                 if (a.Target == AttributeTargets.Parameter) {
4831                                         if (param_attr == null)
4832                                                 param_attr = new ImplicitParameter (method_data.MethodBuilder);
4833
4834                                         param_attr.ApplyAttributeBuilder (a, cb, pa);
4835                                         return;
4836                                 }
4837
4838                                 base.ApplyAttributeBuilder (a, cb, pa);
4839                         }
4840
4841                         public override AttributeTargets AttributeTargets {
4842                                 get {
4843                                         return AttributeTargets.Method;
4844                                 }
4845                         }
4846
4847                         public override bool IsClsComplianceRequired ()
4848                         {
4849                                 return method.IsClsComplianceRequired ();
4850                         }
4851
4852                         public virtual MethodBuilder Define (DeclSpace parent)
4853                         {
4854                                 method_data = new MethodData (method, method.ModFlags,
4855                                         method.flags | MethodAttributes.HideBySig | MethodAttributes.SpecialName, this);
4856
4857                                 if (!method_data.Define (parent, method.GetFullName (MemberName), Report))
4858                                         return null;
4859
4860                                 MethodBuilder mb = method_data.MethodBuilder;
4861                                 ParameterInfo.ApplyAttributes (mb);
4862                                 return mb;
4863                         }
4864
4865                         public override Type ReturnType {
4866                                 get {
4867                                         return TypeManager.void_type;
4868                                 }
4869                         }
4870
4871                         public override ObsoleteAttribute GetObsoleteAttribute ()
4872                         {
4873                                 return method.GetObsoleteAttribute ();
4874                         }
4875
4876                         public override string[] ValidAttributeTargets {
4877                                 get {
4878                                         return attribute_targets;
4879                                 }
4880                         }
4881
4882                         public override ParametersCompiled ParameterInfo {
4883                                 get {
4884                                         return method.parameters;
4885                                 }
4886                         }
4887                 }
4888
4889
4890                 const Modifiers AllowedModifiers =
4891                         Modifiers.NEW |
4892                         Modifiers.PUBLIC |
4893                         Modifiers.PROTECTED |
4894                         Modifiers.INTERNAL |
4895                         Modifiers.PRIVATE |
4896                         Modifiers.STATIC |
4897                         Modifiers.VIRTUAL |
4898                         Modifiers.SEALED |
4899                         Modifiers.OVERRIDE |
4900                         Modifiers.UNSAFE |
4901                         Modifiers.ABSTRACT |
4902                         Modifiers.EXTERN;
4903
4904                 const Modifiers AllowedInterfaceModifiers =
4905                         Modifiers.NEW;
4906
4907                 public AEventAccessor Add, Remove;
4908                 public MyEventBuilder     EventBuilder;
4909                 public MethodBuilder AddBuilder, RemoveBuilder;
4910
4911                 ParametersCompiled parameters;
4912
4913                 protected Event (DeclSpace parent, FullNamedExpression type, Modifiers mod_flags, MemberName name, Attributes attrs)
4914                         : base (parent, null, type, mod_flags,
4915                                 parent.PartialContainer.Kind == Kind.Interface ? AllowedInterfaceModifiers : AllowedModifiers,
4916                                 name, attrs)
4917                 {
4918                 }
4919
4920                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
4921                 {
4922                         if ((a.HasSecurityAttribute)) {
4923                                 a.Error_InvalidSecurityParent ();
4924                                 return;
4925                         }
4926                         
4927                         EventBuilder.SetCustomAttribute (cb);
4928                 }
4929
4930                 public bool AreAccessorsDuplicateImplementation (MethodCore mc)
4931                 {
4932                         return Add.IsDuplicateImplementation (mc) || Remove.IsDuplicateImplementation (mc);
4933                 }
4934
4935                 public override AttributeTargets AttributeTargets {
4936                         get {
4937                                 return AttributeTargets.Event;
4938                         }
4939                 }
4940
4941                 public override bool Define ()
4942                 {
4943                         if (!base.Define ())
4944                                 return false;
4945
4946                         if (!TypeManager.IsDelegateType (MemberType)) {
4947                                 Report.Error (66, Location, "`{0}': event must be of a delegate type", GetSignatureForError ());
4948                         }
4949
4950                         parameters = ParametersCompiled.CreateFullyResolved (
4951                                 new Parameter (null, "value", Parameter.Modifier.NONE, null, Location), MemberType);
4952
4953                         if (!CheckBase ())
4954                                 return false;
4955
4956                         if (TypeManager.delegate_combine_delegate_delegate == null) {
4957                                 TypeManager.delegate_combine_delegate_delegate = TypeManager.GetPredefinedMethod (
4958                                         TypeManager.delegate_type, "Combine", Location,
4959                                         TypeManager.delegate_type, TypeManager.delegate_type);
4960                         }
4961                         if (TypeManager.delegate_remove_delegate_delegate == null) {
4962                                 TypeManager.delegate_remove_delegate_delegate = TypeManager.GetPredefinedMethod (
4963                                         TypeManager.delegate_type, "Remove", Location,
4964                                         TypeManager.delegate_type, TypeManager.delegate_type);
4965                         }
4966
4967                         //
4968                         // Now define the accessors
4969                         //
4970
4971                         AddBuilder = Add.Define (Parent);
4972                         if (AddBuilder == null)
4973                                 return false;
4974
4975                         RemoveBuilder = Remove.Define (Parent);
4976                         if (RemoveBuilder == null)
4977                                 return false;
4978
4979                         EventBuilder = new MyEventBuilder (this, Parent.TypeBuilder, Name, EventAttributes.None, MemberType);                                           
4980                         EventBuilder.SetAddOnMethod (AddBuilder);
4981                         EventBuilder.SetRemoveOnMethod (RemoveBuilder);
4982
4983                         Parent.MemberCache.AddMember (EventBuilder, this);
4984                         Parent.MemberCache.AddMember (AddBuilder, Add);
4985                         Parent.MemberCache.AddMember (RemoveBuilder, Remove);
4986                         
4987                         return true;
4988                 }
4989
4990                 public override void Emit ()
4991                 {
4992                         if (OptAttributes != null) {
4993                                 OptAttributes.Emit ();
4994                         }
4995
4996                         Add.Emit (Parent);
4997                         Remove.Emit (Parent);
4998
4999                         base.Emit ();
5000                 }
5001
5002                 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
5003                 {
5004                         MethodInfo mi = (MethodInfo) Parent.PartialContainer.BaseCache.FindBaseEvent (
5005                                 Parent.TypeBuilder, Name);
5006
5007                         if (mi == null)
5008                                 return null;
5009
5010                         AParametersCollection pd = TypeManager.GetParameterData (mi);
5011                         base_ret_type = pd.Types [0];
5012                         return mi;
5013                 }
5014
5015                 //
5016                 //   Represents header string for documentation comment.
5017                 //
5018                 public override string DocCommentHeader {
5019                         get { return "E:"; }
5020                 }
5021         }
5022
5023  
5024         public class Indexer : PropertyBase
5025         {
5026                 public class GetIndexerMethod : GetMethod
5027                 {
5028                         ParametersCompiled parameters;
5029
5030                         public GetIndexerMethod (Indexer method):
5031                                 base (method)
5032                         {
5033                                 this.parameters = method.parameters;
5034                         }
5035
5036                         public GetIndexerMethod (PropertyBase method, Accessor accessor):
5037                                 base (method, accessor)
5038                         {
5039                                 parameters = accessor.Parameters;
5040                         }
5041
5042                         public override MethodBuilder Define (DeclSpace parent)
5043                         {
5044                                 parameters.Resolve (this);
5045                                 return base.Define (parent);
5046                         }
5047                         
5048                         public override bool EnableOverloadChecks (MemberCore overload)
5049                         {
5050                                 if (base.EnableOverloadChecks (overload)) {
5051                                         overload.caching_flags |= Flags.MethodOverloadsExist;
5052                                         return true;
5053                                 }
5054
5055                                 return false;
5056                         }                       
5057
5058                         public override ParametersCompiled ParameterInfo {
5059                                 get {
5060                                         return parameters;
5061                                 }
5062                         }
5063                 }
5064
5065                 public class SetIndexerMethod: SetMethod
5066                 {
5067                         public SetIndexerMethod (Indexer method):
5068                                 base (method)
5069                         {
5070                                 parameters = ParametersCompiled.MergeGenerated (Compiler, method.parameters, false, parameters [0], null);
5071                         }
5072
5073                         public SetIndexerMethod (PropertyBase method, Accessor accessor):
5074                                 base (method, accessor)
5075                         {
5076                                 parameters = method.Get.IsDummy ? accessor.Parameters : accessor.Parameters.Clone ();                   
5077                         }
5078
5079                         public override bool EnableOverloadChecks (MemberCore overload)
5080                         {
5081                                 if (base.EnableOverloadChecks (overload)) {
5082                                         overload.caching_flags |= Flags.MethodOverloadsExist;
5083                                         return true;
5084                                 }
5085
5086                                 return false;
5087                         }
5088                 }
5089
5090                 const Modifiers AllowedModifiers =
5091                         Modifiers.NEW |
5092                         Modifiers.PUBLIC |
5093                         Modifiers.PROTECTED |
5094                         Modifiers.INTERNAL |
5095                         Modifiers.PRIVATE |
5096                         Modifiers.VIRTUAL |
5097                         Modifiers.SEALED |
5098                         Modifiers.OVERRIDE |
5099                         Modifiers.UNSAFE |
5100                         Modifiers.EXTERN |
5101                         Modifiers.ABSTRACT;
5102
5103                 const Modifiers AllowedInterfaceModifiers =
5104                         Modifiers.NEW;
5105
5106                 public readonly ParametersCompiled parameters;
5107
5108                 public Indexer (DeclSpace parent, FullNamedExpression type, MemberName name, Modifiers mod,
5109                                 ParametersCompiled parameters, Attributes attrs,
5110                                 Accessor get_block, Accessor set_block, bool define_set_first)
5111                         : base (parent, type, mod,
5112                                 parent.PartialContainer.Kind == Kind.Interface ? AllowedInterfaceModifiers : AllowedModifiers,
5113                                 name, attrs, define_set_first)
5114                 {
5115                         this.parameters = parameters;
5116
5117                         if (get_block == null)
5118                                 Get = new GetIndexerMethod (this);
5119                         else
5120                                 Get = new GetIndexerMethod (this, get_block);
5121
5122                         if (set_block == null)
5123                                 Set = new SetIndexerMethod (this);
5124                         else
5125                                 Set = new SetIndexerMethod (this, set_block);
5126                 }
5127
5128                 protected override bool CheckForDuplications ()
5129                 {
5130                         return Parent.MemberCache.CheckExistingMembersOverloads (this, GetFullName (MemberName), parameters, Report);
5131                 }
5132                 
5133                 public override bool Define ()
5134                 {
5135                         if (!base.Define ())
5136                                 return false;
5137
5138                         if (!DefineParameters (parameters))
5139                                 return false;
5140
5141                         if (OptAttributes != null) {
5142                                 Attribute indexer_attr = OptAttributes.Search (PredefinedAttributes.Get.IndexerName);
5143                                 if (indexer_attr != null) {
5144                                         // Remove the attribute from the list because it is not emitted
5145                                         OptAttributes.Attrs.Remove (indexer_attr);
5146
5147                                         string name = indexer_attr.GetIndexerAttributeValue ();
5148                                         if (name == null)
5149                                                 return false;
5150
5151                                         ShortName = name;
5152
5153                                         if (IsExplicitImpl) {
5154                                                 Report.Error (415, indexer_attr.Location,
5155                                                               "The `IndexerName' attribute is valid only on an " +
5156                                                               "indexer that is not an explicit interface member declaration");
5157                                                 return false;
5158                                         }
5159
5160                                         if ((ModFlags & Modifiers.OVERRIDE) != 0) {
5161                                                 Report.Error (609, indexer_attr.Location,
5162                                                               "Cannot set the `IndexerName' attribute on an indexer marked override");
5163                                                 return false;
5164                                         }
5165                                 }
5166                         }
5167
5168                         if (InterfaceType != null) {
5169                                 string base_IndexerName = TypeManager.IndexerPropertyName (InterfaceType);
5170                                 if (base_IndexerName != Name)
5171                                         ShortName = base_IndexerName;
5172                         }
5173
5174                         if (!Parent.PartialContainer.AddMember (this) ||
5175                                 !Parent.PartialContainer.AddMember (Get) || !Parent.PartialContainer.AddMember (Set))
5176                                 return false;
5177
5178                         flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
5179                         
5180                         if (!DefineAccessors ())
5181                                 return false;
5182
5183                         if (!CheckBase ())
5184                                 return false;
5185
5186                         //
5187                         // Now name the parameters
5188                         //
5189                         PropertyBuilder = Parent.TypeBuilder.DefineProperty (
5190                                 GetFullName (MemberName), PropertyAttributes.None, MemberType, parameters.GetEmitTypes ());
5191
5192                         if (!Get.IsDummy) {
5193                                 PropertyBuilder.SetGetMethod (GetBuilder);
5194                                 Parent.MemberCache.AddMember (GetBuilder, Get);
5195                         }
5196
5197                         if (!Set.IsDummy) {
5198                                 PropertyBuilder.SetSetMethod (SetBuilder);
5199                                 Parent.MemberCache.AddMember (SetBuilder, Set);
5200                         }
5201                                 
5202                         TypeManager.RegisterIndexer (PropertyBuilder, parameters);
5203                         Parent.MemberCache.AddMember (PropertyBuilder, this);
5204                         return true;
5205                 }
5206
5207                 public override bool EnableOverloadChecks (MemberCore overload)
5208                 {
5209                         if (overload is Indexer) {
5210                                 caching_flags |= Flags.MethodOverloadsExist;
5211                                 return true;
5212                         }
5213
5214                         return base.EnableOverloadChecks (overload);
5215                 }
5216
5217                 public override string GetDocCommentName (DeclSpace ds)
5218                 {
5219                         return DocUtil.GetMethodDocCommentName (this, parameters, ds);
5220                 }
5221
5222                 public override string GetSignatureForError ()
5223                 {
5224                         StringBuilder sb = new StringBuilder (Parent.GetSignatureForError ());
5225                         if (MemberName.Left != null) {
5226                                 sb.Append ('.');
5227                                 sb.Append (MemberName.Left.GetSignatureForError ());
5228                         }
5229
5230                         sb.Append (".this");
5231                         sb.Append (parameters.GetSignatureForError ().Replace ('(', '[').Replace (')', ']'));
5232                         return sb.ToString ();
5233                 }
5234
5235                 protected override PropertyInfo ResolveBaseProperty ()
5236                 {
5237                         return Parent.PartialContainer.BaseCache.FindMemberToOverride (
5238                                 Parent.TypeBuilder, Name, parameters, null, true) as PropertyInfo;
5239                 }
5240
5241                 protected override bool VerifyClsCompliance ()
5242                 {
5243                         if (!base.VerifyClsCompliance ())
5244                                 return false;
5245
5246                         parameters.VerifyClsCompliance (this);
5247                         return true;
5248                 }
5249         }
5250 }
5251