Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2389-EpsLexicase/HeuristicLab.ExtLibs/HeuristicLab.NRefactory/5.5.0/NRefactory.CSharp-5.5.0/Parser/mcs/class.cs

Last change on this file was 11700, checked in by jkarder, 10 years ago

#2077: created branch and added first version

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