Add unit test for AggregateException.GetBaseException that works on .net but is broke...
[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@gmail.com)
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-2011 Novell, Inc
12 // Copyright 2011 Xamarin, Inc (http://www.xamarin.com)
13 //
14
15 using System;
16 using System.Collections.Generic;
17 using System.Runtime.InteropServices;
18 using System.Security;
19 using System.Security.Permissions;
20 using System.Text;
21 using System.Diagnostics;
22 using Mono.CompilerServices.SymbolWriter;
23
24 #if NET_2_1
25 using XmlElement = System.Object;
26 #endif
27
28 #if STATIC
29 using SecurityType = System.Collections.Generic.List<IKVM.Reflection.Emit.CustomAttributeBuilder>;
30 using IKVM.Reflection;
31 using IKVM.Reflection.Emit;
32 #else
33 using SecurityType = System.Collections.Generic.Dictionary<System.Security.Permissions.SecurityAction, System.Security.PermissionSet>;
34 using System.Reflection;
35 using System.Reflection.Emit;
36 #endif
37
38 namespace Mono.CSharp
39 {
40         //
41         // General types container, used as a base class for all constructs which can hold types
42         //
43         public abstract class TypeContainer : MemberCore
44         {
45                 public readonly MemberKind Kind;
46                 public readonly string Basename;
47
48                 protected List<TypeContainer> containers;
49
50                 TypeDefinition main_container;
51
52                 protected Dictionary<string, MemberCore> defined_names;
53
54                 protected bool is_defined;
55
56                 public int CounterAnonymousMethods { get; set; }
57                 public int CounterAnonymousContainers { get; set; }
58                 public int CounterSwitchTypes { get; set; }
59
60                 protected TypeContainer (TypeContainer parent, MemberName name, Attributes attrs, MemberKind kind)
61                         : base (parent, name, attrs)
62                 {
63                         this.Kind = kind;
64                         if (name != null)
65                                 this.Basename = name.Basename;
66
67                         defined_names = new Dictionary<string, MemberCore> ();
68                 }
69
70                 public override TypeSpec CurrentType {
71                         get {
72                                 return null;
73                         }
74                 }
75
76                 public Dictionary<string, MemberCore> DefinedNames {
77                         get {
78                                 return defined_names;
79                         }
80                 }
81
82                 public TypeDefinition PartialContainer {
83                         get {
84                                 return main_container;
85                         }
86                         protected set {
87                                 main_container = value;
88                         }
89                 }
90
91                 public IList<TypeContainer> Containers {
92                         get {
93                                 return containers;
94                         }
95                 }
96
97                 //
98                 // Any unattached attributes during parsing get added here. User
99                 // by FULL_AST mode
100                 //
101                 public Attributes UnattachedAttributes {
102                         get; set;
103                 }
104
105                 public void AddCompilerGeneratedClass (CompilerGeneratedContainer c)
106                 {
107                         AddTypeContainerMember (c);
108                 }
109
110                 public virtual void AddPartial (TypeDefinition next_part)
111                 {
112                         MemberCore mc;
113                         (PartialContainer ?? this).defined_names.TryGetValue (next_part.Basename, out mc);
114
115                         AddPartial (next_part, mc as TypeDefinition);
116                 }
117
118                 protected void AddPartial (TypeDefinition next_part, TypeDefinition existing)
119                 {
120                         next_part.ModFlags |= Modifiers.PARTIAL;
121
122                         if (existing == null) {
123                                 AddTypeContainer (next_part);
124                                 return;
125                         }
126
127                         if ((existing.ModFlags & Modifiers.PARTIAL) == 0) {
128                                 if (existing.Kind != next_part.Kind) {
129                                         AddTypeContainer (next_part);
130                                 } else {
131                                         Report.SymbolRelatedToPreviousError (next_part);
132                                         Error_MissingPartialModifier (existing);
133                                 }
134
135                                 return;
136                         }
137
138                         if (existing.Kind != next_part.Kind) {
139                                 Report.SymbolRelatedToPreviousError (existing);
140                                 Report.Error (261, next_part.Location,
141                                         "Partial declarations of `{0}' must be all classes, all structs or all interfaces",
142                                         next_part.GetSignatureForError ());
143                         }
144
145                         if ((existing.ModFlags & Modifiers.AccessibilityMask) != (next_part.ModFlags & Modifiers.AccessibilityMask) &&
146                                 ((existing.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) == 0 &&
147                                  (next_part.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) == 0)) {
148                                          Report.SymbolRelatedToPreviousError (existing);
149                                 Report.Error (262, next_part.Location,
150                                         "Partial declarations of `{0}' have conflicting accessibility modifiers",
151                                         next_part.GetSignatureForError ());
152                         }
153
154                         var tc_names = existing.CurrentTypeParameters;
155                         if (tc_names != null) {
156                                 for (int i = 0; i < tc_names.Count; ++i) {
157                                         var tp = next_part.MemberName.TypeParameters[i];
158                                         if (tc_names[i].MemberName.Name != tp.MemberName.Name) {
159                                                 Report.SymbolRelatedToPreviousError (existing.Location, "");
160                                                 Report.Error (264, next_part.Location, "Partial declarations of `{0}' must have the same type parameter names in the same order",
161                                                         next_part.GetSignatureForError ());
162                                                 break;
163                                         }
164
165                                         if (tc_names[i].Variance != tp.Variance) {
166                                                 Report.SymbolRelatedToPreviousError (existing.Location, "");
167                                                 Report.Error (1067, next_part.Location, "Partial declarations of `{0}' must have the same type parameter variance modifiers",
168                                                         next_part.GetSignatureForError ());
169                                                 break;
170                                         }
171                                 }
172                         }
173
174                         if ((next_part.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) != 0) {
175                                 existing.ModFlags |= next_part.ModFlags & ~(Modifiers.DEFAULT_ACCESS_MODIFER | Modifiers.AccessibilityMask);
176                         } else if ((existing.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) != 0) {
177                                 existing.ModFlags &= ~(Modifiers.DEFAULT_ACCESS_MODIFER | Modifiers.AccessibilityMask);
178                                 existing.ModFlags |= next_part.ModFlags;
179                         } else {
180                                 existing.ModFlags |= next_part.ModFlags;
181                         }
182
183                         existing.Definition.Modifiers = existing.ModFlags;
184
185                         if (next_part.attributes != null) {
186                                 if (existing.attributes == null)
187                                         existing.attributes = next_part.attributes;
188                                 else
189                                         existing.attributes.AddAttributes (next_part.attributes.Attrs);
190                         }
191
192                         next_part.PartialContainer = existing;
193
194                         existing.AddPartialPart (next_part);
195
196                         AddTypeContainerMember (next_part);
197                 }
198
199                 public virtual void AddTypeContainer (TypeContainer tc)
200                 {
201                         AddTypeContainerMember (tc);
202
203                         var tparams = tc.MemberName.TypeParameters;
204                         if (tparams != null && tc.PartialContainer != null) {
205                                 var td = (TypeDefinition) tc;
206                                 for (int i = 0; i < tparams.Count; ++i) {
207                                         var tp = tparams[i];
208                                         if (tp.MemberName == null)
209                                                 continue;
210
211                                         td.AddNameToContainer (tp, tp.Name);
212                                 }
213                         }
214                 }
215
216                 protected virtual void AddTypeContainerMember (TypeContainer tc)
217                 {
218                         containers.Add (tc);
219                 }
220
221                 public virtual void CloseContainer ()
222                 {
223                         if (containers != null) {
224                                 foreach (TypeContainer tc in containers) {
225                                         tc.CloseContainer ();
226                                 }
227                         }
228                 }
229
230                 public virtual void CreateMetadataName (StringBuilder sb)
231                 {
232                         if (Parent != null && Parent.MemberName != null)
233                                 Parent.CreateMetadataName (sb);
234
235                         MemberName.CreateMetadataName (sb);
236                 }
237
238                 public virtual bool CreateContainer ()
239                 {
240                         if (containers != null) {
241                                 foreach (TypeContainer tc in containers) {
242                                         tc.CreateContainer ();
243                                 }
244                         }
245
246                         return true;
247                 }
248
249                 public override bool Define ()
250                 {
251                         if (containers != null) {
252                                 foreach (TypeContainer tc in containers) {
253                                         tc.Define ();
254                                 }
255                         }
256
257                         // Release cache used by parser only
258                         if (Module.Evaluator == null) {
259                                 defined_names = null;
260                         } else {
261                                 defined_names.Clear ();
262                         }
263
264                         return true;
265                 }
266
267                 public virtual void PrepareEmit ()
268                 {
269                         if (containers != null) {
270                                 foreach (var t in containers) {
271                                         try {
272                                                 t.PrepareEmit ();
273                                         } catch (Exception e) {
274                                                 if (MemberName == MemberName.Null)
275                                                         throw;
276
277                                                 throw new InternalErrorException (t, e);
278                                         }
279                                 }
280                         }
281                 }
282
283                 public virtual bool DefineContainer ()
284                 {
285                         if (is_defined)
286                                 return true;
287
288                         is_defined = true;
289
290                         DoDefineContainer ();
291
292                         if (containers != null) {
293                                 foreach (TypeContainer tc in containers) {
294                                         try {
295                                                 tc.DefineContainer ();
296                                         } catch (Exception e) {
297                                                 if (MemberName == MemberName.Null)
298                                                         throw;
299
300                                                 throw new InternalErrorException (tc, e);
301                                         }
302                                 }
303                         }
304
305                         return true;
306                 }
307
308                 public virtual void ExpandBaseInterfaces ()
309                 {
310                         if (containers != null) {
311                                 foreach (TypeContainer tc in containers) {
312                                         tc.ExpandBaseInterfaces ();
313                                 }
314                         }
315                 }
316
317                 protected virtual void DefineNamespace ()
318                 {
319                         if (containers != null) {
320                                 foreach (var tc in containers) {
321                                         try {
322                                                 tc.DefineNamespace ();
323                                         } catch (Exception e) {
324                                                 throw new InternalErrorException (tc, e);
325                                         }
326                                 }
327                         }
328                 }
329
330                 protected virtual void DoDefineContainer ()
331                 {
332                 }
333
334                 public virtual void EmitContainer ()
335                 {
336                         if (containers != null) {
337                                 for (int i = 0; i < containers.Count; ++i)
338                                         containers[i].EmitContainer ();
339                         }
340                 }
341
342                 protected void Error_MissingPartialModifier (MemberCore type)
343                 {
344                         Report.Error (260, type.Location,
345                                 "Missing partial modifier on declaration of type `{0}'. Another partial declaration of this type exists",
346                                 type.GetSignatureForError ());
347                 }
348
349                 public override string GetSignatureForDocumentation ()
350                 {
351                         if (Parent != null && Parent.MemberName != null)
352                                 return Parent.GetSignatureForDocumentation () + "." + MemberName.GetSignatureForDocumentation ();
353
354                         return MemberName.GetSignatureForDocumentation ();
355                 }
356
357                 public override string GetSignatureForError ()
358                 {
359                         if (Parent != null && Parent.MemberName != null) 
360                                 return Parent.GetSignatureForError () + "." + MemberName.GetSignatureForError ();
361
362                         return MemberName.GetSignatureForError ();
363                 }
364
365                 public string GetSignatureForMetadata ()
366                 {
367                         if (Parent is TypeDefinition) {
368                                 return Parent.GetSignatureForMetadata () + "+" + TypeNameParser.Escape (MemberName.Basename);
369                         }
370
371                         var sb = new StringBuilder ();
372                         CreateMetadataName (sb);
373                         return sb.ToString ();
374                 }
375
376                 public virtual void RemoveContainer (TypeContainer cont)
377                 {
378                         if (containers != null)
379                                 containers.Remove (cont);
380
381                         var tc = Parent == Module ? Module : this;
382                         tc.defined_names.Remove (cont.Basename);
383                 }
384
385                 public virtual void VerifyMembers ()
386                 {
387                         if (containers != null) {
388                                 foreach (TypeContainer tc in containers)
389                                         tc.VerifyMembers ();
390                         }
391                 }
392
393                 public override void WriteDebugSymbol (MonoSymbolFile file)
394                 {
395                         if (containers != null) {
396                                 foreach (TypeContainer tc in containers) {
397                                         tc.WriteDebugSymbol (file);
398                                 }
399                         }
400                 }
401         }
402
403         public abstract class TypeDefinition : TypeContainer, ITypeDefinition
404         {
405                 //
406                 // Different context is needed when resolving type container base
407                 // types. Type names come from the parent scope but type parameter
408                 // names from the container scope.
409                 //
410                 public struct BaseContext : IMemberContext
411                 {
412                         TypeContainer tc;
413
414                         public BaseContext (TypeContainer tc)
415                         {
416                                 this.tc = tc;
417                         }
418
419                         #region IMemberContext Members
420
421                         public CompilerContext Compiler {
422                                 get { return tc.Compiler; }
423                         }
424
425                         public TypeSpec CurrentType {
426                                 get { return tc.Parent.CurrentType; }
427                         }
428
429                         public TypeParameters CurrentTypeParameters {
430                                 get { return tc.PartialContainer.CurrentTypeParameters; }
431                         }
432
433                         public MemberCore CurrentMemberDefinition {
434                                 get { return tc; }
435                         }
436
437                         public bool IsObsolete {
438                                 get { return tc.IsObsolete; }
439                         }
440
441                         public bool IsUnsafe {
442                                 get { return tc.IsUnsafe; }
443                         }
444
445                         public bool IsStatic {
446                                 get { return tc.IsStatic; }
447                         }
448
449                         public ModuleContainer Module {
450                                 get { return tc.Module; }
451                         }
452
453                         public string GetSignatureForError ()
454                         {
455                                 return tc.GetSignatureForError ();
456                         }
457
458                         public ExtensionMethodCandidates LookupExtensionMethod (TypeSpec extensionType, string name, int arity)
459                         {
460                                 return null;
461                         }
462
463                         public FullNamedExpression LookupNamespaceAlias (string name)
464                         {
465                                 return tc.Parent.LookupNamespaceAlias (name);
466                         }
467
468                         public FullNamedExpression LookupNamespaceOrType (string name, int arity, LookupMode mode, Location loc)
469                         {
470                                 if (arity == 0) {
471                                         var tp = CurrentTypeParameters;
472                                         if (tp != null) {
473                                                 TypeParameter t = tp.Find (name);
474                                                 if (t != null)
475                                                         return new TypeParameterExpr (t, loc);
476                                         }
477                                 }
478
479                                 return tc.Parent.LookupNamespaceOrType (name, arity, mode, loc);
480                         }
481
482                         #endregion
483                 }
484
485                 [Flags]
486                 enum CachedMethods
487                 {
488                         Equals                          = 1,
489                         GetHashCode                     = 1 << 1,
490                         HasStaticFieldInitializer       = 1 << 2
491                 }
492
493                 readonly List<MemberCore> members;
494
495                 // Holds a list of fields that have initializers
496                 protected List<FieldInitializer> initialized_fields;
497
498                 // Holds a list of static fields that have initializers
499                 protected List<FieldInitializer> initialized_static_fields;
500
501                 Dictionary<MethodSpec, Method> hoisted_base_call_proxies;
502
503                 Dictionary<string, FullNamedExpression> Cache = new Dictionary<string, FullNamedExpression> ();
504
505                 //
506                 // Points to the first non-static field added to the container.
507                 //
508                 // This is an arbitrary choice.  We are interested in looking at _some_ non-static field,
509                 // and the first one's as good as any.
510                 //
511                 protected FieldBase first_nonstatic_field;
512
513                 //
514                 // This one is computed after we can distinguish interfaces
515                 // from classes from the arraylist `type_bases' 
516                 //
517                 protected TypeSpec base_type;
518                 FullNamedExpression base_type_expr;     // TODO: It's temporary variable
519                 protected TypeSpec[] iface_exprs;
520
521                 protected List<FullNamedExpression> type_bases;
522
523                 // Partial parts for classes only
524                 List<TypeDefinition> class_partial_parts;
525
526                 TypeDefinition InTransit;
527
528                 public TypeBuilder TypeBuilder;
529                 GenericTypeParameterBuilder[] all_tp_builders;
530                 //
531                 // All recursive type parameters put together sharing same
532                 // TypeParameter instances
533                 //
534                 TypeParameters all_type_parameters;
535
536                 public const string DefaultIndexerName = "Item";
537
538                 bool has_normal_indexers;
539                 string indexer_name;
540                 protected bool requires_delayed_unmanagedtype_check;
541                 bool error;
542                 bool members_defined;
543                 bool members_defined_ok;
544                 protected bool has_static_constructor;
545
546                 private CachedMethods cached_method;
547
548                 protected TypeSpec spec;
549                 TypeSpec current_type;
550
551                 public int DynamicSitesCounter;
552                 public int AnonymousMethodsCounter;
553                 public int MethodGroupsCounter;
554
555                 static readonly string[] attribute_targets = new string[] { "type" };
556
557                 /// <remarks>
558                 ///  The pending methods that need to be implemented
559                 //   (interfaces or abstract methods)
560                 /// </remarks>
561                 PendingImplementation pending;
562
563                 protected TypeDefinition (TypeContainer parent, MemberName name, Attributes attrs, MemberKind kind)
564                         : base (parent, name, attrs, kind)
565                 {
566                         PartialContainer = this;
567                         members = new List<MemberCore> ();
568                 }
569
570                 #region Properties
571
572                 public List<FullNamedExpression> BaseTypeExpressions {
573                         get {
574                                 return type_bases;
575                         }
576                 }
577
578                 public override TypeSpec CurrentType {
579                         get {
580                                 if (current_type == null) {
581                                         if (IsGenericOrParentIsGeneric) {
582                                                 //
583                                                 // Switch to inflated version as it's used by all expressions
584                                                 //
585                                                 var targs = CurrentTypeParameters == null ? TypeSpec.EmptyTypes : CurrentTypeParameters.Types;
586                                                 current_type = spec.MakeGenericType (this, targs);
587                                         } else {
588                                                 current_type = spec;
589                                         }
590                                 }
591
592                                 return current_type;
593                         }
594                 }
595
596                 public override TypeParameters CurrentTypeParameters {
597                         get {
598                                 return PartialContainer.MemberName.TypeParameters;
599                         }
600                 }
601
602                 int CurrentTypeParametersStartIndex {
603                         get {
604                                 int total = all_tp_builders.Length;
605                                 if (CurrentTypeParameters != null) {
606                                         return total - CurrentTypeParameters.Count;
607                                 }
608                                 return total;
609                         }
610                 }
611
612                 public virtual AssemblyDefinition DeclaringAssembly {
613                         get {
614                                 return Module.DeclaringAssembly;
615                         }
616                 }
617
618                 IAssemblyDefinition ITypeDefinition.DeclaringAssembly {
619                         get {
620                                 return Module.DeclaringAssembly;
621                         }
622                 }
623
624                 public TypeSpec Definition {
625                         get {
626                                 return spec;
627                         }
628                 }
629
630                 public bool HasMembersDefined {
631                         get {
632                                 return members_defined;
633                         }
634                 }
635
636                 public bool HasInstanceConstructor {
637                         get {
638                                 return (caching_flags & Flags.HasInstanceConstructor) != 0;
639                         }
640                         set {
641                                 caching_flags |= Flags.HasInstanceConstructor;
642                         }
643                 }
644
645                 // Indicated whether container has StructLayout attribute set Explicit
646                 public bool HasExplicitLayout {
647                         get { return (caching_flags & Flags.HasExplicitLayout) != 0; }
648                         set { caching_flags |= Flags.HasExplicitLayout; }
649                 }
650
651                 public bool HasOperators {
652                         get {
653                                 return (caching_flags & Flags.HasUserOperators) != 0;
654                         }
655                         set {
656                                 caching_flags |= Flags.HasUserOperators;
657                         }
658                 }
659
660                 public bool HasStructLayout {
661                         get { return (caching_flags & Flags.HasStructLayout) != 0; }
662                         set { caching_flags |= Flags.HasStructLayout; }
663                 }
664
665                 public TypeSpec[] Interfaces {
666                         get {
667                                 return iface_exprs;
668                         }
669                 }
670
671                 public bool IsGenericOrParentIsGeneric {
672                         get {
673                                 return all_type_parameters != null;
674                         }
675                 }
676
677                 public bool IsTopLevel {
678                         get {
679                                 return !(Parent is TypeDefinition);
680                         }
681                 }
682
683                 public bool IsPartial {
684                         get {
685                                 return (ModFlags & Modifiers.PARTIAL) != 0;
686                         }
687                 }
688
689                 bool ITypeDefinition.IsTypeForwarder {
690                         get {
691                                 return false;
692                         }
693                 }
694
695                 bool ITypeDefinition.IsCyclicTypeForwarder {
696                         get {
697                                 return false;
698                         }
699                 }
700
701                 //
702                 // Returns true for secondary partial containers
703                 //
704                 bool IsPartialPart {
705                         get {
706                                 return PartialContainer != this;
707                         }
708                 }
709
710                 public MemberCache MemberCache {
711                         get {
712                                 return spec.MemberCache;
713                         }
714                 }
715
716                 public List<MemberCore> Members {
717                         get {
718                                 return members;
719                         }
720                 }
721
722                 string ITypeDefinition.Namespace {
723                         get {
724                                 var p = Parent;
725                                 while (p.Kind != MemberKind.Namespace)
726                                         p = p.Parent;
727
728                                 return p.MemberName == null ? null : p.GetSignatureForError ();
729                         }
730                 }
731
732                 public TypeParameters TypeParametersAll {
733                         get {
734                                 return all_type_parameters;
735                         }
736                 }
737
738                 public override string[] ValidAttributeTargets {
739                         get {
740                                 return attribute_targets;
741                         }
742                 }
743
744                 #endregion
745
746                 public override void Accept (StructuralVisitor visitor)
747                 {
748                         visitor.Visit (this);
749                 }
750
751                 public void AddMember (MemberCore symbol)
752                 {
753                         if (symbol.MemberName.ExplicitInterface != null) {
754                                 if (!(Kind == MemberKind.Class || Kind == MemberKind.Struct)) {
755                                         Report.Error (541, symbol.Location,
756                                                 "`{0}': explicit interface declaration can only be declared in a class or struct",
757                                                 symbol.GetSignatureForError ());
758                                 }
759                         }
760
761                         AddNameToContainer (symbol, symbol.MemberName.Name);
762                         members.Add (symbol);
763                 }
764
765                 public override void AddTypeContainer (TypeContainer tc)
766                 {
767                         AddNameToContainer (tc, tc.Basename);
768
769                         base.AddTypeContainer (tc);
770                 }
771
772                 protected override void AddTypeContainerMember (TypeContainer tc)
773                 {
774                         members.Add (tc);
775
776                         if (containers == null)
777                                 containers = new List<TypeContainer> ();
778
779                         base.AddTypeContainerMember (tc);
780                 }
781
782                 //
783                 // Adds the member to defined_names table. It tests for duplications and enclosing name conflicts
784                 //
785                 public virtual void AddNameToContainer (MemberCore symbol, string name)
786                 {
787                         if (((ModFlags | symbol.ModFlags) & Modifiers.COMPILER_GENERATED) != 0)
788                                 return;
789
790                         MemberCore mc;
791                         if (!PartialContainer.defined_names.TryGetValue (name, out mc)) {
792                                 PartialContainer.defined_names.Add (name, symbol);
793                                 return;
794                         }
795
796                         if (symbol.EnableOverloadChecks (mc))
797                                 return;
798
799                         InterfaceMemberBase im = mc as InterfaceMemberBase;
800                         if (im != null && im.IsExplicitImpl)
801                                 return;
802
803                         Report.SymbolRelatedToPreviousError (mc);
804                         if ((mc.ModFlags & Modifiers.PARTIAL) != 0 && (symbol is ClassOrStruct || symbol is Interface)) {
805                                 Error_MissingPartialModifier (symbol);
806                                 return;
807                         }
808
809                         if (symbol is TypeParameter) {
810                                 Report.Error (692, symbol.Location,
811                                         "Duplicate type parameter `{0}'", symbol.GetSignatureForError ());
812                         } else {
813                                 Report.Error (102, symbol.Location,
814                                         "The type `{0}' already contains a definition for `{1}'",
815                                         GetSignatureForError (), name);
816                         }
817
818                         return;
819                 }
820         
821                 public void AddConstructor (Constructor c)
822                 {
823                         AddConstructor (c, false);
824                 }
825
826                 public void AddConstructor (Constructor c, bool isDefault)
827                 {
828                         bool is_static = (c.ModFlags & Modifiers.STATIC) != 0;
829                         if (!isDefault)
830                                 AddNameToContainer (c, is_static ? Constructor.TypeConstructorName : Constructor.ConstructorName);
831
832                         if (is_static && c.ParameterInfo.IsEmpty) {
833                                 PartialContainer.has_static_constructor = true;
834                         } else {
835                                 PartialContainer.HasInstanceConstructor = true;
836                         }
837
838                         members.Add (c);
839                 }
840
841                 public bool AddField (FieldBase field)
842                 {
843                         AddMember (field);
844
845                         if ((field.ModFlags & Modifiers.STATIC) != 0)
846                                 return true;
847
848                         var first_field = PartialContainer.first_nonstatic_field;
849                         if (first_field == null) {
850                                 PartialContainer.first_nonstatic_field = field;
851                                 return true;
852                         }
853
854                         if (Kind == MemberKind.Struct && first_field.Parent != field.Parent) {
855                                 Report.SymbolRelatedToPreviousError (first_field.Parent);
856                                 Report.Warning (282, 3, field.Location,
857                                         "struct instance field `{0}' found in different declaration from instance field `{1}'",
858                                         field.GetSignatureForError (), first_field.GetSignatureForError ());
859                         }
860                         return true;
861                 }
862
863                 /// <summary>
864                 /// Indexer has special handling in constrast to other AddXXX because the name can be driven by IndexerNameAttribute
865                 /// </summary>
866                 public void AddIndexer (Indexer i)
867                 {
868                         members.Add (i);
869                 }
870
871                 public void AddOperator (Operator op)
872                 {
873                         PartialContainer.HasOperators = true;
874                         AddMember (op);
875                 }
876
877                 public void AddPartialPart (TypeDefinition part)
878                 {
879                         if (Kind != MemberKind.Class)
880                                 return;
881
882                         if (class_partial_parts == null)
883                                 class_partial_parts = new List<TypeDefinition> ();
884
885                         class_partial_parts.Add (part);
886                 }
887
888                 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
889                 {
890                         if (has_normal_indexers && a.Type == pa.DefaultMember) {
891                                 Report.Error (646, a.Location, "Cannot specify the `DefaultMember' attribute on type containing an indexer");
892                                 return;
893                         }
894
895                         if (a.Type == pa.Required) {
896                                 Report.Error (1608, a.Location, "The RequiredAttribute attribute is not permitted on C# types");
897                                 return;
898                         }
899
900                         TypeBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
901                 } 
902
903                 public override AttributeTargets AttributeTargets {
904                         get {
905                                 throw new NotSupportedException ();
906                         }
907                 }
908
909                 public TypeSpec BaseType {
910                         get {
911                                 return spec.BaseType;
912                         }
913                 }
914
915                 protected virtual TypeAttributes TypeAttr {
916                         get {
917                                 return ModifiersExtensions.TypeAttr (ModFlags, IsTopLevel);
918                         }
919                 }
920
921                 public int TypeParametersCount {
922                         get {
923                                 return MemberName.Arity;
924                         }
925                 }
926
927                 TypeParameterSpec[] ITypeDefinition.TypeParameters {
928                         get {
929                                 return PartialContainer.CurrentTypeParameters.Types;
930                         }
931                 }
932
933                 public string GetAttributeDefaultMember ()
934                 {
935                         return indexer_name ?? DefaultIndexerName;
936                 }
937
938                 public bool IsComImport {
939                         get {
940                                 if (OptAttributes == null)
941                                         return false;
942
943                                 return OptAttributes.Contains (Module.PredefinedAttributes.ComImport);
944                         }
945                 }
946
947                 public virtual void RegisterFieldForInitialization (MemberCore field, FieldInitializer expression)
948                 {
949                         if (IsPartialPart)
950                                 PartialContainer.RegisterFieldForInitialization (field, expression);
951
952                         if ((field.ModFlags & Modifiers.STATIC) != 0){
953                                 if (initialized_static_fields == null) {
954                                         HasStaticFieldInitializer = true;
955                                         initialized_static_fields = new List<FieldInitializer> (4);
956                                 }
957
958                                 initialized_static_fields.Add (expression);
959                         } else {
960                                 if (initialized_fields == null)
961                                         initialized_fields = new List<FieldInitializer> (4);
962
963                                 initialized_fields.Add (expression);
964                         }
965                 }
966
967                 public void ResolveFieldInitializers (BlockContext ec)
968                 {
969                         Debug.Assert (!IsPartialPart);
970
971                         if (ec.IsStatic) {
972                                 if (initialized_static_fields == null)
973                                         return;
974
975                                 bool has_complex_initializer = !ec.Module.Compiler.Settings.Optimize;
976                                 int i;
977                                 ExpressionStatement [] init = new ExpressionStatement [initialized_static_fields.Count];
978                                 for (i = 0; i < initialized_static_fields.Count; ++i) {
979                                         FieldInitializer fi = initialized_static_fields [i];
980                                         ExpressionStatement s = fi.ResolveStatement (ec);
981                                         if (s == null) {
982                                                 s = EmptyExpressionStatement.Instance;
983                                         } else if (!fi.IsSideEffectFree) {
984                                                 has_complex_initializer = true;
985                                         }
986
987                                         init [i] = s;
988                                 }
989
990                                 for (i = 0; i < initialized_static_fields.Count; ++i) {
991                                         FieldInitializer fi = initialized_static_fields [i];
992                                         //
993                                         // Need special check to not optimize code like this
994                                         // static int a = b = 5;
995                                         // static int b = 0;
996                                         //
997                                         if (!has_complex_initializer && fi.IsDefaultInitializer)
998                                                 continue;
999
1000                                         ec.AssignmentInfoOffset += fi.AssignmentOffset;
1001                                         ec.CurrentBlock.AddScopeStatement (new StatementExpression (init [i]));
1002                                 }
1003
1004                                 return;
1005                         }
1006
1007                         if (initialized_fields == null)
1008                                 return;
1009
1010                         for (int i = 0; i < initialized_fields.Count; ++i) {
1011                                 FieldInitializer fi = initialized_fields [i];
1012                                 ExpressionStatement s = fi.ResolveStatement (ec);
1013                                 if (s == null)
1014                                         continue;
1015
1016                                 //
1017                                 // Field is re-initialized to its default value => removed
1018                                 //
1019                                 if (fi.IsDefaultInitializer && ec.Module.Compiler.Settings.Optimize)
1020                                         continue;
1021
1022                                 ec.AssignmentInfoOffset += fi.AssignmentOffset;
1023                                 ec.CurrentBlock.AddScopeStatement (new StatementExpression (s));
1024                         }
1025                 }
1026
1027                 public override string DocComment {
1028                         get {
1029                                 return comment;
1030                         }
1031                         set {
1032                                 if (value == null)
1033                                         return;
1034
1035                                 comment += value;
1036                         }
1037                 }
1038
1039                 public PendingImplementation PendingImplementations {
1040                         get { return pending; }
1041                 }
1042
1043                 internal override void GenerateDocComment (DocumentationBuilder builder)
1044                 {
1045                         if (IsPartialPart)
1046                                 return;
1047
1048                         base.GenerateDocComment (builder);
1049
1050                         foreach (var member in members)
1051                                 member.GenerateDocComment (builder);
1052                 }
1053
1054                 public TypeSpec GetAttributeCoClass ()
1055                 {
1056                         if (OptAttributes == null)
1057                                 return null;
1058
1059                         Attribute a = OptAttributes.Search (Module.PredefinedAttributes.CoClass);
1060                         if (a == null)
1061                                 return null;
1062
1063                         return a.GetCoClassAttributeValue ();
1064                 }
1065
1066                 public AttributeUsageAttribute GetAttributeUsage (PredefinedAttribute pa)
1067                 {
1068                         Attribute a = null;
1069                         if (OptAttributes != null) {
1070                                 a = OptAttributes.Search (pa);
1071                         }
1072
1073                         if (a == null)
1074                                 return null;
1075
1076                         return a.GetAttributeUsageAttribute ();
1077                 }
1078
1079                 public virtual CompilationSourceFile GetCompilationSourceFile ()
1080                 {
1081                         TypeContainer ns = Parent;
1082                         while (true) {
1083                                 var sf = ns as CompilationSourceFile;
1084                                 if (sf != null)
1085                                         return sf;
1086
1087                                 ns = ns.Parent;
1088                         }
1089                 }
1090
1091                 public virtual void SetBaseTypes (List<FullNamedExpression> baseTypes)
1092                 {
1093                         type_bases = baseTypes;
1094                 }
1095
1096                 /// <summary>
1097                 ///   This function computes the Base class and also the
1098                 ///   list of interfaces that the class or struct @c implements.
1099                 ///   
1100                 ///   The return value is an array (might be null) of
1101                 ///   interfaces implemented (as Types).
1102                 ///   
1103                 ///   The @base_class argument is set to the base object or null
1104                 ///   if this is `System.Object'. 
1105                 /// </summary>
1106                 protected virtual TypeSpec[] ResolveBaseTypes (out FullNamedExpression base_class)
1107                 {
1108                         base_class = null;
1109                         if (type_bases == null)
1110                                 return null;
1111
1112                         int count = type_bases.Count;
1113                         TypeSpec[] ifaces = null;
1114                         var base_context = new BaseContext (this);
1115                         for (int i = 0, j = 0; i < count; i++){
1116                                 FullNamedExpression fne = type_bases [i];
1117
1118                                 var fne_resolved = fne.ResolveAsType (base_context);
1119                                 if (fne_resolved == null)
1120                                         continue;
1121
1122                                 if (i == 0 && Kind == MemberKind.Class && !fne_resolved.IsInterface) {
1123                                         if (fne_resolved.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
1124                                                 Report.Error (1965, Location, "Class `{0}' cannot derive from the dynamic type",
1125                                                         GetSignatureForError ());
1126
1127                                                 continue;
1128                                         }
1129                                         
1130                                         base_type = fne_resolved;
1131                                         base_class = fne;
1132                                         continue;
1133                                 }
1134
1135                                 if (ifaces == null)
1136                                         ifaces = new TypeSpec [count - i];
1137
1138                                 if (fne_resolved.IsInterface) {
1139                                         for (int ii = 0; ii < j; ++ii) {
1140                                                 if (fne_resolved == ifaces [ii]) {
1141                                                         Report.Error (528, Location, "`{0}' is already listed in interface list",
1142                                                                 fne_resolved.GetSignatureForError ());
1143                                                         break;
1144                                                 }
1145                                         }
1146
1147                                         if (Kind == MemberKind.Interface && !IsAccessibleAs (fne_resolved)) {
1148                                                 Report.Error (61, fne.Location,
1149                                                         "Inconsistent accessibility: base interface `{0}' is less accessible than interface `{1}'",
1150                                                         fne_resolved.GetSignatureForError (), GetSignatureForError ());
1151                                         }
1152                                 } else {
1153                                         Report.SymbolRelatedToPreviousError (fne_resolved);
1154                                         if (Kind != MemberKind.Class) {
1155                                                 Report.Error (527, fne.Location, "Type `{0}' in interface list is not an interface", fne_resolved.GetSignatureForError ());
1156                                         } else if (base_class != null)
1157                                                 Report.Error (1721, fne.Location, "`{0}': Classes cannot have multiple base classes (`{1}' and `{2}')",
1158                                                         GetSignatureForError (), base_class.GetSignatureForError (), fne_resolved.GetSignatureForError ());
1159                                         else {
1160                                                 Report.Error (1722, fne.Location, "`{0}': Base class `{1}' must be specified as first",
1161                                                         GetSignatureForError (), fne_resolved.GetSignatureForError ());
1162                                         }
1163                                 }
1164
1165                                 ifaces [j++] = fne_resolved;
1166                         }
1167
1168                         return ifaces;
1169                 }
1170
1171                 //
1172                 // Checks that some operators come in pairs:
1173                 //  == and !=
1174                 // > and <
1175                 // >= and <=
1176                 // true and false
1177                 //
1178                 // They are matched based on the return type and the argument types
1179                 //
1180                 void CheckPairedOperators ()
1181                 {
1182                         bool has_equality_or_inequality = false;
1183                         List<Operator.OpType> found_matched = new List<Operator.OpType> ();
1184
1185                         for (int i = 0; i < members.Count; ++i) {
1186                                 var o_a = members[i] as Operator;
1187                                 if (o_a == null)
1188                                         continue;
1189
1190                                 var o_type = o_a.OperatorType;
1191                                 if (o_type == Operator.OpType.Equality || o_type == Operator.OpType.Inequality)
1192                                         has_equality_or_inequality = true;
1193
1194                                 if (found_matched.Contains (o_type))
1195                                         continue;
1196
1197                                 var matching_type = o_a.GetMatchingOperator ();
1198                                 if (matching_type == Operator.OpType.TOP) {
1199                                         continue;
1200                                 }
1201
1202                                 bool pair_found = false;
1203                                 for (int ii = 0; ii < members.Count; ++ii) {
1204                                         var o_b = members[ii] as Operator;
1205                                         if (o_b == null || o_b.OperatorType != matching_type)
1206                                                 continue;
1207
1208                                         if (!TypeSpecComparer.IsEqual (o_a.ReturnType, o_b.ReturnType))
1209                                                 continue;
1210
1211                                         if (!TypeSpecComparer.Equals (o_a.ParameterTypes, o_b.ParameterTypes))
1212                                                 continue;
1213
1214                                         found_matched.Add (matching_type);
1215                                         pair_found = true;
1216                                         break;
1217                                 }
1218
1219                                 if (!pair_found) {
1220                                         Report.Error (216, o_a.Location,
1221                                                 "The operator `{0}' requires a matching operator `{1}' to also be defined",
1222                                                 o_a.GetSignatureForError (), Operator.GetName (matching_type));
1223                                 }
1224                         }
1225
1226                         if (has_equality_or_inequality) {
1227                                 if (!HasEquals)
1228                                         Report.Warning (660, 2, Location, "`{0}' defines operator == or operator != but does not override Object.Equals(object o)",
1229                                                 GetSignatureForError ());
1230
1231                                 if (!HasGetHashCode)
1232                                         Report.Warning (661, 2, Location, "`{0}' defines operator == or operator != but does not override Object.GetHashCode()",
1233                                                 GetSignatureForError ());
1234                         }
1235                 }
1236
1237                 public override void CreateMetadataName (StringBuilder sb)
1238                 {
1239                         if (Parent.MemberName != null) {
1240                                 Parent.CreateMetadataName (sb);
1241
1242                                 if (sb.Length != 0) {
1243                                         sb.Append (".");
1244                                 }
1245                         }
1246
1247                         sb.Append (MemberName.Basename);
1248                 }
1249         
1250                 bool CreateTypeBuilder ()
1251                 {
1252                         //
1253                         // Sets .size to 1 for structs with no instance fields
1254                         //
1255                         int type_size = Kind == MemberKind.Struct && first_nonstatic_field == null && !(this is StateMachine) ? 1 : 0;
1256
1257                         var parent_def = Parent as TypeDefinition;
1258                         if (parent_def == null) {
1259                                 var sb = new StringBuilder ();
1260                                 CreateMetadataName (sb);
1261                                 TypeBuilder = Module.CreateBuilder (sb.ToString (), TypeAttr, type_size);
1262                         } else {
1263                                 TypeBuilder = parent_def.TypeBuilder.DefineNestedType (Basename, TypeAttr, null, type_size);
1264                         }
1265
1266                         if (DeclaringAssembly.Importer != null)
1267                                 DeclaringAssembly.Importer.AddCompiledType (TypeBuilder, spec);
1268
1269                         spec.SetMetaInfo (TypeBuilder);
1270                         spec.MemberCache = new MemberCache (this);
1271
1272                         TypeParameters parentAllTypeParameters = null;
1273                         if (parent_def != null) {
1274                                 spec.DeclaringType = Parent.CurrentType;
1275                                 parent_def.MemberCache.AddMember (spec);
1276                                 parentAllTypeParameters = parent_def.all_type_parameters;
1277                         }
1278
1279                         if (MemberName.TypeParameters != null || parentAllTypeParameters != null) {
1280                                 var tparam_names = CreateTypeParameters (parentAllTypeParameters);
1281
1282                                 all_tp_builders = TypeBuilder.DefineGenericParameters (tparam_names);
1283
1284                                 if (CurrentTypeParameters != null) {
1285                                         CurrentTypeParameters.Create (spec, CurrentTypeParametersStartIndex, this);
1286                                         CurrentTypeParameters.Define (all_tp_builders);
1287                                 }
1288                         }
1289
1290                         return true;
1291                 }
1292
1293                 string[] CreateTypeParameters (TypeParameters parentAllTypeParameters)
1294                 {
1295                         string[] names;
1296                         int parent_offset = 0;
1297                         if (parentAllTypeParameters != null) {
1298                                 if (CurrentTypeParameters == null) {
1299                                         all_type_parameters = parentAllTypeParameters;
1300                                         return parentAllTypeParameters.GetAllNames ();
1301                                 }
1302
1303                                 names = new string[parentAllTypeParameters.Count + CurrentTypeParameters.Count];
1304                                 all_type_parameters = new TypeParameters (names.Length);
1305                                 all_type_parameters.Add (parentAllTypeParameters);
1306
1307                                 parent_offset = all_type_parameters.Count;
1308                                 for (int i = 0; i < parent_offset; ++i)
1309                                         names[i] = all_type_parameters[i].MemberName.Name;
1310
1311                         } else {
1312                                 names = new string[CurrentTypeParameters.Count];
1313                         }
1314
1315                         for (int i = 0; i < CurrentTypeParameters.Count; ++i) {
1316                                 if (all_type_parameters != null)
1317                                         all_type_parameters.Add (MemberName.TypeParameters[i]);
1318
1319                                 var name = CurrentTypeParameters[i].MemberName.Name;
1320                                 names[parent_offset + i] = name;
1321                                 for (int ii = 0; ii < parent_offset + i; ++ii) {
1322                                         if (names[ii] != name)
1323                                                 continue;
1324
1325                                         var tp = CurrentTypeParameters[i];
1326                                         var conflict = all_type_parameters[ii];
1327
1328                                         tp.WarningParentNameConflict (conflict);
1329                                 }
1330                         }
1331
1332                         if (all_type_parameters == null)
1333                                 all_type_parameters = CurrentTypeParameters;
1334
1335                         return names;
1336                 }
1337
1338
1339                 public SourceMethodBuilder CreateMethodSymbolEntry ()
1340                 {
1341                         if (Module.DeclaringAssembly.SymbolWriter == null)
1342                                 return null;
1343
1344                         var source_file = GetCompilationSourceFile ();
1345                         if (source_file == null)
1346                                 return null;
1347
1348                         return new SourceMethodBuilder (source_file.SymbolUnitEntry);
1349                 }
1350
1351                 //
1352                 // Creates a proxy base method call inside this container for hoisted base member calls
1353                 //
1354                 public MethodSpec CreateHoistedBaseCallProxy (ResolveContext rc, MethodSpec method)
1355                 {
1356                         Method proxy_method;
1357
1358                         //
1359                         // One proxy per base method is enough
1360                         //
1361                         if (hoisted_base_call_proxies == null) {
1362                                 hoisted_base_call_proxies = new Dictionary<MethodSpec, Method> ();
1363                                 proxy_method = null;
1364                         } else {
1365                                 hoisted_base_call_proxies.TryGetValue (method, out proxy_method);
1366                         }
1367
1368                         if (proxy_method == null) {
1369                                 string name = CompilerGeneratedContainer.MakeName (method.Name, null, "BaseCallProxy", hoisted_base_call_proxies.Count);
1370
1371                                 MemberName member_name;
1372                                 TypeArguments targs = null;
1373                                 TypeSpec return_type = method.ReturnType;
1374                                 var local_param_types = method.Parameters.Types;
1375
1376                                 if (method.IsGeneric) {
1377                                         //
1378                                         // Copy all base generic method type parameters info
1379                                         //
1380                                         var hoisted_tparams = method.GenericDefinition.TypeParameters;
1381                                         var tparams = new TypeParameters ();
1382
1383                                         targs = new TypeArguments ();
1384                                         targs.Arguments = new TypeSpec[hoisted_tparams.Length];
1385                                         for (int i = 0; i < hoisted_tparams.Length; ++i) {
1386                                                 var tp = hoisted_tparams[i];
1387                                                 var local_tp = new TypeParameter (tp, null, new MemberName (tp.Name, Location), null);
1388                                                 tparams.Add (local_tp);
1389
1390                                                 targs.Add (new SimpleName (tp.Name, Location));
1391                                                 targs.Arguments[i] = local_tp.Type;
1392                                         }
1393
1394                                         member_name = new MemberName (name, tparams, Location);
1395
1396                                         //
1397                                         // Mutate any method type parameters from original
1398                                         // to newly created hoisted version
1399                                         //
1400                                         var mutator = new TypeParameterMutator (hoisted_tparams, tparams);
1401                                         return_type = mutator.Mutate (return_type);
1402                                         local_param_types = mutator.Mutate (local_param_types);
1403                                 } else {
1404                                         member_name = new MemberName (name);
1405                                 }
1406
1407                                 var base_parameters = new Parameter[method.Parameters.Count];
1408                                 for (int i = 0; i < base_parameters.Length; ++i) {
1409                                         var base_param = method.Parameters.FixedParameters[i];
1410                                         base_parameters[i] = new Parameter (new TypeExpression (local_param_types [i], Location),
1411                                                 base_param.Name, base_param.ModFlags, null, Location);
1412                                         base_parameters[i].Resolve (this, i);
1413                                 }
1414
1415                                 var cloned_params = ParametersCompiled.CreateFullyResolved (base_parameters, method.Parameters.Types);
1416                                 if (method.Parameters.HasArglist) {
1417                                         cloned_params.FixedParameters[0] = new Parameter (null, "__arglist", Parameter.Modifier.NONE, null, Location);
1418                                         cloned_params.Types[0] = Module.PredefinedTypes.RuntimeArgumentHandle.Resolve ();
1419                                 }
1420
1421                                 // Compiler generated proxy
1422                                 proxy_method = new Method (this, new TypeExpression (return_type, Location),
1423                                         Modifiers.PRIVATE | Modifiers.COMPILER_GENERATED | Modifiers.DEBUGGER_HIDDEN,
1424                                         member_name, cloned_params, null);
1425
1426                                 var block = new ToplevelBlock (Compiler, proxy_method.ParameterInfo, Location) {
1427                                         IsCompilerGenerated = true
1428                                 };
1429
1430                                 var mg = MethodGroupExpr.CreatePredefined (method, method.DeclaringType, Location);
1431                                 mg.InstanceExpression = new BaseThis (method.DeclaringType, Location);
1432                                 if (targs != null)
1433                                         mg.SetTypeArguments (rc, targs);
1434
1435                                 // Get all the method parameters and pass them as arguments
1436                                 var real_base_call = new Invocation (mg, block.GetAllParametersArguments ());
1437                                 Statement statement;
1438                                 if (method.ReturnType.Kind == MemberKind.Void)
1439                                         statement = new StatementExpression (real_base_call);
1440                                 else
1441                                         statement = new Return (real_base_call, Location);
1442
1443                                 block.AddStatement (statement);
1444                                 proxy_method.Block = block;
1445
1446                                 members.Add (proxy_method);
1447                                 proxy_method.Define ();
1448                                 proxy_method.PrepareEmit ();
1449
1450                                 hoisted_base_call_proxies.Add (method, proxy_method);
1451                         }
1452
1453                         return proxy_method.Spec;
1454                 }
1455
1456                 protected bool DefineBaseTypes ()
1457                 {
1458                         if (IsPartialPart && Kind == MemberKind.Class)
1459                                 return true;
1460
1461                         return DoDefineBaseType ();
1462                 }
1463
1464                 bool DoDefineBaseType ()
1465                 {
1466                         iface_exprs = ResolveBaseTypes (out base_type_expr);
1467                         bool set_base_type;
1468
1469                         if (IsPartialPart) {
1470                                 set_base_type = false;
1471
1472                                 if (base_type_expr != null) {
1473                                         if (PartialContainer.base_type_expr != null && PartialContainer.base_type != base_type) {
1474                                                 Report.SymbolRelatedToPreviousError (base_type_expr.Location, "");
1475                                                 Report.Error (263, Location,
1476                                                         "Partial declarations of `{0}' must not specify different base classes",
1477                                                         GetSignatureForError ());
1478                                         } else {
1479                                                 PartialContainer.base_type_expr = base_type_expr;
1480                                                 PartialContainer.base_type = base_type;
1481                                                 set_base_type = true;
1482                                         }
1483                                 }
1484
1485                                 if (iface_exprs != null) {
1486                                         if (PartialContainer.iface_exprs == null)
1487                                                 PartialContainer.iface_exprs = iface_exprs;
1488                                         else {
1489                                                 var ifaces = new List<TypeSpec> (PartialContainer.iface_exprs);
1490                                                 foreach (var iface_partial in iface_exprs) {
1491                                                         if (ifaces.Contains (iface_partial))
1492                                                                 continue;
1493
1494                                                         ifaces.Add (iface_partial);
1495                                                 }
1496
1497                                                 PartialContainer.iface_exprs = ifaces.ToArray ();
1498                                         }
1499                                 }
1500
1501                                 PartialContainer.members.AddRange (members);
1502                                 if (containers != null) {
1503                                         if (PartialContainer.containers == null)
1504                                                 PartialContainer.containers = new List<TypeContainer> ();
1505
1506                                         PartialContainer.containers.AddRange (containers);
1507                                 }
1508
1509                                 members_defined = members_defined_ok = true;
1510                                 caching_flags |= Flags.CloseTypeCreated;
1511                         } else {
1512                                 set_base_type = true;
1513                         }
1514
1515                         var cycle = CheckRecursiveDefinition (this);
1516                         if (cycle != null) {
1517                                 Report.SymbolRelatedToPreviousError (cycle);
1518                                 if (this is Interface) {
1519                                         Report.Error (529, Location,
1520                                                 "Inherited interface `{0}' causes a cycle in the interface hierarchy of `{1}'",
1521                                             GetSignatureForError (), cycle.GetSignatureForError ());
1522
1523                                         iface_exprs = null;
1524                                         PartialContainer.iface_exprs = null;
1525                                 } else {
1526                                         Report.Error (146, Location,
1527                                                 "Circular base class dependency involving `{0}' and `{1}'",
1528                                                 GetSignatureForError (), cycle.GetSignatureForError ());
1529
1530                                         base_type = null;
1531                                         PartialContainer.base_type = null;
1532                                 }
1533                         }
1534
1535                         if (iface_exprs != null) {
1536                                 foreach (var iface_type in iface_exprs) {
1537                                         // Prevents a crash, the interface might not have been resolved: 442144
1538                                         if (iface_type == null)
1539                                                 continue;
1540                                         
1541                                         if (!spec.AddInterfaceDefined (iface_type))
1542                                                 continue;
1543
1544                                         TypeBuilder.AddInterfaceImplementation (iface_type.GetMetaInfo ());
1545                                 }
1546                         }
1547
1548                         if (Kind == MemberKind.Interface) {
1549                                 spec.BaseType = Compiler.BuiltinTypes.Object;
1550                                 return true;
1551                         }
1552
1553                         if (set_base_type) {
1554                                 SetBaseType ();
1555                         }
1556
1557                         //
1558                         // Base type of partial container has to be resolved before we
1559                         // resolve any nested types of the container. We need to know
1560                         // partial parts because the base type can be specified in file
1561                         // defined after current container
1562                         //
1563                         if (class_partial_parts != null) {
1564                                 foreach (var pp in class_partial_parts)
1565                                         pp.DoDefineBaseType ();
1566
1567                         }
1568
1569                         return true;
1570                 }
1571
1572                 void SetBaseType ()
1573                 {
1574                         if (base_type == null) {
1575                                 TypeBuilder.SetParent (null);
1576                                 return;
1577                         }
1578
1579                         if (spec.BaseType == base_type)
1580                                 return;
1581
1582                         spec.BaseType = base_type;
1583
1584                         if (IsPartialPart)
1585                                 spec.UpdateInflatedInstancesBaseType ();
1586
1587                         // Set base type after type creation
1588                         TypeBuilder.SetParent (base_type.GetMetaInfo ());
1589                 }
1590
1591                 public override void ExpandBaseInterfaces ()
1592                 {
1593                         if (!IsPartialPart)
1594                                 DoExpandBaseInterfaces ();
1595
1596                         base.ExpandBaseInterfaces ();
1597                 }
1598
1599                 public void DoExpandBaseInterfaces ()
1600                 {
1601                         if ((caching_flags & Flags.InterfacesExpanded) != 0)
1602                                 return;
1603
1604                         caching_flags |= Flags.InterfacesExpanded;
1605
1606                         //
1607                         // Expand base interfaces. It cannot be done earlier because all partial
1608                         // interface parts need to be defined before the type they are used from
1609                         //
1610                         if (iface_exprs != null) {
1611                                 foreach (var iface in iface_exprs) {
1612                                         if (iface == null)
1613                                                 continue;
1614
1615                                         var td = iface.MemberDefinition as TypeDefinition;
1616                                         if (td != null)
1617                                                 td.DoExpandBaseInterfaces ();
1618
1619                                         if (iface.Interfaces == null)
1620                                                 continue;
1621
1622                                         foreach (var biface in iface.Interfaces) {
1623                                                 if (spec.AddInterfaceDefined (biface)) {
1624                                                         TypeBuilder.AddInterfaceImplementation (biface.GetMetaInfo ());
1625                                                 }
1626                                         }
1627                                 }
1628                         }
1629
1630                         //
1631                         // Include all base type interfaces too, see ImportTypeBase for details
1632                         //
1633                         if (base_type != null) {
1634                                 var td = base_type.MemberDefinition as TypeDefinition;
1635                                 if (td != null)
1636                                         td.DoExpandBaseInterfaces ();
1637
1638                                 //
1639                                 // Simply use base interfaces only, they are all expanded which makes
1640                                 // it easy to handle generic type argument propagation with single
1641                                 // inflator only.
1642                                 //
1643                                 // interface IA<T> : IB<T>
1644                                 // interface IB<U> : IC<U>
1645                                 // interface IC<V>
1646                                 //
1647                                 if (base_type.Interfaces != null) {
1648                                         foreach (var iface in base_type.Interfaces) {
1649                                                 spec.AddInterfaceDefined (iface);
1650                                         }
1651                                 }
1652                         }
1653                 }
1654
1655                 public override void PrepareEmit ()
1656                 {
1657                         if ((caching_flags & Flags.CloseTypeCreated) != 0)
1658                                 return;
1659
1660                         foreach (var member in members) {
1661                                 var pm = member as IParametersMember;
1662                                 if (pm != null) {
1663                                         var mc = member as MethodOrOperator;
1664                                         if (mc != null) {
1665                                                 mc.PrepareEmit ();
1666                                         }
1667
1668                                         var p = pm.Parameters;
1669                                         if (p.IsEmpty)
1670                                                 continue;
1671
1672                                         ((ParametersCompiled) p).ResolveDefaultValues (member);
1673                                 }
1674
1675                                 var c = member as Const;
1676                                 if (c != null)
1677                                         c.DefineValue ();
1678                         }
1679
1680                         base.PrepareEmit ();
1681                 }
1682
1683                 //
1684                 // Defines the type in the appropriate ModuleBuilder or TypeBuilder.
1685                 //
1686                 public override bool CreateContainer ()
1687                 {
1688                         if (TypeBuilder != null)
1689                                 return !error;
1690
1691                         if (error)
1692                                 return false;
1693
1694                         if (IsPartialPart) {
1695                                 spec = PartialContainer.spec;
1696                                 TypeBuilder = PartialContainer.TypeBuilder;
1697                                 all_tp_builders = PartialContainer.all_tp_builders;
1698                                 all_type_parameters = PartialContainer.all_type_parameters;
1699                         } else {
1700                                 if (!CreateTypeBuilder ()) {
1701                                         error = true;
1702                                         return false;
1703                                 }
1704                         }
1705
1706                         return base.CreateContainer ();
1707                 }
1708
1709                 protected override void DoDefineContainer ()
1710                 {
1711                         DefineBaseTypes ();
1712
1713                         DoResolveTypeParameters ();
1714                 }
1715
1716                 //
1717                 // Replaces normal spec with predefined one when compiling corlib
1718                 // and this type container defines predefined type
1719                 //
1720                 public void SetPredefinedSpec (BuiltinTypeSpec spec)
1721                 {
1722                         // When compiling build-in types we start with two
1723                         // version of same type. One is of BuiltinTypeSpec and
1724                         // second one is ordinary TypeSpec. The unification
1725                         // happens at later stage when we know which type
1726                         // really matches the builtin type signature. However
1727                         // that means TypeSpec create during CreateType of this
1728                         // type has to be replaced with builtin one
1729                         // 
1730                         spec.SetMetaInfo (TypeBuilder);
1731                         spec.MemberCache = this.spec.MemberCache;
1732                         spec.DeclaringType = this.spec.DeclaringType;
1733
1734                         this.spec = spec;
1735                         current_type = null;
1736                 }
1737
1738                 public override void RemoveContainer (TypeContainer cont)
1739                 {
1740                         base.RemoveContainer (cont);
1741                         Members.Remove (cont);
1742                         Cache.Remove (cont.Basename);
1743                 }
1744
1745                 protected virtual bool DoResolveTypeParameters ()
1746                 {
1747                         var tparams = CurrentTypeParameters;
1748                         if (tparams == null)
1749                                 return true;
1750
1751                         var base_context = new BaseContext (this);
1752                         for (int i = 0; i < tparams.Count; ++i) {
1753                                 var tp = tparams[i];
1754
1755                                 if (!tp.ResolveConstraints (base_context)) {
1756                                         error = true;
1757                                         return false;
1758                                 }
1759                         }
1760
1761                         if (IsPartialPart) {
1762                                 PartialContainer.CurrentTypeParameters.UpdateConstraints (this);
1763                         }
1764
1765                         return true;
1766                 }
1767
1768                 TypeSpec CheckRecursiveDefinition (TypeDefinition tc)
1769                 {
1770                         if (InTransit != null)
1771                                 return spec;
1772
1773                         InTransit = tc;
1774
1775                         if (base_type != null) {
1776                                 var ptc = base_type.MemberDefinition as TypeDefinition;
1777                                 if (ptc != null && ptc.CheckRecursiveDefinition (this) != null)
1778                                         return base_type;
1779                         }
1780
1781                         if (iface_exprs != null) {
1782                                 foreach (var iface in iface_exprs) {
1783                                         // the interface might not have been resolved, prevents a crash, see #442144
1784                                         if (iface == null)
1785                                                 continue;
1786                                         var ptc = iface.MemberDefinition as Interface;
1787                                         if (ptc != null && ptc.CheckRecursiveDefinition (this) != null)
1788                                                 return iface;
1789                                 }
1790                         }
1791
1792                         if (!IsTopLevel && Parent.PartialContainer.CheckRecursiveDefinition (this) != null)
1793                                 return spec;
1794
1795                         InTransit = null;
1796                         return null;
1797                 }
1798
1799                 /// <summary>
1800                 ///   Populates our TypeBuilder with fields and methods
1801                 /// </summary>
1802                 public sealed override bool Define ()
1803                 {
1804                         if (members_defined)
1805                                 return members_defined_ok;
1806
1807                         members_defined_ok = DoDefineMembers ();
1808                         members_defined = true;
1809
1810                         base.Define ();
1811
1812                         return members_defined_ok;
1813                 }
1814
1815                 protected virtual bool DoDefineMembers ()
1816                 {
1817                         Debug.Assert (!IsPartialPart);
1818
1819                         if (iface_exprs != null) {
1820                                 foreach (var iface_type in iface_exprs) {
1821                                         if (iface_type == null)
1822                                                 continue;
1823
1824                                         // Ensure the base is always setup
1825                                         var compiled_iface = iface_type.MemberDefinition as Interface;
1826                                         if (compiled_iface != null)
1827                                                 compiled_iface.Define ();
1828
1829                                         ObsoleteAttribute oa = iface_type.GetAttributeObsolete ();
1830                                         if (oa != null && !IsObsolete)
1831                                                 AttributeTester.Report_ObsoleteMessage (oa, iface_type.GetSignatureForError (), Location, Report);
1832
1833                                         if (iface_type.Arity > 0) {
1834                                                 // TODO: passing `this' is wrong, should be base type iface instead
1835                                                 VarianceDecl.CheckTypeVariance (iface_type, Variance.Covariant, this);
1836
1837                                                 if (((InflatedTypeSpec) iface_type).HasDynamicArgument () && !IsCompilerGenerated) {
1838                                                         Report.Error (1966, Location,
1839                                                                 "`{0}': cannot implement a dynamic interface `{1}'",
1840                                                                 GetSignatureForError (), iface_type.GetSignatureForError ());
1841                                                         return false;
1842                                                 }
1843                                         }
1844
1845                                         if (iface_type.IsGenericOrParentIsGeneric) {
1846                                                 foreach (var prev_iface in iface_exprs) {
1847                                                         if (prev_iface == iface_type || prev_iface == null)
1848                                                                 break;
1849
1850                                                         if (!TypeSpecComparer.Unify.IsEqual (iface_type, prev_iface))
1851                                                                 continue;
1852
1853                                                         Report.Error (695, Location,
1854                                                                 "`{0}' cannot implement both `{1}' and `{2}' because they may unify for some type parameter substitutions",
1855                                                                 GetSignatureForError (), prev_iface.GetSignatureForError (), iface_type.GetSignatureForError ());
1856                                                 }
1857                                         }
1858                                 }
1859
1860                                 if (Kind == MemberKind.Interface) {
1861                                         foreach (var iface in spec.Interfaces) {
1862                                                 MemberCache.AddInterface (iface);
1863                                         }
1864                                 }
1865                         }
1866
1867                         if (base_type != null) {
1868                                 //
1869                                 // Run checks skipped during DefineType (e.g FullNamedExpression::ResolveAsType)
1870                                 //
1871                                 if (base_type_expr != null) {
1872                                         ObsoleteAttribute obsolete_attr = base_type.GetAttributeObsolete ();
1873                                         if (obsolete_attr != null && !IsObsolete)
1874                                                 AttributeTester.Report_ObsoleteMessage (obsolete_attr, base_type.GetSignatureForError (), base_type_expr.Location, Report);
1875
1876                                         if (IsGenericOrParentIsGeneric && base_type.IsAttribute) {
1877                                                 Report.Error (698, base_type_expr.Location,
1878                                                         "A generic type cannot derive from `{0}' because it is an attribute class",
1879                                                         base_type.GetSignatureForError ());
1880                                         }
1881                                 }
1882
1883                                 var baseContainer = base_type.MemberDefinition as ClassOrStruct;
1884                                 if (baseContainer != null) {
1885                                         baseContainer.Define ();
1886
1887                                         //
1888                                         // It can trigger define of this type (for generic types only)
1889                                         //
1890                                         if (HasMembersDefined)
1891                                                 return true;
1892                                 }
1893                         }
1894
1895                         if (Kind == MemberKind.Struct || Kind == MemberKind.Class) {
1896                                 pending = PendingImplementation.GetPendingImplementations (this);
1897                         }
1898
1899                         var count = members.Count;              
1900                         for (int i = 0; i < count; ++i) {
1901                                 var mc = members[i] as InterfaceMemberBase;
1902                                 if (mc == null || !mc.IsExplicitImpl)
1903                                         continue;
1904
1905                                 try {
1906                                         mc.Define ();
1907                                 } catch (Exception e) {
1908                                         throw new InternalErrorException (mc, e);
1909                                 }
1910                         }
1911
1912                         for (int i = 0; i < count; ++i) {
1913                                 var mc = members[i] as InterfaceMemberBase;
1914                                 if (mc != null && mc.IsExplicitImpl)
1915                                         continue;
1916
1917                                 if (members[i] is TypeContainer)
1918                                         continue;
1919
1920                                 try {
1921                                         members[i].Define ();
1922                                 } catch (Exception e) {
1923                                         throw new InternalErrorException (members[i], e);
1924                                 }
1925                         }
1926
1927                         if (HasOperators) {
1928                                 CheckPairedOperators ();
1929                         }
1930
1931                         if (requires_delayed_unmanagedtype_check) {
1932                                 requires_delayed_unmanagedtype_check = false;
1933                                 foreach (var member in members) {
1934                                         var f = member as Field;
1935                                         if (f != null && f.MemberType != null && f.MemberType.IsPointer)
1936                                                 TypeManager.VerifyUnmanaged (Module, f.MemberType, f.Location);
1937                                 }
1938                         }
1939
1940                         ComputeIndexerName();
1941
1942                         if (HasEquals && !HasGetHashCode) {
1943                                 Report.Warning (659, 3, Location,
1944                                         "`{0}' overrides Object.Equals(object) but does not override Object.GetHashCode()", GetSignatureForError ());
1945                         }
1946
1947                         if (Kind == MemberKind.Interface && iface_exprs != null) {
1948                                 MemberCache.RemoveHiddenMembers (spec);
1949                         }
1950
1951                         return true;
1952                 }
1953
1954                 void ComputeIndexerName ()
1955                 {
1956                         var indexers = MemberCache.FindMembers (spec, MemberCache.IndexerNameAlias, true);
1957                         if (indexers == null)
1958                                 return;
1959
1960                         string class_indexer_name = null;
1961
1962                         //
1963                         // Check normal indexers for consistent name, explicit interface implementation
1964                         // indexers are ignored
1965                         //
1966                         foreach (var indexer in indexers) {
1967                                 //
1968                                 // FindMembers can return unfiltered full hierarchy names
1969                                 //
1970                                 if (indexer.DeclaringType != spec)
1971                                         continue;
1972
1973                                 has_normal_indexers = true;
1974
1975                                 if (class_indexer_name == null) {
1976                                         indexer_name = class_indexer_name = indexer.Name;
1977                                         continue;
1978                                 }
1979
1980                                 if (indexer.Name != class_indexer_name)
1981                                         Report.Error (668, ((Indexer)indexer.MemberDefinition).Location,
1982                                                 "Two indexers have different names; the IndexerName attribute must be used with the same name on every indexer within a type");
1983                         }
1984                 }
1985
1986                 void EmitIndexerName ()
1987                 {
1988                         if (!has_normal_indexers)
1989                                 return;
1990
1991                         var ctor = Module.PredefinedMembers.DefaultMemberAttributeCtor.Get ();
1992                         if (ctor == null)
1993                                 return;
1994
1995                         var encoder = new AttributeEncoder ();
1996                         encoder.Encode (GetAttributeDefaultMember ());
1997                         encoder.EncodeEmptyNamedArguments ();
1998
1999                         TypeBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray ());
2000                 }
2001
2002                 public override void VerifyMembers ()
2003                 {
2004                         //
2005                         // Check for internal or private fields that were never assigned
2006                         //
2007                         if (!IsCompilerGenerated && Compiler.Settings.WarningLevel >= 3 && this == PartialContainer) {
2008                                 bool is_type_exposed = Kind == MemberKind.Struct || IsExposedFromAssembly ();
2009                                 foreach (var member in members) {
2010                                         if (member is Event) {
2011                                                 //
2012                                                 // An event can be assigned from same class only, so we can report
2013                                                 // this warning for all accessibility modes
2014                                                 //
2015                                                 if (!member.IsUsed)
2016                                                         Report.Warning (67, 3, member.Location, "The event `{0}' is never used", member.GetSignatureForError ());
2017
2018                                                 continue;
2019                                         }
2020
2021                                         if ((member.ModFlags & Modifiers.AccessibilityMask) != Modifiers.PRIVATE) {
2022                                                 if (is_type_exposed)
2023                                                         continue;
2024
2025                                                 member.SetIsUsed ();
2026                                         }
2027
2028                                         var f = member as Field;
2029                                         if (f == null)
2030                                                 continue;
2031
2032                                         if (!member.IsUsed) {
2033                                                 if ((member.caching_flags & Flags.IsAssigned) == 0) {
2034                                                         Report.Warning (169, 3, member.Location, "The private field `{0}' is never used", member.GetSignatureForError ());
2035                                                 } else {
2036                                                         Report.Warning (414, 3, member.Location, "The private field `{0}' is assigned but its value is never used",
2037                                                                 member.GetSignatureForError ());
2038                                                 }
2039                                                 continue;
2040                                         }
2041
2042                                         if ((f.caching_flags & Flags.IsAssigned) != 0)
2043                                                 continue;
2044
2045                                         //
2046                                         // Only report 649 on level 4
2047                                         //
2048                                         if (Compiler.Settings.WarningLevel < 4)
2049                                                 continue;
2050
2051                                         //
2052                                         // Don't be pedantic when type requires specific layout
2053                                         //
2054                                         if (f.OptAttributes != null || PartialContainer.HasStructLayout)
2055                                                 continue;
2056
2057                                         Constant c = New.Constantify (f.MemberType, f.Location);
2058                                         string value;
2059                                         if (c != null) {
2060                                                 value = c.GetValueAsLiteral ();
2061                                         } else if (TypeSpec.IsReferenceType (f.MemberType)) {
2062                                                 value = "null";
2063                                         } else {
2064                                                 value = null;
2065                                         }
2066
2067                                         if (value != null)
2068                                                 value = " `" + value + "'";
2069
2070                                         Report.Warning (649, 4, f.Location, "Field `{0}' is never assigned to, and will always have its default value{1}",
2071                                                 f.GetSignatureForError (), value);
2072                                 }
2073                         }
2074
2075                         base.VerifyMembers ();
2076                 }
2077
2078                 public override void Emit ()
2079                 {
2080                         if (OptAttributes != null)
2081                                 OptAttributes.Emit ();
2082
2083                         if (!IsCompilerGenerated) {
2084                                 if (!IsTopLevel) {
2085                                         MemberSpec candidate;
2086                                         bool overrides = false;
2087                                         var conflict_symbol = MemberCache.FindBaseMember (this, out candidate, ref overrides);
2088                                         if (conflict_symbol == null && candidate == null) {
2089                                                 if ((ModFlags & Modifiers.NEW) != 0)
2090                                                         Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required",
2091                                                                 GetSignatureForError ());
2092                                         } else {
2093                                                 if ((ModFlags & Modifiers.NEW) == 0) {
2094                                                         if (candidate == null)
2095                                                                 candidate = conflict_symbol;
2096
2097                                                         Report.SymbolRelatedToPreviousError (candidate);
2098                                                         Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
2099                                                                 GetSignatureForError (), candidate.GetSignatureForError ());
2100                                                 }
2101                                         }
2102                                 }
2103
2104                                 // Run constraints check on all possible generic types
2105                                 if (base_type != null && base_type_expr != null) {
2106                                         ConstraintChecker.Check (this, base_type, base_type_expr.Location);
2107                                 }
2108
2109                                 if (iface_exprs != null) {
2110                                         foreach (var iface_type in iface_exprs) {
2111                                                 if (iface_type == null)
2112                                                         continue;
2113
2114                                                 ConstraintChecker.Check (this, iface_type, Location);   // TODO: Location is wrong
2115                                         }
2116                                 }
2117                         }
2118
2119                         if (all_tp_builders != null) {
2120                                 int current_starts_index = CurrentTypeParametersStartIndex;
2121                                 for (int i = 0; i < all_tp_builders.Length; i++) {
2122                                         if (i < current_starts_index) {
2123                                                 all_type_parameters[i].EmitConstraints (all_tp_builders [i]);
2124                                         } else {
2125                                                 var tp = CurrentTypeParameters [i - current_starts_index];
2126                                                 tp.CheckGenericConstraints (!IsObsolete);
2127                                                 tp.Emit ();
2128                                         }
2129                                 }
2130                         }
2131
2132                         if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0 && !Parent.IsCompilerGenerated)
2133                                 Module.PredefinedAttributes.CompilerGenerated.EmitAttribute (TypeBuilder);
2134
2135 #if STATIC
2136                         if ((TypeBuilder.Attributes & TypeAttributes.StringFormatMask) == 0 && Module.HasDefaultCharSet)
2137                                 TypeBuilder.__SetAttributes (TypeBuilder.Attributes | Module.DefaultCharSetType);
2138 #endif
2139
2140                         base.Emit ();
2141
2142                         for (int i = 0; i < members.Count; i++) {
2143                                 var m = members[i];
2144                                 if ((m.caching_flags & Flags.CloseTypeCreated) != 0)
2145                                         continue;
2146
2147                                 m.Emit ();
2148                         }
2149
2150                         EmitIndexerName ();
2151                         CheckAttributeClsCompliance ();
2152
2153                         if (pending != null)
2154                                 pending.VerifyPendingMethods ();
2155                 }
2156
2157
2158                 void CheckAttributeClsCompliance ()
2159                 {
2160                         if (!spec.IsAttribute || !IsExposedFromAssembly () || !Compiler.Settings.VerifyClsCompliance || !IsClsComplianceRequired ())
2161                                 return;
2162
2163                         foreach (var m in members) {
2164                                 var c = m as Constructor;
2165                                 if (c == null)
2166                                         continue;
2167
2168                                 if (c.HasCompliantArgs)
2169                                         return;
2170                         }
2171
2172                         Report.Warning (3015, 1, Location, "`{0}' has no accessible constructors which use only CLS-compliant types", GetSignatureForError ());
2173                 }
2174
2175                 public sealed override void EmitContainer ()
2176                 {
2177                         if ((caching_flags & Flags.CloseTypeCreated) != 0)
2178                                 return;
2179
2180                         Emit ();
2181                 }
2182
2183                 public override void CloseContainer ()
2184                 {
2185                         if ((caching_flags & Flags.CloseTypeCreated) != 0)
2186                                 return;
2187
2188                         // Close base type container first to avoid TypeLoadException
2189                         if (spec.BaseType != null) {
2190                                 var btype = spec.BaseType.MemberDefinition as TypeContainer;
2191                                 if (btype != null) {
2192                                         btype.CloseContainer ();
2193
2194                                         if ((caching_flags & Flags.CloseTypeCreated) != 0)
2195                                                 return;
2196                                 }
2197                         }
2198
2199                         try {
2200                                 caching_flags |= Flags.CloseTypeCreated;
2201                                 TypeBuilder.CreateType ();
2202                         } catch (TypeLoadException) {
2203                                 //
2204                                 // This is fine, the code still created the type
2205                                 //
2206                         } catch (Exception e) {
2207                                 throw new InternalErrorException (this, e);
2208                         }
2209
2210                         base.CloseContainer ();
2211                         
2212                         containers = null;
2213                         initialized_fields = null;
2214                         initialized_static_fields = null;
2215                         type_bases = null;
2216                         OptAttributes = null;
2217                 }
2218
2219                 //
2220                 // Performs the validation on a Method's modifiers (properties have
2221                 // the same properties).
2222                 //
2223                 // TODO: Why is it not done at parse stage, move to Modifiers::Check
2224                 //
2225                 public bool MethodModifiersValid (MemberCore mc)
2226                 {
2227                         const Modifiers vao = (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE);
2228                         const Modifiers nv = (Modifiers.NEW | Modifiers.VIRTUAL);
2229                         bool ok = true;
2230                         var flags = mc.ModFlags;
2231                         
2232                         //
2233                         // At most one of static, virtual or override
2234                         //
2235                         if ((flags & Modifiers.STATIC) != 0){
2236                                 if ((flags & vao) != 0){
2237                                         Report.Error (112, mc.Location, "A static member `{0}' cannot be marked as override, virtual or abstract",
2238                                                 mc.GetSignatureForError ());
2239                                         ok = false;
2240                                 }
2241                         }
2242
2243                         if ((flags & Modifiers.OVERRIDE) != 0 && (flags & nv) != 0){
2244                                 Report.Error (113, mc.Location, "A member `{0}' marked as override cannot be marked as new or virtual",
2245                                         mc.GetSignatureForError ());
2246                                 ok = false;
2247                         }
2248
2249                         //
2250                         // If the declaration includes the abstract modifier, then the
2251                         // declaration does not include static, virtual or extern
2252                         //
2253                         if ((flags & Modifiers.ABSTRACT) != 0){
2254                                 if ((flags & Modifiers.EXTERN) != 0){
2255                                         Report.Error (
2256                                                 180, mc.Location, "`{0}' cannot be both extern and abstract", mc.GetSignatureForError ());
2257                                         ok = false;
2258                                 }
2259
2260                                 if ((flags & Modifiers.SEALED) != 0) {
2261                                         Report.Error (502, mc.Location, "`{0}' cannot be both abstract and sealed", mc.GetSignatureForError ());
2262                                         ok = false;
2263                                 }
2264
2265                                 if ((flags & Modifiers.VIRTUAL) != 0){
2266                                         Report.Error (503, mc.Location, "The abstract method `{0}' cannot be marked virtual", mc.GetSignatureForError ());
2267                                         ok = false;
2268                                 }
2269
2270                                 if ((ModFlags & Modifiers.ABSTRACT) == 0){
2271                                         Report.SymbolRelatedToPreviousError (this);
2272                                         Report.Error (513, mc.Location, "`{0}' is abstract but it is declared in the non-abstract class `{1}'",
2273                                                 mc.GetSignatureForError (), GetSignatureForError ());
2274                                         ok = false;
2275                                 }
2276                         }
2277
2278                         if ((flags & Modifiers.PRIVATE) != 0){
2279                                 if ((flags & vao) != 0){
2280                                         Report.Error (621, mc.Location, "`{0}': virtual or abstract members cannot be private", mc.GetSignatureForError ());
2281                                         ok = false;
2282                                 }
2283                         }
2284
2285                         if ((flags & Modifiers.SEALED) != 0){
2286                                 if ((flags & Modifiers.OVERRIDE) == 0){
2287                                         Report.Error (238, mc.Location, "`{0}' cannot be sealed because it is not an override", mc.GetSignatureForError ());
2288                                         ok = false;
2289                                 }
2290                         }
2291
2292                         return ok;
2293                 }
2294
2295                 protected override bool VerifyClsCompliance ()
2296                 {
2297                         if (!base.VerifyClsCompliance ())
2298                                 return false;
2299
2300                         // Check all container names for user classes
2301                         if (Kind != MemberKind.Delegate)
2302                                 MemberCache.VerifyClsCompliance (Definition, Report);
2303
2304                         if (BaseType != null && !BaseType.IsCLSCompliant ()) {
2305                                 Report.Warning (3009, 1, Location, "`{0}': base type `{1}' is not CLS-compliant",
2306                                         GetSignatureForError (), BaseType.GetSignatureForError ());
2307                         }
2308                         return true;
2309                 }
2310
2311                 /// <summary>
2312                 ///   Performs checks for an explicit interface implementation.  First it
2313                 ///   checks whether the `interface_type' is a base inteface implementation.
2314                 ///   Then it checks whether `name' exists in the interface type.
2315                 /// </summary>
2316                 public bool VerifyImplements (InterfaceMemberBase mb)
2317                 {
2318                         var ifaces = PartialContainer.Interfaces;
2319                         if (ifaces != null) {
2320                                 foreach (TypeSpec t in ifaces){
2321                                         if (t == mb.InterfaceType)
2322                                                 return true;
2323
2324                                         var expanded_base = t.Interfaces;
2325                                         if (expanded_base == null)
2326                                                 continue;
2327
2328                                         foreach (var bt in expanded_base) {
2329                                                 if (bt == mb.InterfaceType)
2330                                                         return true;
2331                                         }
2332                                 }
2333                         }
2334                         
2335                         Report.SymbolRelatedToPreviousError (mb.InterfaceType);
2336                         Report.Error (540, mb.Location, "`{0}': containing type does not implement interface `{1}'",
2337                                 mb.GetSignatureForError (), mb.InterfaceType.GetSignatureForError ());
2338                         return false;
2339                 }
2340
2341                 //
2342                 // Used for visiblity checks to tests whether this definition shares
2343                 // base type baseType, it does member-definition search
2344                 //
2345                 public bool IsBaseTypeDefinition (TypeSpec baseType)
2346                 {
2347                         // RootContext check
2348                         if (TypeBuilder == null)
2349                                 return false;
2350
2351                         var type = spec;
2352                         do {
2353                                 if (type.MemberDefinition == baseType.MemberDefinition)
2354                                         return true;
2355
2356                                 type = type.BaseType;
2357                         } while (type != null);
2358
2359                         return false;
2360                 }
2361
2362                 public override bool IsClsComplianceRequired ()
2363                 {
2364                         if (IsPartialPart)
2365                                 return PartialContainer.IsClsComplianceRequired ();
2366
2367                         return base.IsClsComplianceRequired ();
2368                 }
2369
2370                 bool ITypeDefinition.IsInternalAsPublic (IAssemblyDefinition assembly)
2371                 {
2372                         return Module.DeclaringAssembly == assembly;
2373                 }
2374
2375                 public virtual bool IsUnmanagedType ()
2376                 {
2377                         return false;
2378                 }
2379
2380                 public void LoadMembers (TypeSpec declaringType, bool onlyTypes, ref MemberCache cache)
2381                 {
2382                         throw new NotSupportedException ("Not supported for compiled definition " + GetSignatureForError ());
2383                 }
2384
2385                 //
2386                 // Public function used to locate types.
2387                 //
2388                 // Returns: Type or null if they type can not be found.
2389                 //
2390                 public override FullNamedExpression LookupNamespaceOrType (string name, int arity, LookupMode mode, Location loc)
2391                 {
2392                         FullNamedExpression e;
2393                         if (arity == 0 && Cache.TryGetValue (name, out e) && mode != LookupMode.IgnoreAccessibility)
2394                                 return e;
2395
2396                         e = null;
2397
2398                         if (arity == 0) {
2399                                 var tp = CurrentTypeParameters;
2400                                 if (tp != null) {
2401                                         TypeParameter tparam = tp.Find (name);
2402                                         if (tparam != null)
2403                                                 e = new TypeParameterExpr (tparam, Location.Null);
2404                                 }
2405                         }
2406
2407                         if (e == null) {
2408                                 TypeSpec t = LookupNestedTypeInHierarchy (name, arity);
2409
2410                                 if (t != null && (t.IsAccessible (this) || mode == LookupMode.IgnoreAccessibility))
2411                                         e = new TypeExpression (t, Location.Null);
2412                                 else {
2413                                         var errors = Compiler.Report.Errors;
2414                                         e = Parent.LookupNamespaceOrType (name, arity, mode, loc);
2415
2416                                         // TODO: LookupNamespaceOrType does more than just lookup. The result
2417                                         // cannot be cached or the error reporting won't happen
2418                                         if (errors != Compiler.Report.Errors)
2419                                                 return e;
2420                                 }
2421                         }
2422
2423                         // TODO MemberCache: How to cache arity stuff ?
2424                         if (arity == 0 && mode == LookupMode.Normal)
2425                                 Cache[name] = e;
2426
2427                         return e;
2428                 }
2429
2430                 TypeSpec LookupNestedTypeInHierarchy (string name, int arity)
2431                 {
2432                         // Has any nested type
2433                         // Does not work, because base type can have
2434                         //if (PartialContainer.Types == null)
2435                         //      return null;
2436
2437                         var container = PartialContainer.CurrentType;
2438                         return MemberCache.FindNestedType (container, name, arity);
2439                 }
2440
2441                 public void Mark_HasEquals ()
2442                 {
2443                         cached_method |= CachedMethods.Equals;
2444                 }
2445
2446                 public void Mark_HasGetHashCode ()
2447                 {
2448                         cached_method |= CachedMethods.GetHashCode;
2449                 }
2450
2451                 public override void WriteDebugSymbol (MonoSymbolFile file)
2452                 {
2453                         if (IsPartialPart)
2454                                 return;
2455
2456                         foreach (var m in members) {
2457                                 m.WriteDebugSymbol (file);
2458                         }
2459                 }
2460
2461                 /// <summary>
2462                 /// Method container contains Equals method
2463                 /// </summary>
2464                 public bool HasEquals {
2465                         get {
2466                                 return (cached_method & CachedMethods.Equals) != 0;
2467                         }
2468                 }
2469  
2470                 /// <summary>
2471                 /// Method container contains GetHashCode method
2472                 /// </summary>
2473                 public bool HasGetHashCode {
2474                         get {
2475                                 return (cached_method & CachedMethods.GetHashCode) != 0;
2476                         }
2477                 }
2478
2479                 public bool HasStaticFieldInitializer {
2480                         get {
2481                                 return (cached_method & CachedMethods.HasStaticFieldInitializer) != 0;
2482                         }
2483                         set {
2484                                 if (value)
2485                                         cached_method |= CachedMethods.HasStaticFieldInitializer;
2486                                 else
2487                                         cached_method &= ~CachedMethods.HasStaticFieldInitializer;
2488                         }
2489                 }
2490
2491                 public override string DocCommentHeader {
2492                         get { return "T:"; }
2493                 }
2494         }
2495
2496         public abstract class ClassOrStruct : TypeDefinition
2497         {
2498                 public const TypeAttributes StaticClassAttribute = TypeAttributes.Abstract | TypeAttributes.Sealed;
2499
2500                 SecurityType declarative_security;
2501
2502                 protected ClassOrStruct (TypeContainer parent, MemberName name, Attributes attrs, MemberKind kind)
2503                         : base (parent, name, attrs, kind)
2504                 {
2505                 }
2506
2507                 protected override TypeAttributes TypeAttr {
2508                         get {
2509                                 TypeAttributes ta = base.TypeAttr;
2510                                 if (!has_static_constructor)
2511                                         ta |= TypeAttributes.BeforeFieldInit;
2512
2513                                 if (Kind == MemberKind.Class) {
2514                                         ta |= TypeAttributes.AutoLayout | TypeAttributes.Class;
2515                                         if (IsStatic)
2516                                                 ta |= StaticClassAttribute;
2517                                 } else {
2518                                         ta |= TypeAttributes.SequentialLayout;
2519                                 }
2520
2521                                 return ta;
2522                         }
2523                 }
2524
2525                 public override void AddNameToContainer (MemberCore symbol, string name)
2526                 {
2527                         if (!(symbol is Constructor) && symbol.MemberName.Name == MemberName.Name) {
2528                                 if (symbol is TypeParameter) {
2529                                         Report.Error (694, symbol.Location,
2530                                                 "Type parameter `{0}' has same name as containing type, or method",
2531                                                 symbol.GetSignatureForError ());
2532                                         return;
2533                                 }
2534                         
2535                                 InterfaceMemberBase imb = symbol as InterfaceMemberBase;
2536                                 if (imb == null || !imb.IsExplicitImpl) {
2537                                         Report.SymbolRelatedToPreviousError (this);
2538                                         Report.Error (542, symbol.Location, "`{0}': member names cannot be the same as their enclosing type",
2539                                                 symbol.GetSignatureForError ());
2540                                         return;
2541                                 }
2542                         }
2543
2544                         base.AddNameToContainer (symbol, name);
2545                 }
2546
2547                 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
2548                 {
2549                         if (a.IsValidSecurityAttribute ()) {
2550                                 a.ExtractSecurityPermissionSet (ctor, ref declarative_security);
2551                                 return;
2552                         }
2553
2554                         if (a.Type == pa.StructLayout) {
2555                                 PartialContainer.HasStructLayout = true;
2556                                 if (a.IsExplicitLayoutKind ())
2557                                         PartialContainer.HasExplicitLayout = true;
2558                         }
2559
2560                         if (a.Type == pa.Dynamic) {
2561                                 a.Error_MisusedDynamicAttribute ();
2562                                 return;
2563                         }
2564
2565                         base.ApplyAttributeBuilder (a, ctor, cdata, pa);
2566                 }
2567
2568                 /// <summary>
2569                 /// Defines the default constructors 
2570                 /// </summary>
2571                 protected virtual Constructor DefineDefaultConstructor (bool is_static)
2572                 {
2573                         // The default instance constructor is public
2574                         // If the class is abstract, the default constructor is protected
2575                         // The default static constructor is private
2576
2577                         Modifiers mods;
2578                         if (is_static) {
2579                                 mods = Modifiers.STATIC | Modifiers.PRIVATE;
2580                         } else {
2581                                 mods = ((ModFlags & Modifiers.ABSTRACT) != 0) ? Modifiers.PROTECTED : Modifiers.PUBLIC;
2582                         }
2583
2584                         var c = new Constructor (this, MemberName.Name, mods, null, ParametersCompiled.EmptyReadOnlyParameters, Location);
2585                         c.Initializer = new GeneratedBaseInitializer (Location);
2586                         
2587                         AddConstructor (c, true);
2588                         c.Block = new ToplevelBlock (Compiler, ParametersCompiled.EmptyReadOnlyParameters, Location) {
2589                                 IsCompilerGenerated = true
2590                         };
2591
2592                         return c;
2593                 }
2594
2595                 protected override bool DoDefineMembers ()
2596                 {
2597                         CheckProtectedModifier ();
2598
2599                         base.DoDefineMembers ();
2600
2601                         return true;
2602                 }
2603
2604                 public override void Emit ()
2605                 {
2606                         if (!has_static_constructor && HasStaticFieldInitializer) {
2607                                 var c = DefineDefaultConstructor (true);
2608                                 c.Define ();
2609                         }
2610
2611                         base.Emit ();
2612
2613                         if (declarative_security != null) {
2614                                 foreach (var de in declarative_security) {
2615 #if STATIC
2616                                         TypeBuilder.__AddDeclarativeSecurity (de);
2617 #else
2618                                         TypeBuilder.AddDeclarativeSecurity (de.Key, de.Value);
2619 #endif
2620                                 }
2621                         }
2622                 }
2623         }
2624
2625
2626         public sealed class Class : ClassOrStruct
2627         {
2628                 const Modifiers AllowedModifiers =
2629                         Modifiers.NEW |
2630                         Modifiers.PUBLIC |
2631                         Modifiers.PROTECTED |
2632                         Modifiers.INTERNAL |
2633                         Modifiers.PRIVATE |
2634                         Modifiers.ABSTRACT |
2635                         Modifiers.SEALED |
2636                         Modifiers.STATIC |
2637                         Modifiers.UNSAFE;
2638
2639                 public Class (TypeContainer parent, MemberName name, Modifiers mod, Attributes attrs)
2640                         : base (parent, name, attrs, MemberKind.Class)
2641                 {
2642                         var accmods = IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE;
2643                         this.ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, accmods, Location, Report);
2644                         spec = new TypeSpec (Kind, null, this, null, ModFlags);
2645                 }
2646
2647                 public override void Accept (StructuralVisitor visitor)
2648                 {
2649                         visitor.Visit (this);
2650                 }
2651
2652                 public override void SetBaseTypes (List<FullNamedExpression> baseTypes)
2653                 {
2654                         var pmn = MemberName;
2655                         if (pmn.Name == "Object" && !pmn.IsGeneric && Parent.MemberName.Name == "System" && Parent.MemberName.Left == null)
2656                                 Report.Error (537, Location,
2657                                         "The class System.Object cannot have a base class or implement an interface.");
2658
2659                         base.SetBaseTypes (baseTypes);
2660                 }
2661
2662                 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
2663                 {
2664                         if (a.Type == pa.AttributeUsage) {
2665                                 if (!BaseType.IsAttribute && spec.BuiltinType != BuiltinTypeSpec.Type.Attribute) {
2666                                         Report.Error (641, a.Location, "Attribute `{0}' is only valid on classes derived from System.Attribute", a.GetSignatureForError ());
2667                                 }
2668                         }
2669
2670                         if (a.Type == pa.Conditional && !BaseType.IsAttribute) {
2671                                 Report.Error (1689, a.Location, "Attribute `System.Diagnostics.ConditionalAttribute' is only valid on methods or attribute classes");
2672                                 return;
2673                         }
2674
2675                         if (a.Type == pa.ComImport && !attributes.Contains (pa.Guid)) {
2676                                 a.Error_MissingGuidAttribute ();
2677                                 return;
2678                         }
2679
2680                         if (a.Type == pa.Extension) {
2681                                 a.Error_MisusedExtensionAttribute ();
2682                                 return;
2683                         }
2684
2685                         if (a.Type.IsConditionallyExcluded (this))
2686                                 return;
2687
2688                         base.ApplyAttributeBuilder (a, ctor, cdata, pa);
2689                 }
2690
2691                 public override AttributeTargets AttributeTargets {
2692                         get {
2693                                 return AttributeTargets.Class;
2694                         }
2695                 }
2696
2697                 protected override bool DoDefineMembers ()
2698                 {
2699                         if ((ModFlags & Modifiers.ABSTRACT) == Modifiers.ABSTRACT && (ModFlags & (Modifiers.SEALED | Modifiers.STATIC)) != 0) {
2700                                 Report.Error (418, Location, "`{0}': an abstract class cannot be sealed or static", GetSignatureForError ());
2701                         }
2702
2703                         if ((ModFlags & (Modifiers.SEALED | Modifiers.STATIC)) == (Modifiers.SEALED | Modifiers.STATIC)) {
2704                                 Report.Error (441, Location, "`{0}': a class cannot be both static and sealed", GetSignatureForError ());
2705                         }
2706
2707                         if (IsStatic) {
2708                                 foreach (var m in Members) {
2709                                         if (m is Operator) {
2710                                                 Report.Error (715, m.Location, "`{0}': Static classes cannot contain user-defined operators", m.GetSignatureForError ());
2711                                                 continue;
2712                                         }
2713
2714                                         if (m is Destructor) {
2715                                                 Report.Error (711, m.Location, "`{0}': Static classes cannot contain destructor", GetSignatureForError ());
2716                                                 continue;
2717                                         }
2718
2719                                         if (m is Indexer) {
2720                                                 Report.Error (720, m.Location, "`{0}': cannot declare indexers in a static class", m.GetSignatureForError ());
2721                                                 continue;
2722                                         }
2723
2724                                         if ((m.ModFlags & Modifiers.STATIC) != 0 || m is TypeContainer)
2725                                                 continue;
2726
2727                                         if (m is Constructor) {
2728                                                 Report.Error (710, m.Location, "`{0}': Static classes cannot have instance constructors", GetSignatureForError ());
2729                                                 continue;
2730                                         }
2731
2732                                         Report.Error (708, m.Location, "`{0}': cannot declare instance members in a static class", m.GetSignatureForError ());
2733                                 }
2734                         } else {
2735                                 if (!PartialContainer.HasInstanceConstructor)
2736                                         DefineDefaultConstructor (false);
2737                         }
2738
2739                         return base.DoDefineMembers ();
2740                 }
2741
2742                 public override void Emit ()
2743                 {
2744                         base.Emit ();
2745
2746                         if ((ModFlags & Modifiers.METHOD_EXTENSION) != 0)
2747                                 Module.PredefinedAttributes.Extension.EmitAttribute (TypeBuilder);
2748
2749                         if (base_type != null && base_type.HasDynamicElement) {
2750                                 Module.PredefinedAttributes.Dynamic.EmitAttribute (TypeBuilder, base_type, Location);
2751                         }
2752                 }
2753
2754                 protected override TypeSpec[] ResolveBaseTypes (out FullNamedExpression base_class)
2755                 {
2756                         var ifaces = base.ResolveBaseTypes (out base_class);
2757
2758                         if (base_class == null) {
2759                                 if (spec.BuiltinType != BuiltinTypeSpec.Type.Object)
2760                                         base_type = Compiler.BuiltinTypes.Object;
2761                         } else {
2762                                 if (base_type.IsGenericParameter){
2763                                         Report.Error (689, base_class.Location, "`{0}': Cannot derive from type parameter `{1}'",
2764                                                 GetSignatureForError (), base_type.GetSignatureForError ());
2765                                 } else if (base_type.IsStatic) {
2766                                         Report.SymbolRelatedToPreviousError (base_type);
2767                                         Report.Error (709, Location, "`{0}': Cannot derive from static class `{1}'",
2768                                                 GetSignatureForError (), base_type.GetSignatureForError ());
2769                                 } else if (base_type.IsSealed) {
2770                                         Report.SymbolRelatedToPreviousError (base_type);
2771                                         Report.Error (509, Location, "`{0}': cannot derive from sealed type `{1}'",
2772                                                 GetSignatureForError (), base_type.GetSignatureForError ());
2773                                 } else if (PartialContainer.IsStatic && base_type.BuiltinType != BuiltinTypeSpec.Type.Object) {
2774                                         Report.Error (713, Location, "Static class `{0}' cannot derive from type `{1}'. Static classes must derive from object",
2775                                                 GetSignatureForError (), base_type.GetSignatureForError ());
2776                                 }
2777
2778                                 switch (base_type.BuiltinType) {
2779                                 case BuiltinTypeSpec.Type.Enum:
2780                                 case BuiltinTypeSpec.Type.ValueType:
2781                                 case BuiltinTypeSpec.Type.MulticastDelegate:
2782                                 case BuiltinTypeSpec.Type.Delegate:
2783                                 case BuiltinTypeSpec.Type.Array:
2784                                         if (!(spec is BuiltinTypeSpec)) {
2785                                                 Report.Error (644, Location, "`{0}' cannot derive from special class `{1}'",
2786                                                         GetSignatureForError (), base_type.GetSignatureForError ());
2787
2788                                                 base_type = Compiler.BuiltinTypes.Object;
2789                                         }
2790                                         break;
2791                                 }
2792
2793                                 if (!IsAccessibleAs (base_type)) {
2794                                         Report.SymbolRelatedToPreviousError (base_type);
2795                                         Report.Error (60, Location, "Inconsistent accessibility: base class `{0}' is less accessible than class `{1}'",
2796                                                 base_type.GetSignatureForError (), GetSignatureForError ());
2797                                 }
2798                         }
2799
2800                         if (PartialContainer.IsStatic && ifaces != null) {
2801                                 foreach (var t in ifaces)
2802                                         Report.SymbolRelatedToPreviousError (t);
2803                                 Report.Error (714, Location, "Static class `{0}' cannot implement interfaces", GetSignatureForError ());
2804                         }
2805
2806                         return ifaces;
2807                 }
2808
2809                 /// Search for at least one defined condition in ConditionalAttribute of attribute class
2810                 /// Valid only for attribute classes.
2811                 public override string[] ConditionalConditions ()
2812                 {
2813                         if ((caching_flags & (Flags.Excluded_Undetected | Flags.Excluded)) == 0)
2814                                 return null;
2815
2816                         caching_flags &= ~Flags.Excluded_Undetected;
2817
2818                         if (OptAttributes == null)
2819                                 return null;
2820
2821                         Attribute[] attrs = OptAttributes.SearchMulti (Module.PredefinedAttributes.Conditional);
2822                         if (attrs == null)
2823                                 return null;
2824
2825                         string[] conditions = new string[attrs.Length];
2826                         for (int i = 0; i < conditions.Length; ++i)
2827                                 conditions[i] = attrs[i].GetConditionalAttributeValue ();
2828
2829                         caching_flags |= Flags.Excluded;
2830                         return conditions;
2831                 }
2832         }
2833
2834         public sealed class Struct : ClassOrStruct
2835         {
2836                 bool is_unmanaged, has_unmanaged_check_done;
2837                 bool InTransit;
2838
2839                 // <summary>
2840                 //   Modifiers allowed in a struct declaration
2841                 // </summary>
2842                 const Modifiers AllowedModifiers =
2843                         Modifiers.NEW       |
2844                         Modifiers.PUBLIC    |
2845                         Modifiers.PROTECTED |
2846                         Modifiers.INTERNAL  |
2847                         Modifiers.UNSAFE    |
2848                         Modifiers.PRIVATE;
2849
2850                 public Struct (TypeContainer parent, MemberName name, Modifiers mod, Attributes attrs)
2851                         : base (parent, name, attrs, MemberKind.Struct)
2852                 {
2853                         var accmods = IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE;                      
2854                         this.ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, accmods, Location, Report) | Modifiers.SEALED ;
2855                         spec = new TypeSpec (Kind, null, this, null, ModFlags);
2856                 }
2857
2858                 public override AttributeTargets AttributeTargets {
2859                         get {
2860                                 return AttributeTargets.Struct;
2861                         }
2862                 }
2863
2864                 public override void Accept (StructuralVisitor visitor)
2865                 {
2866                         visitor.Visit (this);
2867                 }
2868
2869                 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
2870                 {
2871                         base.ApplyAttributeBuilder (a, ctor, cdata, pa);
2872
2873                         //
2874                         // When struct constains fixed fixed and struct layout has explicitly
2875                         // set CharSet, its value has to be propagated to compiler generated
2876                         // fixed types
2877                         //
2878                         if (a.Type == pa.StructLayout) {
2879                                 var value = a.GetNamedValue ("CharSet");
2880                                 if (value == null)
2881                                         return;
2882
2883                                 for (int i = 0; i < Members.Count; ++i) {
2884                                         FixedField ff = Members [i] as FixedField;
2885                                         if (ff == null)
2886                                                 continue;
2887
2888                                         ff.CharSet = (CharSet) System.Enum.Parse (typeof (CharSet), value.GetValue ().ToString ());
2889                                 }
2890                         }
2891                 }
2892
2893                 bool CheckStructCycles ()
2894                 {
2895                         if (InTransit)
2896                                 return false;
2897
2898                         InTransit = true;
2899                         foreach (var member in Members) {
2900                                 var field = member as Field;
2901                                 if (field == null)
2902                                         continue;
2903
2904                                 TypeSpec ftype = field.Spec.MemberType;
2905                                 if (!ftype.IsStruct)
2906                                         continue;
2907
2908                                 if (ftype is BuiltinTypeSpec)
2909                                         continue;
2910
2911                                 foreach (var targ in ftype.TypeArguments) {
2912                                         if (!CheckFieldTypeCycle (targ)) {
2913                                                 Report.Error (523, field.Location,
2914                                                         "Struct member `{0}' of type `{1}' causes a cycle in the struct layout",
2915                                                         field.GetSignatureForError (), ftype.GetSignatureForError ());
2916                                                 break;
2917                                         }
2918                                 }
2919
2920                                 //
2921                                 // Static fields of exactly same type are allowed
2922                                 //
2923                                 if (field.IsStatic && ftype == CurrentType)
2924                                         continue;
2925
2926                                 if (!CheckFieldTypeCycle (ftype)) {
2927                                         Report.Error (523, field.Location,
2928                                                 "Struct member `{0}' of type `{1}' causes a cycle in the struct layout",
2929                                                 field.GetSignatureForError (), ftype.GetSignatureForError ());
2930                                         break;
2931                                 }
2932                         }
2933
2934                         InTransit = false;
2935                         return true;
2936                 }
2937
2938                 static bool CheckFieldTypeCycle (TypeSpec ts)
2939                 {
2940                         var fts = ts.MemberDefinition as Struct;
2941                         if (fts == null)
2942                                 return true;
2943
2944                         return fts.CheckStructCycles ();
2945                 }
2946
2947                 public override void Emit ()
2948                 {
2949                         CheckStructCycles ();
2950
2951                         base.Emit ();
2952                 }
2953
2954                 public override bool IsUnmanagedType ()
2955                 {
2956                         if (has_unmanaged_check_done)
2957                                 return is_unmanaged;
2958
2959                         if (requires_delayed_unmanagedtype_check)
2960                                 return true;
2961
2962                         var parent_def = Parent.PartialContainer;
2963                         if (parent_def != null && parent_def.IsGenericOrParentIsGeneric) {
2964                                 has_unmanaged_check_done = true;
2965                                 return false;
2966                         }
2967
2968                         if (first_nonstatic_field != null) {
2969                                 requires_delayed_unmanagedtype_check = true;
2970
2971                                 foreach (var member in Members) {
2972                                         var f = member as Field;
2973                                         if (f == null)
2974                                                 continue;
2975
2976                                         if (f.IsStatic)
2977                                                 continue;
2978
2979                                         // It can happen when recursive unmanaged types are defined
2980                                         // struct S { S* s; }
2981                                         TypeSpec mt = f.MemberType;
2982                                         if (mt == null) {
2983                                                 return true;
2984                                         }
2985
2986                                         if (mt.IsUnmanaged)
2987                                                 continue;
2988
2989                                         has_unmanaged_check_done = true;
2990                                         return false;
2991                                 }
2992
2993                                 has_unmanaged_check_done = true;
2994                         }
2995
2996                         is_unmanaged = true;
2997                         return true;
2998                 }
2999
3000                 protected override TypeSpec[] ResolveBaseTypes (out FullNamedExpression base_class)
3001                 {
3002                         var ifaces = base.ResolveBaseTypes (out base_class);
3003                         base_type = Compiler.BuiltinTypes.ValueType;
3004                         return ifaces;
3005                 }
3006
3007                 public override void RegisterFieldForInitialization (MemberCore field, FieldInitializer expression)
3008                 {
3009                         if ((field.ModFlags & Modifiers.STATIC) == 0) {
3010                                 Report.Error (573, field.Location, "`{0}': Structs cannot have instance field initializers",
3011                                         field.GetSignatureForError ());
3012                                 return;
3013                         }
3014                         base.RegisterFieldForInitialization (field, expression);
3015                 }
3016
3017         }
3018
3019         /// <summary>
3020         ///   Interfaces
3021         /// </summary>
3022         public sealed class Interface : TypeDefinition {
3023
3024                 /// <summary>
3025                 ///   Modifiers allowed in a class declaration
3026                 /// </summary>
3027                 const Modifiers AllowedModifiers =
3028                         Modifiers.NEW       |
3029                         Modifiers.PUBLIC    |
3030                         Modifiers.PROTECTED |
3031                         Modifiers.INTERNAL  |
3032                         Modifiers.UNSAFE    |
3033                         Modifiers.PRIVATE;
3034
3035                 public Interface (TypeContainer parent, MemberName name, Modifiers mod, Attributes attrs)
3036                         : base (parent, name, attrs, MemberKind.Interface)
3037                 {
3038                         var accmods = IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE;
3039
3040                         this.ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, accmods, name.Location, Report);
3041                         spec = new TypeSpec (Kind, null, this, null, ModFlags);
3042                 }
3043
3044                 #region Properties
3045
3046                 public override AttributeTargets AttributeTargets {
3047                         get {
3048                                 return AttributeTargets.Interface;
3049                         }
3050                 }
3051
3052                 protected override TypeAttributes TypeAttr {
3053                         get {
3054                                 const TypeAttributes DefaultTypeAttributes =
3055                                         TypeAttributes.AutoLayout |
3056                                         TypeAttributes.Abstract |
3057                                         TypeAttributes.Interface;
3058
3059                                 return base.TypeAttr | DefaultTypeAttributes;
3060                         }
3061                 }
3062
3063                 #endregion
3064
3065                 public override void Accept (StructuralVisitor visitor)
3066                 {
3067                         visitor.Visit (this);
3068                 }
3069
3070                 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
3071                 {
3072                         if (a.Type == pa.ComImport && !attributes.Contains (pa.Guid)) {
3073                                 a.Error_MissingGuidAttribute ();
3074                                 return;
3075                         }
3076
3077                         base.ApplyAttributeBuilder (a, ctor, cdata, pa);
3078                 }
3079
3080                 protected override bool VerifyClsCompliance ()
3081                 {
3082                         if (!base.VerifyClsCompliance ())
3083                                 return false;
3084
3085                         if (iface_exprs != null) {
3086                                 foreach (var iface in iface_exprs) {
3087                                         if (iface.IsCLSCompliant ())
3088                                                 continue;
3089
3090                                         Report.SymbolRelatedToPreviousError (iface);
3091                                         Report.Warning (3027, 1, Location, "`{0}' is not CLS-compliant because base interface `{1}' is not CLS-compliant",
3092                                                 GetSignatureForError (), iface.GetSignatureForError ());
3093                                 }
3094                         }
3095
3096                         return true;
3097                 }
3098         }
3099
3100         public abstract class InterfaceMemberBase : MemberBase
3101         {
3102                 //
3103                 // Common modifiers allowed in a class declaration
3104                 //
3105                 protected const Modifiers AllowedModifiersClass =
3106                         Modifiers.NEW |
3107                         Modifiers.PUBLIC |
3108                         Modifiers.PROTECTED |
3109                         Modifiers.INTERNAL |
3110                         Modifiers.PRIVATE |
3111                         Modifiers.STATIC |
3112                         Modifiers.VIRTUAL |
3113                         Modifiers.SEALED |
3114                         Modifiers.OVERRIDE |
3115                         Modifiers.ABSTRACT |
3116                         Modifiers.UNSAFE |
3117                         Modifiers.EXTERN;
3118
3119                 //
3120                 // Common modifiers allowed in a struct declaration
3121                 //
3122                 protected const Modifiers AllowedModifiersStruct =
3123                         Modifiers.NEW |
3124                         Modifiers.PUBLIC |
3125                         Modifiers.PROTECTED |
3126                         Modifiers.INTERNAL |
3127                         Modifiers.PRIVATE |
3128                         Modifiers.STATIC |
3129                         Modifiers.OVERRIDE |
3130                         Modifiers.UNSAFE |
3131                         Modifiers.EXTERN;
3132
3133                 //
3134                 // Common modifiers allowed in a interface declaration
3135                 //
3136                 protected const Modifiers AllowedModifiersInterface =
3137                         Modifiers.NEW |
3138                         Modifiers.UNSAFE;
3139
3140                 //
3141                 // Whether this is an interface member.
3142                 //
3143                 public bool IsInterface;
3144
3145                 //
3146                 // If true, this is an explicit interface implementation
3147                 //
3148                 public readonly bool IsExplicitImpl;
3149
3150                 protected bool is_external_implementation;
3151
3152                 //
3153                 // The interface type we are explicitly implementing
3154                 //
3155                 public TypeSpec InterfaceType;
3156
3157                 //
3158                 // The method we're overriding if this is an override method.
3159                 //
3160                 protected MethodSpec base_method;
3161
3162                 readonly Modifiers explicit_mod_flags;
3163                 public MethodAttributes flags;
3164
3165                 protected InterfaceMemberBase (TypeDefinition parent, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, MemberName name, Attributes attrs)
3166                         : base (parent, type, mod, allowed_mod, Modifiers.PRIVATE, name, attrs)
3167                 {
3168                         IsInterface = parent.Kind == MemberKind.Interface;
3169                         IsExplicitImpl = (MemberName.ExplicitInterface != null);
3170                         explicit_mod_flags = mod;
3171                 }
3172
3173                 public abstract Variance ExpectedMemberTypeVariance { get; }
3174                 
3175                 protected override bool CheckBase ()
3176                 {
3177                         if (!base.CheckBase ())
3178                                 return false;
3179
3180                         if ((caching_flags & Flags.MethodOverloadsExist) != 0)
3181                                 CheckForDuplications ();
3182                         
3183                         if (IsExplicitImpl)
3184                                 return true;
3185
3186                         // For System.Object only
3187                         if (Parent.BaseType == null)
3188                                 return true;
3189
3190                         MemberSpec candidate;
3191                         bool overrides = false;
3192                         var base_member = FindBaseMember (out candidate, ref overrides);
3193
3194                         if ((ModFlags & Modifiers.OVERRIDE) != 0) {
3195                                 if (base_member == null) {
3196                                         if (candidate == null) {
3197                                                 if (this is Method && ((Method)this).ParameterInfo.IsEmpty && MemberName.Name == Destructor.MetadataName && MemberName.Arity == 0) {
3198                                                         Report.Error (249, Location, "Do not override `{0}'. Use destructor syntax instead",
3199                                                                 "object.Finalize()");
3200                                                 } else {
3201                                                         Report.Error (115, Location, "`{0}' is marked as an override but no suitable {1} found to override",
3202                                                                 GetSignatureForError (), SimpleName.GetMemberType (this));
3203                                                 }
3204                                         } else {
3205                                                 Report.SymbolRelatedToPreviousError (candidate);
3206                                                 if (this is Event)
3207                                                         Report.Error (72, Location, "`{0}': cannot override because `{1}' is not an event",
3208                                                                 GetSignatureForError (), TypeManager.GetFullNameSignature (candidate));
3209                                                 else if (this is PropertyBase)
3210                                                         Report.Error (544, Location, "`{0}': cannot override because `{1}' is not a property",
3211                                                                 GetSignatureForError (), TypeManager.GetFullNameSignature (candidate));
3212                                                 else
3213                                                         Report.Error (505, Location, "`{0}': cannot override because `{1}' is not a method",
3214                                                                 GetSignatureForError (), TypeManager.GetFullNameSignature (candidate));
3215                                         }
3216
3217                                         return false;
3218                                 }
3219
3220                                 //
3221                                 // Handles ambiguous overrides
3222                                 //
3223                                 if (candidate != null) {
3224                                         Report.SymbolRelatedToPreviousError (candidate);
3225                                         Report.SymbolRelatedToPreviousError (base_member);
3226
3227                                         // Get member definition for error reporting
3228                                         var m1 = MemberCache.GetMember (base_member.DeclaringType.GetDefinition (), base_member);
3229                                         var m2 = MemberCache.GetMember (candidate.DeclaringType.GetDefinition (), candidate);
3230
3231                                         Report.Error (462, Location,
3232                                                 "`{0}' cannot override inherited members `{1}' and `{2}' because they have the same signature when used in type `{3}'",
3233                                                 GetSignatureForError (), m1.GetSignatureForError (), m2.GetSignatureForError (), Parent.GetSignatureForError ());
3234                                 }
3235
3236                                 if (!CheckOverrideAgainstBase (base_member))
3237                                         return false;
3238
3239                                 ObsoleteAttribute oa = base_member.GetAttributeObsolete ();
3240                                 if (oa != null) {
3241                                         if (OptAttributes == null || !OptAttributes.Contains (Module.PredefinedAttributes.Obsolete)) {
3242                                                 Report.SymbolRelatedToPreviousError (base_member);
3243                                                 Report.Warning (672, 1, Location, "Member `{0}' overrides obsolete member `{1}'. Add the Obsolete attribute to `{0}'",
3244                                                         GetSignatureForError (), base_member.GetSignatureForError ());
3245                                         }
3246                                 } else {
3247                                         if (OptAttributes != null && OptAttributes.Contains (Module.PredefinedAttributes.Obsolete)) {
3248                                                 Report.SymbolRelatedToPreviousError (base_member);
3249                                                 Report.Warning (809, 1, Location, "Obsolete member `{0}' overrides non-obsolete member `{1}'",
3250                                                         GetSignatureForError (), base_member.GetSignatureForError ());
3251                                         }
3252                                 }
3253
3254                                 base_method = base_member as MethodSpec;
3255                                 return true;
3256                         }
3257
3258                         if (base_member == null && candidate != null && (!(candidate is IParametersMember) || !(this is IParametersMember)))
3259                                 base_member = candidate;
3260
3261                         if (base_member == null) {
3262                                 if ((ModFlags & Modifiers.NEW) != 0) {
3263                                         if (base_member == null) {
3264                                                 Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required",
3265                                                         GetSignatureForError ());
3266                                         }
3267                                 }
3268                         } else {
3269                                 if ((ModFlags & Modifiers.NEW) == 0) {
3270                                         ModFlags |= Modifiers.NEW;
3271                                         if (!IsCompilerGenerated) {
3272                                                 Report.SymbolRelatedToPreviousError (base_member);
3273                                                 if (!IsInterface && (base_member.Modifiers & (Modifiers.ABSTRACT | Modifiers.VIRTUAL | Modifiers.OVERRIDE)) != 0) {
3274                                                         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",
3275                                                                 GetSignatureForError (), base_member.GetSignatureForError ());
3276                                                 } else {
3277                                                         Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
3278                                                                 GetSignatureForError (), base_member.GetSignatureForError ());
3279                                                 }
3280                                         }
3281                                 }
3282
3283                                 if (!IsInterface && base_member.IsAbstract && !overrides && !IsStatic) {
3284                                         Report.SymbolRelatedToPreviousError (base_member);
3285                                         Report.Error (533, Location, "`{0}' hides inherited abstract member `{1}'",
3286                                                 GetSignatureForError (), base_member.GetSignatureForError ());
3287                                 }
3288                         }
3289
3290                         return true;
3291                 }
3292
3293                 protected virtual bool CheckForDuplications ()
3294                 {
3295                         return Parent.MemberCache.CheckExistingMembersOverloads (this, ParametersCompiled.EmptyReadOnlyParameters);
3296                 }
3297
3298                 //
3299                 // Performs various checks on the MethodInfo `mb' regarding the modifier flags
3300                 // that have been defined.
3301                 //
3302                 protected virtual bool CheckOverrideAgainstBase (MemberSpec base_member)
3303                 {
3304                         bool ok = true;
3305
3306                         if ((base_member.Modifiers & (Modifiers.ABSTRACT | Modifiers.VIRTUAL | Modifiers.OVERRIDE)) == 0) {
3307                                 Report.SymbolRelatedToPreviousError (base_member);
3308                                 Report.Error (506, Location,
3309                                         "`{0}': cannot override inherited member `{1}' because it is not marked virtual, abstract or override",
3310                                          GetSignatureForError (), TypeManager.CSharpSignature (base_member));
3311                                 ok = false;
3312                         }
3313
3314                         // Now we check that the overriden method is not final  
3315                         if ((base_member.Modifiers & Modifiers.SEALED) != 0) {
3316                                 Report.SymbolRelatedToPreviousError (base_member);
3317                                 Report.Error (239, Location, "`{0}': cannot override inherited member `{1}' because it is sealed",
3318                                                           GetSignatureForError (), TypeManager.CSharpSignature (base_member));
3319                                 ok = false;
3320                         }
3321
3322                         var base_member_type = ((IInterfaceMemberSpec) base_member).MemberType;
3323                         if (!TypeSpecComparer.Override.IsEqual (MemberType, base_member_type)) {
3324                                 Report.SymbolRelatedToPreviousError (base_member);
3325                                 if (this is PropertyBasedMember) {
3326                                         Report.Error (1715, Location, "`{0}': type must be `{1}' to match overridden member `{2}'",
3327                                                 GetSignatureForError (), base_member_type.GetSignatureForError (), base_member.GetSignatureForError ());
3328                                 } else {
3329                                         Report.Error (508, Location, "`{0}': return type must be `{1}' to match overridden member `{2}'",
3330                                                 GetSignatureForError (), base_member_type.GetSignatureForError (), base_member.GetSignatureForError ());
3331                                 }
3332                                 ok = false;
3333                         }
3334
3335                         return ok;
3336                 }
3337
3338                 protected static bool CheckAccessModifiers (MemberCore this_member, MemberSpec base_member)
3339                 {
3340                         var thisp = this_member.ModFlags & Modifiers.AccessibilityMask;
3341                         var base_classp = base_member.Modifiers & Modifiers.AccessibilityMask;
3342
3343                         if ((base_classp & (Modifiers.PROTECTED | Modifiers.INTERNAL)) == (Modifiers.PROTECTED | Modifiers.INTERNAL)) {
3344                                 //
3345                                 // It must be at least "protected"
3346                                 //
3347                                 if ((thisp & Modifiers.PROTECTED) == 0) {
3348                                         return false;
3349                                 }
3350
3351                                 //
3352                                 // when overriding protected internal, the method can be declared
3353                                 // protected internal only within the same assembly or assembly
3354                                 // which has InternalsVisibleTo
3355                                 //
3356                                 if ((thisp & Modifiers.INTERNAL) != 0) {
3357                                         return base_member.DeclaringType.MemberDefinition.IsInternalAsPublic (this_member.Module.DeclaringAssembly);
3358                                 }
3359
3360                                 //
3361                                 // protected overriding protected internal inside same assembly
3362                                 // requires internal modifier as well
3363                                 //
3364                                 if (base_member.DeclaringType.MemberDefinition.IsInternalAsPublic (this_member.Module.DeclaringAssembly)) {
3365                                         return false;
3366                                 }
3367
3368                                 return true;
3369                         }
3370
3371                         return thisp == base_classp;
3372                 }
3373
3374                 public override bool Define ()
3375                 {
3376                         if (IsInterface) {
3377                                 ModFlags = Modifiers.PUBLIC | Modifiers.ABSTRACT |
3378                                         Modifiers.VIRTUAL | (ModFlags & (Modifiers.UNSAFE | Modifiers.NEW));
3379
3380                                 flags = MethodAttributes.Public |
3381                                         MethodAttributes.Abstract |
3382                                         MethodAttributes.HideBySig |
3383                                         MethodAttributes.NewSlot |
3384                                         MethodAttributes.Virtual;
3385                         } else {
3386                                 Parent.PartialContainer.MethodModifiersValid (this);
3387
3388                                 flags = ModifiersExtensions.MethodAttr (ModFlags);
3389                         }
3390
3391                         if (IsExplicitImpl) {
3392                                 InterfaceType = MemberName.ExplicitInterface.ResolveAsType (Parent);
3393                                 if (InterfaceType == null)
3394                                         return false;
3395
3396                                 if ((ModFlags & Modifiers.PARTIAL) != 0) {
3397                                         Report.Error (754, Location, "A partial method `{0}' cannot explicitly implement an interface",
3398                                                 GetSignatureForError ());
3399                                 }
3400
3401                                 if (!InterfaceType.IsInterface) {
3402                                         Report.SymbolRelatedToPreviousError (InterfaceType);
3403                                         Report.Error (538, Location, "The type `{0}' in explicit interface declaration is not an interface",
3404                                                 InterfaceType.GetSignatureForError ());
3405                                 } else {
3406                                         Parent.PartialContainer.VerifyImplements (this);
3407                                 }
3408
3409                                 Modifiers allowed_explicit = Modifiers.AllowedExplicitImplFlags;
3410                                 if (this is Method)
3411                                         allowed_explicit |= Modifiers.ASYNC;
3412
3413                                 ModifiersExtensions.Check (allowed_explicit, explicit_mod_flags, 0, Location, Report);
3414                         }
3415
3416                         return base.Define ();
3417                 }
3418
3419                 protected bool DefineParameters (ParametersCompiled parameters)
3420                 {
3421                         if (!parameters.Resolve (this))
3422                                 return false;
3423
3424                         bool error = false;
3425                         for (int i = 0; i < parameters.Count; ++i) {
3426                                 Parameter p = parameters [i];
3427
3428                                 if (p.HasDefaultValue && (IsExplicitImpl || this is Operator || (this is Indexer && parameters.Count == 1)))
3429                                         p.Warning_UselessOptionalParameter (Report);
3430
3431                                 if (p.CheckAccessibility (this))
3432                                         continue;
3433
3434                                 TypeSpec t = parameters.Types [i];
3435                                 Report.SymbolRelatedToPreviousError (t);
3436                                 if (this is Indexer)
3437                                         Report.Error (55, Location,
3438                                                       "Inconsistent accessibility: parameter type `{0}' is less accessible than indexer `{1}'",
3439                                                       t.GetSignatureForError (), GetSignatureForError ());
3440                                 else if (this is Operator)
3441                                         Report.Error (57, Location,
3442                                                       "Inconsistent accessibility: parameter type `{0}' is less accessible than operator `{1}'",
3443                                                       t.GetSignatureForError (), GetSignatureForError ());
3444                                 else
3445                                         Report.Error (51, Location,
3446                                                 "Inconsistent accessibility: parameter type `{0}' is less accessible than method `{1}'",
3447                                                 t.GetSignatureForError (), GetSignatureForError ());
3448                                 error = true;
3449                         }
3450                         return !error;
3451                 }
3452
3453                 protected override void DoMemberTypeDependentChecks ()
3454                 {
3455                         base.DoMemberTypeDependentChecks ();
3456
3457                         VarianceDecl.CheckTypeVariance (MemberType, ExpectedMemberTypeVariance, this);
3458                 }
3459
3460                 public override void Emit()
3461                 {
3462                         // for extern static method must be specified either DllImport attribute or MethodImplAttribute.
3463                         // We are more strict than csc and report this as an error because SRE does not allow emit that
3464                         if ((ModFlags & Modifiers.EXTERN) != 0 && !is_external_implementation && (OptAttributes == null || !OptAttributes.HasResolveError ())) {
3465                                 if (this is Constructor) {
3466                                         Report.Warning (824, 1, Location,
3467                                                 "Constructor `{0}' is marked `external' but has no external implementation specified", GetSignatureForError ());
3468                                 } else {
3469                                         Report.Warning (626, 1, Location,
3470                                                 "`{0}' is marked as an external but has no DllImport attribute. Consider adding a DllImport attribute to specify the external implementation",
3471                                                 GetSignatureForError ());
3472                                 }
3473                         }
3474
3475                         base.Emit ();
3476                 }
3477
3478                 public override bool EnableOverloadChecks (MemberCore overload)
3479                 {
3480                         //
3481                         // Two members can differ in their explicit interface
3482                         // type parameter only
3483                         //
3484                         InterfaceMemberBase imb = overload as InterfaceMemberBase;
3485                         if (imb != null && imb.IsExplicitImpl) {
3486                                 if (IsExplicitImpl) {
3487                                         caching_flags |= Flags.MethodOverloadsExist;
3488                                 }
3489                                 return true;
3490                         }
3491
3492                         return IsExplicitImpl;
3493                 }
3494
3495                 protected void Error_CannotChangeAccessModifiers (MemberCore member, MemberSpec base_member)
3496                 {
3497                         var base_modifiers = base_member.Modifiers;
3498
3499                         // Remove internal modifier from types which are not internally accessible
3500                         if ((base_modifiers & Modifiers.AccessibilityMask) == (Modifiers.PROTECTED | Modifiers.INTERNAL) &&
3501                                 !base_member.DeclaringType.MemberDefinition.IsInternalAsPublic (member.Module.DeclaringAssembly))
3502                                 base_modifiers = Modifiers.PROTECTED;
3503
3504                         Report.SymbolRelatedToPreviousError (base_member);
3505                         Report.Error (507, member.Location,
3506                                 "`{0}': cannot change access modifiers when overriding `{1}' inherited member `{2}'",
3507                                 member.GetSignatureForError (),
3508                                 ModifiersExtensions.AccessibilityName (base_modifiers),
3509                                 base_member.GetSignatureForError ());
3510                 }
3511
3512                 protected void Error_StaticReturnType ()
3513                 {
3514                         Report.Error (722, Location,
3515                                 "`{0}': static types cannot be used as return types",
3516                                 MemberType.GetSignatureForError ());
3517                 }
3518
3519                 /// <summary>
3520                 /// Gets base method and its return type
3521                 /// </summary>
3522                 protected virtual MemberSpec FindBaseMember (out MemberSpec bestCandidate, ref bool overrides)
3523                 {
3524                         return MemberCache.FindBaseMember (this, out bestCandidate, ref overrides);
3525                 }
3526
3527                 //
3528                 // The "short" name of this property / indexer / event.  This is the
3529                 // name without the explicit interface.
3530                 //
3531                 public string ShortName {
3532                         get { return MemberName.Name; }
3533                 }
3534                 
3535                 //
3536                 // Returns full metadata method name
3537                 //
3538                 public string GetFullName (MemberName name)
3539                 {
3540                         return GetFullName (name.Name);
3541                 }
3542
3543                 public string GetFullName (string name)
3544                 {
3545                         if (!IsExplicitImpl)
3546                                 return name;
3547
3548                         //
3549                         // When dealing with explicit members a full interface type
3550                         // name is added to member name to avoid possible name conflicts
3551                         //
3552                         // We use CSharpName which gets us full name with benefit of
3553                         // replacing predefined names which saves some space and name
3554                         // is still unique
3555                         //
3556                         return InterfaceType.GetSignatureForError () + "." + name;
3557                 }
3558
3559                 public override string GetSignatureForDocumentation ()
3560                 {
3561                         if (IsExplicitImpl)
3562                                 return Parent.GetSignatureForDocumentation () + "." + InterfaceType.GetExplicitNameSignatureForDocumentation () + "#" + ShortName;
3563
3564                         return Parent.GetSignatureForDocumentation () + "." + ShortName;
3565                 }
3566
3567                 public override bool IsUsed 
3568                 {
3569                         get { return IsExplicitImpl || base.IsUsed; }
3570                 }
3571
3572                 public override void SetConstraints (List<Constraints> constraints_list)
3573                 {
3574                         if (((ModFlags & Modifiers.OVERRIDE) != 0 || IsExplicitImpl)) {
3575                                 Report.Error (460, Location,
3576                                         "`{0}': Cannot specify constraints for overrides and explicit interface implementation methods",
3577                                         GetSignatureForError ());
3578                         }
3579
3580                         base.SetConstraints (constraints_list);
3581                 }
3582         }
3583
3584         public abstract class MemberBase : MemberCore
3585         {
3586                 protected FullNamedExpression type_expr;
3587                 protected TypeSpec member_type;
3588                 public new TypeDefinition Parent;
3589
3590                 protected MemberBase (TypeDefinition parent, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, Modifiers def_mod, MemberName name, Attributes attrs)
3591                         : base (parent, name, attrs)
3592                 {
3593                         this.Parent = parent;
3594                         this.type_expr = type;
3595
3596                         if (name != MemberName.Null)
3597                                 ModFlags = ModifiersExtensions.Check (allowed_mod, mod, def_mod, Location, Report);
3598                 }
3599
3600                 #region Properties
3601
3602                 public TypeSpec MemberType {
3603                         get {
3604                                 return member_type;
3605                         }
3606                 }
3607
3608                 public FullNamedExpression TypeExpression {
3609                         get {
3610                                 return type_expr;
3611                         }
3612                 }
3613
3614                 #endregion
3615
3616                 //
3617                 // Main member define entry
3618                 //
3619                 public override bool Define ()
3620                 {
3621                         DoMemberTypeIndependentChecks ();
3622
3623                         //
3624                         // Returns false only when type resolution failed
3625                         //
3626                         if (!ResolveMemberType ())
3627                                 return false;
3628
3629                         DoMemberTypeDependentChecks ();
3630                         return true;
3631                 }
3632
3633                 //
3634                 // Any type_name independent checks
3635                 //
3636                 protected virtual void DoMemberTypeIndependentChecks ()
3637                 {
3638                         if ((Parent.ModFlags & Modifiers.SEALED) != 0 &&
3639                                 (ModFlags & (Modifiers.VIRTUAL | Modifiers.ABSTRACT)) != 0) {
3640                                 Report.Error (549, Location, "New virtual member `{0}' is declared in a sealed class `{1}'",
3641                                         GetSignatureForError (), Parent.GetSignatureForError ());
3642                         }
3643                 }
3644
3645                 //
3646                 // Any type_name dependent checks
3647                 //
3648                 protected virtual void DoMemberTypeDependentChecks ()
3649                 {
3650                         // verify accessibility
3651                         if (!IsAccessibleAs (MemberType)) {
3652                                 Report.SymbolRelatedToPreviousError (MemberType);
3653                                 if (this is Property)
3654                                         Report.Error (53, Location,
3655                                                       "Inconsistent accessibility: property type `" +
3656                                                       MemberType.GetSignatureForError () + "' is less " +
3657                                                       "accessible than property `" + GetSignatureForError () + "'");
3658                                 else if (this is Indexer)
3659                                         Report.Error (54, Location,
3660                                                       "Inconsistent accessibility: indexer return type `" +
3661                                                       MemberType.GetSignatureForError () + "' is less " +
3662                                                       "accessible than indexer `" + GetSignatureForError () + "'");
3663                                 else if (this is MethodCore) {
3664                                         if (this is Operator)
3665                                                 Report.Error (56, Location,
3666                                                               "Inconsistent accessibility: return type `" +
3667                                                               MemberType.GetSignatureForError () + "' is less " +
3668                                                               "accessible than operator `" + GetSignatureForError () + "'");
3669                                         else
3670                                                 Report.Error (50, Location,
3671                                                               "Inconsistent accessibility: return type `" +
3672                                                               MemberType.GetSignatureForError () + "' is less " +
3673                                                               "accessible than method `" + GetSignatureForError () + "'");
3674                                 } else {
3675                                         Report.Error (52, Location,
3676                                                       "Inconsistent accessibility: field type `" +
3677                                                       MemberType.GetSignatureForError () + "' is less " +
3678                                                       "accessible than field `" + GetSignatureForError () + "'");
3679                                 }
3680                         }
3681                 }
3682
3683                 protected void IsTypePermitted ()
3684                 {
3685                         if (MemberType.IsSpecialRuntimeType) {
3686                                 if (Parent is StateMachine) {
3687                                         Report.Error (4012, Location,
3688                                                 "Parameters or local variables of type `{0}' cannot be declared in async methods or iterators",
3689                                                 MemberType.GetSignatureForError ());
3690                                 } else if (Parent is HoistedStoreyClass) {
3691                                         Report.Error (4013, Location,
3692                                                 "Local variables of type `{0}' cannot be used inside anonymous methods, lambda expressions or query expressions",
3693                                                 MemberType.GetSignatureForError ());
3694                                 } else {
3695                                         Report.Error (610, Location, 
3696                                                 "Field or property cannot be of type `{0}'", MemberType.GetSignatureForError ());
3697                                 }
3698                         }
3699                 }
3700
3701                 protected virtual bool CheckBase ()
3702                 {
3703                         CheckProtectedModifier ();
3704
3705                         return true;
3706                 }
3707
3708                 public override string GetSignatureForDocumentation ()
3709                 {
3710                         return Parent.GetSignatureForDocumentation () + "." + MemberName.Basename;
3711                 }
3712
3713                 protected virtual bool ResolveMemberType ()
3714                 {
3715                         if (member_type != null)
3716                                 throw new InternalErrorException ("Multi-resolve");
3717
3718                         member_type = type_expr.ResolveAsType (this);
3719                         return member_type != null;
3720                 }
3721         }
3722 }
3723