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