2 // class.cs: Class and Struct handlers
4 // Authors: Miguel de Icaza (miguel@gnu.org)
5 // Martin Baulig (martin@ximian.com)
6 // Marek Safar (marek.safar@gmail.com)
8 // Dual licensed under the terms of the MIT X11 or GNU GPL
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)
16 using System.Collections.Generic;
17 using System.Runtime.InteropServices;
18 using System.Security;
19 using System.Security.Permissions;
21 using System.Diagnostics;
22 using Mono.CompilerServices.SymbolWriter;
25 using XmlElement = System.Object;
29 using SecurityType = System.Collections.Generic.List<IKVM.Reflection.Emit.CustomAttributeBuilder>;
30 using IKVM.Reflection;
31 using IKVM.Reflection.Emit;
33 using SecurityType = System.Collections.Generic.Dictionary<System.Security.Permissions.SecurityAction, System.Security.PermissionSet>;
34 using System.Reflection;
35 using System.Reflection.Emit;
41 // General types container, used as a base class for all constructs which can hold types
43 public abstract class TypeContainer : MemberCore
45 public readonly MemberKind Kind;
46 public readonly string Basename;
48 protected List<TypeContainer> containers;
50 TypeDefinition main_container;
52 protected Dictionary<string, MemberCore> defined_names;
54 protected bool is_defined;
56 public int CounterAnonymousMethods { get; set; }
57 public int CounterAnonymousContainers { get; set; }
58 public int CounterSwitchTypes { get; set; }
60 protected TypeContainer (TypeContainer parent, MemberName name, Attributes attrs, MemberKind kind)
61 : base (parent, name, attrs)
65 this.Basename = name.Basename;
67 defined_names = new Dictionary<string, MemberCore> ();
70 public override TypeSpec CurrentType {
76 public Dictionary<string, MemberCore> DefinedNames {
82 public TypeDefinition PartialContainer {
84 return main_container;
87 main_container = value;
91 public IList<TypeContainer> Containers {
98 // Any unattached attributes during parsing get added here. User
101 public Attributes UnattachedAttributes {
105 public void AddCompilerGeneratedClass (CompilerGeneratedContainer c)
107 AddTypeContainerMember (c);
110 public virtual void AddPartial (TypeDefinition next_part)
113 (PartialContainer ?? this).defined_names.TryGetValue (next_part.Basename, out mc);
115 AddPartial (next_part, mc as TypeDefinition);
118 protected void AddPartial (TypeDefinition next_part, TypeDefinition existing)
120 next_part.ModFlags |= Modifiers.PARTIAL;
122 if (existing == null) {
123 AddTypeContainer (next_part);
127 if ((existing.ModFlags & Modifiers.PARTIAL) == 0) {
128 if (existing.Kind != next_part.Kind) {
129 AddTypeContainer (next_part);
131 Report.SymbolRelatedToPreviousError (next_part);
132 Error_MissingPartialModifier (existing);
138 if (existing.Kind != next_part.Kind) {
139 Report.SymbolRelatedToPreviousError (existing);
140 Report.Error (261, next_part.Location,
141 "Partial declarations of `{0}' must be all classes, all structs or all interfaces",
142 next_part.GetSignatureForError ());
145 if ((existing.ModFlags & Modifiers.AccessibilityMask) != (next_part.ModFlags & Modifiers.AccessibilityMask) &&
146 ((existing.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) == 0 &&
147 (next_part.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) == 0)) {
148 Report.SymbolRelatedToPreviousError (existing);
149 Report.Error (262, next_part.Location,
150 "Partial declarations of `{0}' have conflicting accessibility modifiers",
151 next_part.GetSignatureForError ());
154 var tc_names = existing.CurrentTypeParameters;
155 if (tc_names != null) {
156 for (int i = 0; i < tc_names.Count; ++i) {
157 var tp = next_part.MemberName.TypeParameters[i];
158 if (tc_names[i].MemberName.Name != tp.MemberName.Name) {
159 Report.SymbolRelatedToPreviousError (existing.Location, "");
160 Report.Error (264, next_part.Location, "Partial declarations of `{0}' must have the same type parameter names in the same order",
161 next_part.GetSignatureForError ());
165 if (tc_names[i].Variance != tp.Variance) {
166 Report.SymbolRelatedToPreviousError (existing.Location, "");
167 Report.Error (1067, next_part.Location, "Partial declarations of `{0}' must have the same type parameter variance modifiers",
168 next_part.GetSignatureForError ());
174 if ((next_part.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) != 0) {
175 existing.ModFlags |= next_part.ModFlags & ~(Modifiers.DEFAULT_ACCESS_MODIFER | Modifiers.AccessibilityMask);
176 } else if ((existing.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) != 0) {
177 existing.ModFlags &= ~(Modifiers.DEFAULT_ACCESS_MODIFER | Modifiers.AccessibilityMask);
178 existing.ModFlags |= next_part.ModFlags;
180 existing.ModFlags |= next_part.ModFlags;
183 existing.Definition.Modifiers = existing.ModFlags;
185 if (next_part.attributes != null) {
186 if (existing.attributes == null)
187 existing.attributes = next_part.attributes;
189 existing.attributes.AddAttributes (next_part.attributes.Attrs);
192 next_part.PartialContainer = existing;
194 existing.AddPartialPart (next_part);
196 AddTypeContainerMember (next_part);
199 public virtual void AddTypeContainer (TypeContainer tc)
201 AddTypeContainerMember (tc);
203 var tparams = tc.MemberName.TypeParameters;
204 if (tparams != null && tc.PartialContainer != null) {
205 var td = (TypeDefinition) tc;
206 for (int i = 0; i < tparams.Count; ++i) {
208 if (tp.MemberName == null)
211 td.AddNameToContainer (tp, tp.Name);
216 protected virtual void AddTypeContainerMember (TypeContainer tc)
221 public virtual void CloseContainer ()
223 if (containers != null) {
224 foreach (TypeContainer tc in containers) {
225 tc.CloseContainer ();
230 public virtual void CreateMetadataName (StringBuilder sb)
232 if (Parent != null && Parent.MemberName != null)
233 Parent.CreateMetadataName (sb);
235 MemberName.CreateMetadataName (sb);
238 public virtual bool CreateContainer ()
240 if (containers != null) {
241 foreach (TypeContainer tc in containers) {
242 tc.CreateContainer ();
249 public override bool Define ()
251 if (containers != null) {
252 foreach (TypeContainer tc in containers) {
257 // Release cache used by parser only
258 if (Module.Evaluator == null) {
259 defined_names = null;
261 defined_names.Clear ();
267 public virtual void PrepareEmit ()
269 if (containers != null) {
270 foreach (var t in containers) {
273 } catch (Exception e) {
274 if (MemberName == MemberName.Null)
277 throw new InternalErrorException (t, e);
283 public virtual bool DefineContainer ()
290 DoDefineContainer ();
292 if (containers != null) {
293 foreach (TypeContainer tc in containers) {
295 tc.DefineContainer ();
296 } catch (Exception e) {
297 if (MemberName == MemberName.Null)
300 throw new InternalErrorException (tc, e);
308 public virtual void ExpandBaseInterfaces ()
310 if (containers != null) {
311 foreach (TypeContainer tc in containers) {
312 tc.ExpandBaseInterfaces ();
317 protected virtual void DefineNamespace ()
319 if (containers != null) {
320 foreach (var tc in containers) {
322 tc.DefineNamespace ();
323 } catch (Exception e) {
324 throw new InternalErrorException (tc, e);
330 protected virtual void DoDefineContainer ()
334 public virtual void EmitContainer ()
336 if (containers != null) {
337 for (int i = 0; i < containers.Count; ++i)
338 containers[i].EmitContainer ();
342 protected void Error_MissingPartialModifier (MemberCore type)
344 Report.Error (260, type.Location,
345 "Missing partial modifier on declaration of type `{0}'. Another partial declaration of this type exists",
346 type.GetSignatureForError ());
349 public override string GetSignatureForDocumentation ()
351 if (Parent != null && Parent.MemberName != null)
352 return Parent.GetSignatureForDocumentation () + "." + MemberName.GetSignatureForDocumentation ();
354 return MemberName.GetSignatureForDocumentation ();
357 public override string GetSignatureForError ()
359 if (Parent != null && Parent.MemberName != null)
360 return Parent.GetSignatureForError () + "." + MemberName.GetSignatureForError ();
362 return MemberName.GetSignatureForError ();
365 public string GetSignatureForMetadata ()
367 if (Parent is TypeDefinition) {
368 return Parent.GetSignatureForMetadata () + "+" + TypeNameParser.Escape (MemberName.Basename);
371 var sb = new StringBuilder ();
372 CreateMetadataName (sb);
373 return sb.ToString ();
376 public virtual void RemoveContainer (TypeContainer cont)
378 if (containers != null)
379 containers.Remove (cont);
381 var tc = Parent == Module ? Module : this;
382 tc.defined_names.Remove (cont.Basename);
385 public virtual void VerifyMembers ()
387 if (containers != null) {
388 foreach (TypeContainer tc in containers)
393 public override void WriteDebugSymbol (MonoSymbolFile file)
395 if (containers != null) {
396 foreach (TypeContainer tc in containers) {
397 tc.WriteDebugSymbol (file);
403 public abstract class TypeDefinition : TypeContainer, ITypeDefinition
406 // Different context is needed when resolving type container base
407 // types. Type names come from the parent scope but type parameter
408 // names from the container scope.
410 public struct BaseContext : IMemberContext
414 public BaseContext (TypeContainer tc)
419 #region IMemberContext Members
421 public CompilerContext Compiler {
422 get { return tc.Compiler; }
425 public TypeSpec CurrentType {
426 get { return tc.Parent.CurrentType; }
429 public TypeParameters CurrentTypeParameters {
430 get { return tc.PartialContainer.CurrentTypeParameters; }
433 public MemberCore CurrentMemberDefinition {
437 public bool IsObsolete {
438 get { return tc.IsObsolete; }
441 public bool IsUnsafe {
442 get { return tc.IsUnsafe; }
445 public bool IsStatic {
446 get { return tc.IsStatic; }
449 public ModuleContainer Module {
450 get { return tc.Module; }
453 public string GetSignatureForError ()
455 return tc.GetSignatureForError ();
458 public ExtensionMethodCandidates LookupExtensionMethod (TypeSpec extensionType, string name, int arity)
463 public FullNamedExpression LookupNamespaceAlias (string name)
465 return tc.Parent.LookupNamespaceAlias (name);
468 public FullNamedExpression LookupNamespaceOrType (string name, int arity, LookupMode mode, Location loc)
471 var tp = CurrentTypeParameters;
473 TypeParameter t = tp.Find (name);
475 return new TypeParameterExpr (t, loc);
479 return tc.Parent.LookupNamespaceOrType (name, arity, mode, loc);
489 GetHashCode = 1 << 1,
490 HasStaticFieldInitializer = 1 << 2
493 readonly List<MemberCore> members;
495 // Holds a list of fields that have initializers
496 protected List<FieldInitializer> initialized_fields;
498 // Holds a list of static fields that have initializers
499 protected List<FieldInitializer> initialized_static_fields;
501 Dictionary<MethodSpec, Method> hoisted_base_call_proxies;
503 Dictionary<string, FullNamedExpression> Cache = new Dictionary<string, FullNamedExpression> ();
506 // Points to the first non-static field added to the container.
508 // This is an arbitrary choice. We are interested in looking at _some_ non-static field,
509 // and the first one's as good as any.
511 protected FieldBase first_nonstatic_field;
514 // This one is computed after we can distinguish interfaces
515 // from classes from the arraylist `type_bases'
517 protected TypeSpec base_type;
518 FullNamedExpression base_type_expr; // TODO: It's temporary variable
519 protected TypeSpec[] iface_exprs;
521 protected List<FullNamedExpression> type_bases;
523 // Partial parts for classes only
524 List<TypeDefinition> class_partial_parts;
526 TypeDefinition InTransit;
528 public TypeBuilder TypeBuilder;
529 GenericTypeParameterBuilder[] all_tp_builders;
531 // All recursive type parameters put together sharing same
532 // TypeParameter instances
534 TypeParameters all_type_parameters;
536 public const string DefaultIndexerName = "Item";
538 bool has_normal_indexers;
540 protected bool requires_delayed_unmanagedtype_check;
542 bool members_defined;
543 bool members_defined_ok;
544 protected bool has_static_constructor;
546 private CachedMethods cached_method;
548 protected TypeSpec spec;
549 TypeSpec current_type;
551 public int DynamicSitesCounter;
552 public int AnonymousMethodsCounter;
553 public int MethodGroupsCounter;
555 static readonly string[] attribute_targets = new string[] { "type" };
558 /// The pending methods that need to be implemented
559 // (interfaces or abstract methods)
561 PendingImplementation pending;
563 protected TypeDefinition (TypeContainer parent, MemberName name, Attributes attrs, MemberKind kind)
564 : base (parent, name, attrs, kind)
566 PartialContainer = this;
567 members = new List<MemberCore> ();
572 public List<FullNamedExpression> BaseTypeExpressions {
578 public override TypeSpec CurrentType {
580 if (current_type == null) {
581 if (IsGenericOrParentIsGeneric) {
583 // Switch to inflated version as it's used by all expressions
585 var targs = CurrentTypeParameters == null ? TypeSpec.EmptyTypes : CurrentTypeParameters.Types;
586 current_type = spec.MakeGenericType (this, targs);
596 public override TypeParameters CurrentTypeParameters {
598 return PartialContainer.MemberName.TypeParameters;
602 int CurrentTypeParametersStartIndex {
604 int total = all_tp_builders.Length;
605 if (CurrentTypeParameters != null) {
606 return total - CurrentTypeParameters.Count;
612 public virtual AssemblyDefinition DeclaringAssembly {
614 return Module.DeclaringAssembly;
618 IAssemblyDefinition ITypeDefinition.DeclaringAssembly {
620 return Module.DeclaringAssembly;
624 public TypeSpec Definition {
630 public bool HasMembersDefined {
632 return members_defined;
636 public bool HasInstanceConstructor {
638 return (caching_flags & Flags.HasInstanceConstructor) != 0;
641 caching_flags |= Flags.HasInstanceConstructor;
645 // Indicated whether container has StructLayout attribute set Explicit
646 public bool HasExplicitLayout {
647 get { return (caching_flags & Flags.HasExplicitLayout) != 0; }
648 set { caching_flags |= Flags.HasExplicitLayout; }
651 public bool HasOperators {
653 return (caching_flags & Flags.HasUserOperators) != 0;
656 caching_flags |= Flags.HasUserOperators;
660 public bool HasStructLayout {
661 get { return (caching_flags & Flags.HasStructLayout) != 0; }
662 set { caching_flags |= Flags.HasStructLayout; }
665 public TypeSpec[] Interfaces {
671 public bool IsGenericOrParentIsGeneric {
673 return all_type_parameters != null;
677 public bool IsTopLevel {
679 return !(Parent is TypeDefinition);
683 public bool IsPartial {
685 return (ModFlags & Modifiers.PARTIAL) != 0;
689 bool ITypeDefinition.IsTypeForwarder {
695 bool ITypeDefinition.IsCyclicTypeForwarder {
702 // Returns true for secondary partial containers
706 return PartialContainer != this;
710 public MemberCache MemberCache {
712 return spec.MemberCache;
716 public List<MemberCore> Members {
722 string ITypeDefinition.Namespace {
725 while (p.Kind != MemberKind.Namespace)
728 return p.MemberName == null ? null : p.GetSignatureForError ();
732 public TypeParameters TypeParametersAll {
734 return all_type_parameters;
738 public override string[] ValidAttributeTargets {
740 return attribute_targets;
746 public override void Accept (StructuralVisitor visitor)
748 visitor.Visit (this);
751 public void AddMember (MemberCore symbol)
753 if (symbol.MemberName.ExplicitInterface != null) {
754 if (!(Kind == MemberKind.Class || Kind == MemberKind.Struct)) {
755 Report.Error (541, symbol.Location,
756 "`{0}': explicit interface declaration can only be declared in a class or struct",
757 symbol.GetSignatureForError ());
761 AddNameToContainer (symbol, symbol.MemberName.Name);
762 members.Add (symbol);
765 public override void AddTypeContainer (TypeContainer tc)
767 AddNameToContainer (tc, tc.Basename);
769 base.AddTypeContainer (tc);
772 protected override void AddTypeContainerMember (TypeContainer tc)
776 if (containers == null)
777 containers = new List<TypeContainer> ();
779 base.AddTypeContainerMember (tc);
783 // Adds the member to defined_names table. It tests for duplications and enclosing name conflicts
785 public virtual void AddNameToContainer (MemberCore symbol, string name)
787 if (((ModFlags | symbol.ModFlags) & Modifiers.COMPILER_GENERATED) != 0)
791 if (!PartialContainer.defined_names.TryGetValue (name, out mc)) {
792 PartialContainer.defined_names.Add (name, symbol);
796 if (symbol.EnableOverloadChecks (mc))
799 InterfaceMemberBase im = mc as InterfaceMemberBase;
800 if (im != null && im.IsExplicitImpl)
803 Report.SymbolRelatedToPreviousError (mc);
804 if ((mc.ModFlags & Modifiers.PARTIAL) != 0 && (symbol is ClassOrStruct || symbol is Interface)) {
805 Error_MissingPartialModifier (symbol);
809 if (symbol is TypeParameter) {
810 Report.Error (692, symbol.Location,
811 "Duplicate type parameter `{0}'", symbol.GetSignatureForError ());
813 Report.Error (102, symbol.Location,
814 "The type `{0}' already contains a definition for `{1}'",
815 GetSignatureForError (), name);
821 public void AddConstructor (Constructor c)
823 AddConstructor (c, false);
826 public void AddConstructor (Constructor c, bool isDefault)
828 bool is_static = (c.ModFlags & Modifiers.STATIC) != 0;
830 AddNameToContainer (c, is_static ? Constructor.TypeConstructorName : Constructor.ConstructorName);
832 if (is_static && c.ParameterInfo.IsEmpty) {
833 PartialContainer.has_static_constructor = true;
835 PartialContainer.HasInstanceConstructor = true;
841 public bool AddField (FieldBase field)
845 if ((field.ModFlags & Modifiers.STATIC) != 0)
848 var first_field = PartialContainer.first_nonstatic_field;
849 if (first_field == null) {
850 PartialContainer.first_nonstatic_field = field;
854 if (Kind == MemberKind.Struct && first_field.Parent != field.Parent) {
855 Report.SymbolRelatedToPreviousError (first_field.Parent);
856 Report.Warning (282, 3, field.Location,
857 "struct instance field `{0}' found in different declaration from instance field `{1}'",
858 field.GetSignatureForError (), first_field.GetSignatureForError ());
864 /// Indexer has special handling in constrast to other AddXXX because the name can be driven by IndexerNameAttribute
866 public void AddIndexer (Indexer i)
871 public void AddOperator (Operator op)
873 PartialContainer.HasOperators = true;
877 public void AddPartialPart (TypeDefinition part)
879 if (Kind != MemberKind.Class)
882 if (class_partial_parts == null)
883 class_partial_parts = new List<TypeDefinition> ();
885 class_partial_parts.Add (part);
888 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
890 if (has_normal_indexers && a.Type == pa.DefaultMember) {
891 Report.Error (646, a.Location, "Cannot specify the `DefaultMember' attribute on type containing an indexer");
895 if (a.Type == pa.Required) {
896 Report.Error (1608, a.Location, "The RequiredAttribute attribute is not permitted on C# types");
900 TypeBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
903 public override AttributeTargets AttributeTargets {
905 throw new NotSupportedException ();
909 public TypeSpec BaseType {
911 return spec.BaseType;
915 protected virtual TypeAttributes TypeAttr {
917 return ModifiersExtensions.TypeAttr (ModFlags, IsTopLevel);
921 public int TypeParametersCount {
923 return MemberName.Arity;
927 TypeParameterSpec[] ITypeDefinition.TypeParameters {
929 return PartialContainer.CurrentTypeParameters.Types;
933 public string GetAttributeDefaultMember ()
935 return indexer_name ?? DefaultIndexerName;
938 public bool IsComImport {
940 if (OptAttributes == null)
943 return OptAttributes.Contains (Module.PredefinedAttributes.ComImport);
947 public virtual void RegisterFieldForInitialization (MemberCore field, FieldInitializer expression)
950 PartialContainer.RegisterFieldForInitialization (field, expression);
952 if ((field.ModFlags & Modifiers.STATIC) != 0){
953 if (initialized_static_fields == null) {
954 HasStaticFieldInitializer = true;
955 initialized_static_fields = new List<FieldInitializer> (4);
958 initialized_static_fields.Add (expression);
960 if (initialized_fields == null)
961 initialized_fields = new List<FieldInitializer> (4);
963 initialized_fields.Add (expression);
967 public void ResolveFieldInitializers (BlockContext ec)
969 Debug.Assert (!IsPartialPart);
972 if (initialized_static_fields == null)
975 bool has_complex_initializer = !ec.Module.Compiler.Settings.Optimize;
977 ExpressionStatement [] init = new ExpressionStatement [initialized_static_fields.Count];
978 for (i = 0; i < initialized_static_fields.Count; ++i) {
979 FieldInitializer fi = initialized_static_fields [i];
980 ExpressionStatement s = fi.ResolveStatement (ec);
982 s = EmptyExpressionStatement.Instance;
983 } else if (!fi.IsSideEffectFree) {
984 has_complex_initializer = true;
990 for (i = 0; i < initialized_static_fields.Count; ++i) {
991 FieldInitializer fi = initialized_static_fields [i];
993 // Need special check to not optimize code like this
994 // static int a = b = 5;
997 if (!has_complex_initializer && fi.IsDefaultInitializer)
1000 ec.AssignmentInfoOffset += fi.AssignmentOffset;
1001 ec.CurrentBlock.AddScopeStatement (new StatementExpression (init [i]));
1007 if (initialized_fields == null)
1010 for (int i = 0; i < initialized_fields.Count; ++i) {
1011 FieldInitializer fi = initialized_fields [i];
1012 ExpressionStatement s = fi.ResolveStatement (ec);
1017 // Field is re-initialized to its default value => removed
1019 if (fi.IsDefaultInitializer && ec.Module.Compiler.Settings.Optimize)
1022 ec.AssignmentInfoOffset += fi.AssignmentOffset;
1023 ec.CurrentBlock.AddScopeStatement (new StatementExpression (s));
1027 public override string DocComment {
1039 public PendingImplementation PendingImplementations {
1040 get { return pending; }
1043 internal override void GenerateDocComment (DocumentationBuilder builder)
1048 base.GenerateDocComment (builder);
1050 foreach (var member in members)
1051 member.GenerateDocComment (builder);
1054 public TypeSpec GetAttributeCoClass ()
1056 if (OptAttributes == null)
1059 Attribute a = OptAttributes.Search (Module.PredefinedAttributes.CoClass);
1063 return a.GetCoClassAttributeValue ();
1066 public AttributeUsageAttribute GetAttributeUsage (PredefinedAttribute pa)
1069 if (OptAttributes != null) {
1070 a = OptAttributes.Search (pa);
1076 return a.GetAttributeUsageAttribute ();
1079 public virtual CompilationSourceFile GetCompilationSourceFile ()
1081 TypeContainer ns = Parent;
1083 var sf = ns as CompilationSourceFile;
1091 public virtual void SetBaseTypes (List<FullNamedExpression> baseTypes)
1093 type_bases = baseTypes;
1097 /// This function computes the Base class and also the
1098 /// list of interfaces that the class or struct @c implements.
1100 /// The return value is an array (might be null) of
1101 /// interfaces implemented (as Types).
1103 /// The @base_class argument is set to the base object or null
1104 /// if this is `System.Object'.
1106 protected virtual TypeSpec[] ResolveBaseTypes (out FullNamedExpression base_class)
1109 if (type_bases == null)
1112 int count = type_bases.Count;
1113 TypeSpec[] ifaces = null;
1114 var base_context = new BaseContext (this);
1115 for (int i = 0, j = 0; i < count; i++){
1116 FullNamedExpression fne = type_bases [i];
1118 var fne_resolved = fne.ResolveAsType (base_context);
1119 if (fne_resolved == null)
1122 if (i == 0 && Kind == MemberKind.Class && !fne_resolved.IsInterface) {
1123 if (fne_resolved.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
1124 Report.Error (1965, Location, "Class `{0}' cannot derive from the dynamic type",
1125 GetSignatureForError ());
1130 base_type = fne_resolved;
1136 ifaces = new TypeSpec [count - i];
1138 if (fne_resolved.IsInterface) {
1139 for (int ii = 0; ii < j; ++ii) {
1140 if (fne_resolved == ifaces [ii]) {
1141 Report.Error (528, Location, "`{0}' is already listed in interface list",
1142 fne_resolved.GetSignatureForError ());
1147 if (Kind == MemberKind.Interface && !IsAccessibleAs (fne_resolved)) {
1148 Report.Error (61, fne.Location,
1149 "Inconsistent accessibility: base interface `{0}' is less accessible than interface `{1}'",
1150 fne_resolved.GetSignatureForError (), GetSignatureForError ());
1153 Report.SymbolRelatedToPreviousError (fne_resolved);
1154 if (Kind != MemberKind.Class) {
1155 Report.Error (527, fne.Location, "Type `{0}' in interface list is not an interface", fne_resolved.GetSignatureForError ());
1156 } else if (base_class != null)
1157 Report.Error (1721, fne.Location, "`{0}': Classes cannot have multiple base classes (`{1}' and `{2}')",
1158 GetSignatureForError (), base_class.GetSignatureForError (), fne_resolved.GetSignatureForError ());
1160 Report.Error (1722, fne.Location, "`{0}': Base class `{1}' must be specified as first",
1161 GetSignatureForError (), fne_resolved.GetSignatureForError ());
1165 ifaces [j++] = fne_resolved;
1172 // Checks that some operators come in pairs:
1178 // They are matched based on the return type and the argument types
1180 void CheckPairedOperators ()
1182 bool has_equality_or_inequality = false;
1183 List<Operator.OpType> found_matched = new List<Operator.OpType> ();
1185 for (int i = 0; i < members.Count; ++i) {
1186 var o_a = members[i] as Operator;
1190 var o_type = o_a.OperatorType;
1191 if (o_type == Operator.OpType.Equality || o_type == Operator.OpType.Inequality)
1192 has_equality_or_inequality = true;
1194 if (found_matched.Contains (o_type))
1197 var matching_type = o_a.GetMatchingOperator ();
1198 if (matching_type == Operator.OpType.TOP) {
1202 bool pair_found = false;
1203 for (int ii = 0; ii < members.Count; ++ii) {
1204 var o_b = members[ii] as Operator;
1205 if (o_b == null || o_b.OperatorType != matching_type)
1208 if (!TypeSpecComparer.IsEqual (o_a.ReturnType, o_b.ReturnType))
1211 if (!TypeSpecComparer.Equals (o_a.ParameterTypes, o_b.ParameterTypes))
1214 found_matched.Add (matching_type);
1220 Report.Error (216, o_a.Location,
1221 "The operator `{0}' requires a matching operator `{1}' to also be defined",
1222 o_a.GetSignatureForError (), Operator.GetName (matching_type));
1226 if (has_equality_or_inequality) {
1228 Report.Warning (660, 2, Location, "`{0}' defines operator == or operator != but does not override Object.Equals(object o)",
1229 GetSignatureForError ());
1231 if (!HasGetHashCode)
1232 Report.Warning (661, 2, Location, "`{0}' defines operator == or operator != but does not override Object.GetHashCode()",
1233 GetSignatureForError ());
1237 public override void CreateMetadataName (StringBuilder sb)
1239 if (Parent.MemberName != null) {
1240 Parent.CreateMetadataName (sb);
1242 if (sb.Length != 0) {
1247 sb.Append (MemberName.Basename);
1250 bool CreateTypeBuilder ()
1253 // Sets .size to 1 for structs with no instance fields
1255 int type_size = Kind == MemberKind.Struct && first_nonstatic_field == null && !(this is StateMachine) ? 1 : 0;
1257 var parent_def = Parent as TypeDefinition;
1258 if (parent_def == null) {
1259 var sb = new StringBuilder ();
1260 CreateMetadataName (sb);
1261 TypeBuilder = Module.CreateBuilder (sb.ToString (), TypeAttr, type_size);
1263 TypeBuilder = parent_def.TypeBuilder.DefineNestedType (Basename, TypeAttr, null, type_size);
1266 if (DeclaringAssembly.Importer != null)
1267 DeclaringAssembly.Importer.AddCompiledType (TypeBuilder, spec);
1269 spec.SetMetaInfo (TypeBuilder);
1270 spec.MemberCache = new MemberCache (this);
1272 TypeParameters parentAllTypeParameters = null;
1273 if (parent_def != null) {
1274 spec.DeclaringType = Parent.CurrentType;
1275 parent_def.MemberCache.AddMember (spec);
1276 parentAllTypeParameters = parent_def.all_type_parameters;
1279 if (MemberName.TypeParameters != null || parentAllTypeParameters != null) {
1280 var tparam_names = CreateTypeParameters (parentAllTypeParameters);
1282 all_tp_builders = TypeBuilder.DefineGenericParameters (tparam_names);
1284 if (CurrentTypeParameters != null) {
1285 CurrentTypeParameters.Create (spec, CurrentTypeParametersStartIndex, this);
1286 CurrentTypeParameters.Define (all_tp_builders);
1293 string[] CreateTypeParameters (TypeParameters parentAllTypeParameters)
1296 int parent_offset = 0;
1297 if (parentAllTypeParameters != null) {
1298 if (CurrentTypeParameters == null) {
1299 all_type_parameters = parentAllTypeParameters;
1300 return parentAllTypeParameters.GetAllNames ();
1303 names = new string[parentAllTypeParameters.Count + CurrentTypeParameters.Count];
1304 all_type_parameters = new TypeParameters (names.Length);
1305 all_type_parameters.Add (parentAllTypeParameters);
1307 parent_offset = all_type_parameters.Count;
1308 for (int i = 0; i < parent_offset; ++i)
1309 names[i] = all_type_parameters[i].MemberName.Name;
1312 names = new string[CurrentTypeParameters.Count];
1315 for (int i = 0; i < CurrentTypeParameters.Count; ++i) {
1316 if (all_type_parameters != null)
1317 all_type_parameters.Add (MemberName.TypeParameters[i]);
1319 var name = CurrentTypeParameters[i].MemberName.Name;
1320 names[parent_offset + i] = name;
1321 for (int ii = 0; ii < parent_offset + i; ++ii) {
1322 if (names[ii] != name)
1325 var tp = CurrentTypeParameters[i];
1326 var conflict = all_type_parameters[ii];
1328 tp.WarningParentNameConflict (conflict);
1332 if (all_type_parameters == null)
1333 all_type_parameters = CurrentTypeParameters;
1339 public SourceMethodBuilder CreateMethodSymbolEntry ()
1341 if (Module.DeclaringAssembly.SymbolWriter == null)
1344 var source_file = GetCompilationSourceFile ();
1345 if (source_file == null)
1348 return new SourceMethodBuilder (source_file.SymbolUnitEntry);
1352 // Creates a proxy base method call inside this container for hoisted base member calls
1354 public MethodSpec CreateHoistedBaseCallProxy (ResolveContext rc, MethodSpec method)
1356 Method proxy_method;
1359 // One proxy per base method is enough
1361 if (hoisted_base_call_proxies == null) {
1362 hoisted_base_call_proxies = new Dictionary<MethodSpec, Method> ();
1363 proxy_method = null;
1365 hoisted_base_call_proxies.TryGetValue (method, out proxy_method);
1368 if (proxy_method == null) {
1369 string name = CompilerGeneratedContainer.MakeName (method.Name, null, "BaseCallProxy", hoisted_base_call_proxies.Count);
1371 MemberName member_name;
1372 TypeArguments targs = null;
1373 TypeSpec return_type = method.ReturnType;
1374 var local_param_types = method.Parameters.Types;
1376 if (method.IsGeneric) {
1378 // Copy all base generic method type parameters info
1380 var hoisted_tparams = method.GenericDefinition.TypeParameters;
1381 var tparams = new TypeParameters ();
1383 targs = new TypeArguments ();
1384 targs.Arguments = new TypeSpec[hoisted_tparams.Length];
1385 for (int i = 0; i < hoisted_tparams.Length; ++i) {
1386 var tp = hoisted_tparams[i];
1387 var local_tp = new TypeParameter (tp, null, new MemberName (tp.Name, Location), null);
1388 tparams.Add (local_tp);
1390 targs.Add (new SimpleName (tp.Name, Location));
1391 targs.Arguments[i] = local_tp.Type;
1394 member_name = new MemberName (name, tparams, Location);
1397 // Mutate any method type parameters from original
1398 // to newly created hoisted version
1400 var mutator = new TypeParameterMutator (hoisted_tparams, tparams);
1401 return_type = mutator.Mutate (return_type);
1402 local_param_types = mutator.Mutate (local_param_types);
1404 member_name = new MemberName (name);
1407 var base_parameters = new Parameter[method.Parameters.Count];
1408 for (int i = 0; i < base_parameters.Length; ++i) {
1409 var base_param = method.Parameters.FixedParameters[i];
1410 base_parameters[i] = new Parameter (new TypeExpression (local_param_types [i], Location),
1411 base_param.Name, base_param.ModFlags, null, Location);
1412 base_parameters[i].Resolve (this, i);
1415 var cloned_params = ParametersCompiled.CreateFullyResolved (base_parameters, method.Parameters.Types);
1416 if (method.Parameters.HasArglist) {
1417 cloned_params.FixedParameters[0] = new Parameter (null, "__arglist", Parameter.Modifier.NONE, null, Location);
1418 cloned_params.Types[0] = Module.PredefinedTypes.RuntimeArgumentHandle.Resolve ();
1421 // Compiler generated proxy
1422 proxy_method = new Method (this, new TypeExpression (return_type, Location),
1423 Modifiers.PRIVATE | Modifiers.COMPILER_GENERATED | Modifiers.DEBUGGER_HIDDEN,
1424 member_name, cloned_params, null);
1426 var block = new ToplevelBlock (Compiler, proxy_method.ParameterInfo, Location) {
1427 IsCompilerGenerated = true
1430 var mg = MethodGroupExpr.CreatePredefined (method, method.DeclaringType, Location);
1431 mg.InstanceExpression = new BaseThis (method.DeclaringType, Location);
1433 mg.SetTypeArguments (rc, targs);
1435 // Get all the method parameters and pass them as arguments
1436 var real_base_call = new Invocation (mg, block.GetAllParametersArguments ());
1437 Statement statement;
1438 if (method.ReturnType.Kind == MemberKind.Void)
1439 statement = new StatementExpression (real_base_call);
1441 statement = new Return (real_base_call, Location);
1443 block.AddStatement (statement);
1444 proxy_method.Block = block;
1446 members.Add (proxy_method);
1447 proxy_method.Define ();
1448 proxy_method.PrepareEmit ();
1450 hoisted_base_call_proxies.Add (method, proxy_method);
1453 return proxy_method.Spec;
1456 protected bool DefineBaseTypes ()
1458 if (IsPartialPart && Kind == MemberKind.Class)
1461 return DoDefineBaseType ();
1464 bool DoDefineBaseType ()
1466 iface_exprs = ResolveBaseTypes (out base_type_expr);
1469 if (IsPartialPart) {
1470 set_base_type = false;
1472 if (base_type_expr != null) {
1473 if (PartialContainer.base_type_expr != null && PartialContainer.base_type != base_type) {
1474 Report.SymbolRelatedToPreviousError (base_type_expr.Location, "");
1475 Report.Error (263, Location,
1476 "Partial declarations of `{0}' must not specify different base classes",
1477 GetSignatureForError ());
1479 PartialContainer.base_type_expr = base_type_expr;
1480 PartialContainer.base_type = base_type;
1481 set_base_type = true;
1485 if (iface_exprs != null) {
1486 if (PartialContainer.iface_exprs == null)
1487 PartialContainer.iface_exprs = iface_exprs;
1489 var ifaces = new List<TypeSpec> (PartialContainer.iface_exprs);
1490 foreach (var iface_partial in iface_exprs) {
1491 if (ifaces.Contains (iface_partial))
1494 ifaces.Add (iface_partial);
1497 PartialContainer.iface_exprs = ifaces.ToArray ();
1501 PartialContainer.members.AddRange (members);
1502 if (containers != null) {
1503 if (PartialContainer.containers == null)
1504 PartialContainer.containers = new List<TypeContainer> ();
1506 PartialContainer.containers.AddRange (containers);
1509 members_defined = members_defined_ok = true;
1510 caching_flags |= Flags.CloseTypeCreated;
1512 set_base_type = true;
1515 var cycle = CheckRecursiveDefinition (this);
1516 if (cycle != null) {
1517 Report.SymbolRelatedToPreviousError (cycle);
1518 if (this is Interface) {
1519 Report.Error (529, Location,
1520 "Inherited interface `{0}' causes a cycle in the interface hierarchy of `{1}'",
1521 GetSignatureForError (), cycle.GetSignatureForError ());
1524 PartialContainer.iface_exprs = null;
1526 Report.Error (146, Location,
1527 "Circular base class dependency involving `{0}' and `{1}'",
1528 GetSignatureForError (), cycle.GetSignatureForError ());
1531 PartialContainer.base_type = null;
1535 if (iface_exprs != null) {
1536 foreach (var iface_type in iface_exprs) {
1537 // Prevents a crash, the interface might not have been resolved: 442144
1538 if (iface_type == null)
1541 if (!spec.AddInterfaceDefined (iface_type))
1544 TypeBuilder.AddInterfaceImplementation (iface_type.GetMetaInfo ());
1548 if (Kind == MemberKind.Interface) {
1549 spec.BaseType = Compiler.BuiltinTypes.Object;
1553 if (set_base_type) {
1558 // Base type of partial container has to be resolved before we
1559 // resolve any nested types of the container. We need to know
1560 // partial parts because the base type can be specified in file
1561 // defined after current container
1563 if (class_partial_parts != null) {
1564 foreach (var pp in class_partial_parts)
1565 pp.DoDefineBaseType ();
1574 if (base_type == null) {
1575 TypeBuilder.SetParent (null);
1579 if (spec.BaseType == base_type)
1582 spec.BaseType = base_type;
1585 spec.UpdateInflatedInstancesBaseType ();
1587 // Set base type after type creation
1588 TypeBuilder.SetParent (base_type.GetMetaInfo ());
1591 public override void ExpandBaseInterfaces ()
1594 DoExpandBaseInterfaces ();
1596 base.ExpandBaseInterfaces ();
1599 public void DoExpandBaseInterfaces ()
1601 if ((caching_flags & Flags.InterfacesExpanded) != 0)
1604 caching_flags |= Flags.InterfacesExpanded;
1607 // Expand base interfaces. It cannot be done earlier because all partial
1608 // interface parts need to be defined before the type they are used from
1610 if (iface_exprs != null) {
1611 foreach (var iface in iface_exprs) {
1615 var td = iface.MemberDefinition as TypeDefinition;
1617 td.DoExpandBaseInterfaces ();
1619 if (iface.Interfaces == null)
1622 foreach (var biface in iface.Interfaces) {
1623 if (spec.AddInterfaceDefined (biface)) {
1624 TypeBuilder.AddInterfaceImplementation (biface.GetMetaInfo ());
1631 // Include all base type interfaces too, see ImportTypeBase for details
1633 if (base_type != null) {
1634 var td = base_type.MemberDefinition as TypeDefinition;
1636 td.DoExpandBaseInterfaces ();
1639 // Simply use base interfaces only, they are all expanded which makes
1640 // it easy to handle generic type argument propagation with single
1643 // interface IA<T> : IB<T>
1644 // interface IB<U> : IC<U>
1647 if (base_type.Interfaces != null) {
1648 foreach (var iface in base_type.Interfaces) {
1649 spec.AddInterfaceDefined (iface);
1655 public override void PrepareEmit ()
1657 if ((caching_flags & Flags.CloseTypeCreated) != 0)
1660 foreach (var member in members) {
1661 var pm = member as IParametersMember;
1663 var mc = member as MethodOrOperator;
1668 var p = pm.Parameters;
1672 ((ParametersCompiled) p).ResolveDefaultValues (member);
1675 var c = member as Const;
1680 base.PrepareEmit ();
1684 // Defines the type in the appropriate ModuleBuilder or TypeBuilder.
1686 public override bool CreateContainer ()
1688 if (TypeBuilder != null)
1694 if (IsPartialPart) {
1695 spec = PartialContainer.spec;
1696 TypeBuilder = PartialContainer.TypeBuilder;
1697 all_tp_builders = PartialContainer.all_tp_builders;
1698 all_type_parameters = PartialContainer.all_type_parameters;
1700 if (!CreateTypeBuilder ()) {
1706 return base.CreateContainer ();
1709 protected override void DoDefineContainer ()
1713 DoResolveTypeParameters ();
1717 // Replaces normal spec with predefined one when compiling corlib
1718 // and this type container defines predefined type
1720 public void SetPredefinedSpec (BuiltinTypeSpec spec)
1722 // When compiling build-in types we start with two
1723 // version of same type. One is of BuiltinTypeSpec and
1724 // second one is ordinary TypeSpec. The unification
1725 // happens at later stage when we know which type
1726 // really matches the builtin type signature. However
1727 // that means TypeSpec create during CreateType of this
1728 // type has to be replaced with builtin one
1730 spec.SetMetaInfo (TypeBuilder);
1731 spec.MemberCache = this.spec.MemberCache;
1732 spec.DeclaringType = this.spec.DeclaringType;
1735 current_type = null;
1738 public override void RemoveContainer (TypeContainer cont)
1740 base.RemoveContainer (cont);
1741 Members.Remove (cont);
1742 Cache.Remove (cont.Basename);
1745 protected virtual bool DoResolveTypeParameters ()
1747 var tparams = CurrentTypeParameters;
1748 if (tparams == null)
1751 var base_context = new BaseContext (this);
1752 for (int i = 0; i < tparams.Count; ++i) {
1753 var tp = tparams[i];
1755 if (!tp.ResolveConstraints (base_context)) {
1761 if (IsPartialPart) {
1762 PartialContainer.CurrentTypeParameters.UpdateConstraints (this);
1768 TypeSpec CheckRecursiveDefinition (TypeDefinition tc)
1770 if (InTransit != null)
1775 if (base_type != null) {
1776 var ptc = base_type.MemberDefinition as TypeDefinition;
1777 if (ptc != null && ptc.CheckRecursiveDefinition (this) != null)
1781 if (iface_exprs != null) {
1782 foreach (var iface in iface_exprs) {
1783 // the interface might not have been resolved, prevents a crash, see #442144
1786 var ptc = iface.MemberDefinition as Interface;
1787 if (ptc != null && ptc.CheckRecursiveDefinition (this) != null)
1792 if (!IsTopLevel && Parent.PartialContainer.CheckRecursiveDefinition (this) != null)
1800 /// Populates our TypeBuilder with fields and methods
1802 public sealed override bool Define ()
1804 if (members_defined)
1805 return members_defined_ok;
1807 members_defined_ok = DoDefineMembers ();
1808 members_defined = true;
1812 return members_defined_ok;
1815 protected virtual bool DoDefineMembers ()
1817 Debug.Assert (!IsPartialPart);
1819 if (iface_exprs != null) {
1820 foreach (var iface_type in iface_exprs) {
1821 if (iface_type == null)
1824 // Ensure the base is always setup
1825 var compiled_iface = iface_type.MemberDefinition as Interface;
1826 if (compiled_iface != null)
1827 compiled_iface.Define ();
1829 ObsoleteAttribute oa = iface_type.GetAttributeObsolete ();
1830 if (oa != null && !IsObsolete)
1831 AttributeTester.Report_ObsoleteMessage (oa, iface_type.GetSignatureForError (), Location, Report);
1833 if (iface_type.Arity > 0) {
1834 // TODO: passing `this' is wrong, should be base type iface instead
1835 VarianceDecl.CheckTypeVariance (iface_type, Variance.Covariant, this);
1837 if (((InflatedTypeSpec) iface_type).HasDynamicArgument () && !IsCompilerGenerated) {
1838 Report.Error (1966, Location,
1839 "`{0}': cannot implement a dynamic interface `{1}'",
1840 GetSignatureForError (), iface_type.GetSignatureForError ());
1845 if (iface_type.IsGenericOrParentIsGeneric) {
1846 foreach (var prev_iface in iface_exprs) {
1847 if (prev_iface == iface_type || prev_iface == null)
1850 if (!TypeSpecComparer.Unify.IsEqual (iface_type, prev_iface))
1853 Report.Error (695, Location,
1854 "`{0}' cannot implement both `{1}' and `{2}' because they may unify for some type parameter substitutions",
1855 GetSignatureForError (), prev_iface.GetSignatureForError (), iface_type.GetSignatureForError ());
1860 if (Kind == MemberKind.Interface) {
1861 foreach (var iface in spec.Interfaces) {
1862 MemberCache.AddInterface (iface);
1867 if (base_type != null) {
1869 // Run checks skipped during DefineType (e.g FullNamedExpression::ResolveAsType)
1871 if (base_type_expr != null) {
1872 ObsoleteAttribute obsolete_attr = base_type.GetAttributeObsolete ();
1873 if (obsolete_attr != null && !IsObsolete)
1874 AttributeTester.Report_ObsoleteMessage (obsolete_attr, base_type.GetSignatureForError (), base_type_expr.Location, Report);
1876 if (IsGenericOrParentIsGeneric && base_type.IsAttribute) {
1877 Report.Error (698, base_type_expr.Location,
1878 "A generic type cannot derive from `{0}' because it is an attribute class",
1879 base_type.GetSignatureForError ());
1883 var baseContainer = base_type.MemberDefinition as ClassOrStruct;
1884 if (baseContainer != null) {
1885 baseContainer.Define ();
1888 // It can trigger define of this type (for generic types only)
1890 if (HasMembersDefined)
1895 if (Kind == MemberKind.Struct || Kind == MemberKind.Class) {
1896 pending = PendingImplementation.GetPendingImplementations (this);
1899 var count = members.Count;
1900 for (int i = 0; i < count; ++i) {
1901 var mc = members[i] as InterfaceMemberBase;
1902 if (mc == null || !mc.IsExplicitImpl)
1907 } catch (Exception e) {
1908 throw new InternalErrorException (mc, e);
1912 for (int i = 0; i < count; ++i) {
1913 var mc = members[i] as InterfaceMemberBase;
1914 if (mc != null && mc.IsExplicitImpl)
1917 if (members[i] is TypeContainer)
1921 members[i].Define ();
1922 } catch (Exception e) {
1923 throw new InternalErrorException (members[i], e);
1928 CheckPairedOperators ();
1931 if (requires_delayed_unmanagedtype_check) {
1932 requires_delayed_unmanagedtype_check = false;
1933 foreach (var member in members) {
1934 var f = member as Field;
1935 if (f != null && f.MemberType != null && f.MemberType.IsPointer)
1936 TypeManager.VerifyUnmanaged (Module, f.MemberType, f.Location);
1940 ComputeIndexerName();
1942 if (HasEquals && !HasGetHashCode) {
1943 Report.Warning (659, 3, Location,
1944 "`{0}' overrides Object.Equals(object) but does not override Object.GetHashCode()", GetSignatureForError ());
1947 if (Kind == MemberKind.Interface && iface_exprs != null) {
1948 MemberCache.RemoveHiddenMembers (spec);
1954 void ComputeIndexerName ()
1956 var indexers = MemberCache.FindMembers (spec, MemberCache.IndexerNameAlias, true);
1957 if (indexers == null)
1960 string class_indexer_name = null;
1963 // Check normal indexers for consistent name, explicit interface implementation
1964 // indexers are ignored
1966 foreach (var indexer in indexers) {
1968 // FindMembers can return unfiltered full hierarchy names
1970 if (indexer.DeclaringType != spec)
1973 has_normal_indexers = true;
1975 if (class_indexer_name == null) {
1976 indexer_name = class_indexer_name = indexer.Name;
1980 if (indexer.Name != class_indexer_name)
1981 Report.Error (668, ((Indexer)indexer.MemberDefinition).Location,
1982 "Two indexers have different names; the IndexerName attribute must be used with the same name on every indexer within a type");
1986 void EmitIndexerName ()
1988 if (!has_normal_indexers)
1991 var ctor = Module.PredefinedMembers.DefaultMemberAttributeCtor.Get ();
1995 var encoder = new AttributeEncoder ();
1996 encoder.Encode (GetAttributeDefaultMember ());
1997 encoder.EncodeEmptyNamedArguments ();
1999 TypeBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray ());
2002 public override void VerifyMembers ()
2005 // Check for internal or private fields that were never assigned
2007 if (!IsCompilerGenerated && Compiler.Settings.WarningLevel >= 3 && this == PartialContainer) {
2008 bool is_type_exposed = Kind == MemberKind.Struct || IsExposedFromAssembly ();
2009 foreach (var member in members) {
2010 if (member is Event) {
2012 // An event can be assigned from same class only, so we can report
2013 // this warning for all accessibility modes
2016 Report.Warning (67, 3, member.Location, "The event `{0}' is never used", member.GetSignatureForError ());
2021 if ((member.ModFlags & Modifiers.AccessibilityMask) != Modifiers.PRIVATE) {
2022 if (is_type_exposed)
2025 member.SetIsUsed ();
2028 var f = member as Field;
2032 if (!member.IsUsed) {
2033 if ((member.caching_flags & Flags.IsAssigned) == 0) {
2034 Report.Warning (169, 3, member.Location, "The private field `{0}' is never used", member.GetSignatureForError ());
2036 Report.Warning (414, 3, member.Location, "The private field `{0}' is assigned but its value is never used",
2037 member.GetSignatureForError ());
2042 if ((f.caching_flags & Flags.IsAssigned) != 0)
2046 // Only report 649 on level 4
2048 if (Compiler.Settings.WarningLevel < 4)
2052 // Don't be pedantic when type requires specific layout
2054 if (f.OptAttributes != null || PartialContainer.HasStructLayout)
2057 Constant c = New.Constantify (f.MemberType, f.Location);
2060 value = c.GetValueAsLiteral ();
2061 } else if (TypeSpec.IsReferenceType (f.MemberType)) {
2068 value = " `" + value + "'";
2070 Report.Warning (649, 4, f.Location, "Field `{0}' is never assigned to, and will always have its default value{1}",
2071 f.GetSignatureForError (), value);
2075 base.VerifyMembers ();
2078 public override void Emit ()
2080 if (OptAttributes != null)
2081 OptAttributes.Emit ();
2083 if (!IsCompilerGenerated) {
2085 MemberSpec candidate;
2086 bool overrides = false;
2087 var conflict_symbol = MemberCache.FindBaseMember (this, out candidate, ref overrides);
2088 if (conflict_symbol == null && candidate == null) {
2089 if ((ModFlags & Modifiers.NEW) != 0)
2090 Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required",
2091 GetSignatureForError ());
2093 if ((ModFlags & Modifiers.NEW) == 0) {
2094 if (candidate == null)
2095 candidate = conflict_symbol;
2097 Report.SymbolRelatedToPreviousError (candidate);
2098 Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
2099 GetSignatureForError (), candidate.GetSignatureForError ());
2104 // Run constraints check on all possible generic types
2105 if (base_type != null && base_type_expr != null) {
2106 ConstraintChecker.Check (this, base_type, base_type_expr.Location);
2109 if (iface_exprs != null) {
2110 foreach (var iface_type in iface_exprs) {
2111 if (iface_type == null)
2114 ConstraintChecker.Check (this, iface_type, Location); // TODO: Location is wrong
2119 if (all_tp_builders != null) {
2120 int current_starts_index = CurrentTypeParametersStartIndex;
2121 for (int i = 0; i < all_tp_builders.Length; i++) {
2122 if (i < current_starts_index) {
2123 all_type_parameters[i].EmitConstraints (all_tp_builders [i]);
2125 var tp = CurrentTypeParameters [i - current_starts_index];
2126 tp.CheckGenericConstraints (!IsObsolete);
2132 if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0 && !Parent.IsCompilerGenerated)
2133 Module.PredefinedAttributes.CompilerGenerated.EmitAttribute (TypeBuilder);
2136 if ((TypeBuilder.Attributes & TypeAttributes.StringFormatMask) == 0 && Module.HasDefaultCharSet)
2137 TypeBuilder.__SetAttributes (TypeBuilder.Attributes | Module.DefaultCharSetType);
2142 for (int i = 0; i < members.Count; i++) {
2144 if ((m.caching_flags & Flags.CloseTypeCreated) != 0)
2151 CheckAttributeClsCompliance ();
2153 if (pending != null)
2154 pending.VerifyPendingMethods ();
2158 void CheckAttributeClsCompliance ()
2160 if (!spec.IsAttribute || !IsExposedFromAssembly () || !Compiler.Settings.VerifyClsCompliance || !IsClsComplianceRequired ())
2163 foreach (var m in members) {
2164 var c = m as Constructor;
2168 if (c.HasCompliantArgs)
2172 Report.Warning (3015, 1, Location, "`{0}' has no accessible constructors which use only CLS-compliant types", GetSignatureForError ());
2175 public sealed override void EmitContainer ()
2177 if ((caching_flags & Flags.CloseTypeCreated) != 0)
2183 public override void CloseContainer ()
2185 if ((caching_flags & Flags.CloseTypeCreated) != 0)
2188 // Close base type container first to avoid TypeLoadException
2189 if (spec.BaseType != null) {
2190 var btype = spec.BaseType.MemberDefinition as TypeContainer;
2191 if (btype != null) {
2192 btype.CloseContainer ();
2194 if ((caching_flags & Flags.CloseTypeCreated) != 0)
2200 caching_flags |= Flags.CloseTypeCreated;
2201 TypeBuilder.CreateType ();
2202 } catch (TypeLoadException) {
2204 // This is fine, the code still created the type
2206 } catch (Exception e) {
2207 throw new InternalErrorException (this, e);
2210 base.CloseContainer ();
2213 initialized_fields = null;
2214 initialized_static_fields = null;
2216 OptAttributes = null;
2220 // Performs the validation on a Method's modifiers (properties have
2221 // the same properties).
2223 // TODO: Why is it not done at parse stage, move to Modifiers::Check
2225 public bool MethodModifiersValid (MemberCore mc)
2227 const Modifiers vao = (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE);
2228 const Modifiers nv = (Modifiers.NEW | Modifiers.VIRTUAL);
2230 var flags = mc.ModFlags;
2233 // At most one of static, virtual or override
2235 if ((flags & Modifiers.STATIC) != 0){
2236 if ((flags & vao) != 0){
2237 Report.Error (112, mc.Location, "A static member `{0}' cannot be marked as override, virtual or abstract",
2238 mc.GetSignatureForError ());
2243 if ((flags & Modifiers.OVERRIDE) != 0 && (flags & nv) != 0){
2244 Report.Error (113, mc.Location, "A member `{0}' marked as override cannot be marked as new or virtual",
2245 mc.GetSignatureForError ());
2250 // If the declaration includes the abstract modifier, then the
2251 // declaration does not include static, virtual or extern
2253 if ((flags & Modifiers.ABSTRACT) != 0){
2254 if ((flags & Modifiers.EXTERN) != 0){
2256 180, mc.Location, "`{0}' cannot be both extern and abstract", mc.GetSignatureForError ());
2260 if ((flags & Modifiers.SEALED) != 0) {
2261 Report.Error (502, mc.Location, "`{0}' cannot be both abstract and sealed", mc.GetSignatureForError ());
2265 if ((flags & Modifiers.VIRTUAL) != 0){
2266 Report.Error (503, mc.Location, "The abstract method `{0}' cannot be marked virtual", mc.GetSignatureForError ());
2270 if ((ModFlags & Modifiers.ABSTRACT) == 0){
2271 Report.SymbolRelatedToPreviousError (this);
2272 Report.Error (513, mc.Location, "`{0}' is abstract but it is declared in the non-abstract class `{1}'",
2273 mc.GetSignatureForError (), GetSignatureForError ());
2278 if ((flags & Modifiers.PRIVATE) != 0){
2279 if ((flags & vao) != 0){
2280 Report.Error (621, mc.Location, "`{0}': virtual or abstract members cannot be private", mc.GetSignatureForError ());
2285 if ((flags & Modifiers.SEALED) != 0){
2286 if ((flags & Modifiers.OVERRIDE) == 0){
2287 Report.Error (238, mc.Location, "`{0}' cannot be sealed because it is not an override", mc.GetSignatureForError ());
2295 protected override bool VerifyClsCompliance ()
2297 if (!base.VerifyClsCompliance ())
2300 // Check all container names for user classes
2301 if (Kind != MemberKind.Delegate)
2302 MemberCache.VerifyClsCompliance (Definition, Report);
2304 if (BaseType != null && !BaseType.IsCLSCompliant ()) {
2305 Report.Warning (3009, 1, Location, "`{0}': base type `{1}' is not CLS-compliant",
2306 GetSignatureForError (), BaseType.GetSignatureForError ());
2312 /// Performs checks for an explicit interface implementation. First it
2313 /// checks whether the `interface_type' is a base inteface implementation.
2314 /// Then it checks whether `name' exists in the interface type.
2316 public bool VerifyImplements (InterfaceMemberBase mb)
2318 var ifaces = PartialContainer.Interfaces;
2319 if (ifaces != null) {
2320 foreach (TypeSpec t in ifaces){
2321 if (t == mb.InterfaceType)
2324 var expanded_base = t.Interfaces;
2325 if (expanded_base == null)
2328 foreach (var bt in expanded_base) {
2329 if (bt == mb.InterfaceType)
2335 Report.SymbolRelatedToPreviousError (mb.InterfaceType);
2336 Report.Error (540, mb.Location, "`{0}': containing type does not implement interface `{1}'",
2337 mb.GetSignatureForError (), mb.InterfaceType.GetSignatureForError ());
2342 // Used for visiblity checks to tests whether this definition shares
2343 // base type baseType, it does member-definition search
2345 public bool IsBaseTypeDefinition (TypeSpec baseType)
2347 // RootContext check
2348 if (TypeBuilder == null)
2353 if (type.MemberDefinition == baseType.MemberDefinition)
2356 type = type.BaseType;
2357 } while (type != null);
2362 public override bool IsClsComplianceRequired ()
2365 return PartialContainer.IsClsComplianceRequired ();
2367 return base.IsClsComplianceRequired ();
2370 bool ITypeDefinition.IsInternalAsPublic (IAssemblyDefinition assembly)
2372 return Module.DeclaringAssembly == assembly;
2375 public virtual bool IsUnmanagedType ()
2380 public void LoadMembers (TypeSpec declaringType, bool onlyTypes, ref MemberCache cache)
2382 throw new NotSupportedException ("Not supported for compiled definition " + GetSignatureForError ());
2386 // Public function used to locate types.
2388 // Returns: Type or null if they type can not be found.
2390 public override FullNamedExpression LookupNamespaceOrType (string name, int arity, LookupMode mode, Location loc)
2392 FullNamedExpression e;
2393 if (arity == 0 && Cache.TryGetValue (name, out e) && mode != LookupMode.IgnoreAccessibility)
2399 var tp = CurrentTypeParameters;
2401 TypeParameter tparam = tp.Find (name);
2403 e = new TypeParameterExpr (tparam, Location.Null);
2408 TypeSpec t = LookupNestedTypeInHierarchy (name, arity);
2410 if (t != null && (t.IsAccessible (this) || mode == LookupMode.IgnoreAccessibility))
2411 e = new TypeExpression (t, Location.Null);
2413 var errors = Compiler.Report.Errors;
2414 e = Parent.LookupNamespaceOrType (name, arity, mode, loc);
2416 // TODO: LookupNamespaceOrType does more than just lookup. The result
2417 // cannot be cached or the error reporting won't happen
2418 if (errors != Compiler.Report.Errors)
2423 // TODO MemberCache: How to cache arity stuff ?
2424 if (arity == 0 && mode == LookupMode.Normal)
2430 TypeSpec LookupNestedTypeInHierarchy (string name, int arity)
2432 // Has any nested type
2433 // Does not work, because base type can have
2434 //if (PartialContainer.Types == null)
2437 var container = PartialContainer.CurrentType;
2438 return MemberCache.FindNestedType (container, name, arity);
2441 public void Mark_HasEquals ()
2443 cached_method |= CachedMethods.Equals;
2446 public void Mark_HasGetHashCode ()
2448 cached_method |= CachedMethods.GetHashCode;
2451 public override void WriteDebugSymbol (MonoSymbolFile file)
2456 foreach (var m in members) {
2457 m.WriteDebugSymbol (file);
2462 /// Method container contains Equals method
2464 public bool HasEquals {
2466 return (cached_method & CachedMethods.Equals) != 0;
2471 /// Method container contains GetHashCode method
2473 public bool HasGetHashCode {
2475 return (cached_method & CachedMethods.GetHashCode) != 0;
2479 public bool HasStaticFieldInitializer {
2481 return (cached_method & CachedMethods.HasStaticFieldInitializer) != 0;
2485 cached_method |= CachedMethods.HasStaticFieldInitializer;
2487 cached_method &= ~CachedMethods.HasStaticFieldInitializer;
2491 public override string DocCommentHeader {
2492 get { return "T:"; }
2496 public abstract class ClassOrStruct : TypeDefinition
2498 public const TypeAttributes StaticClassAttribute = TypeAttributes.Abstract | TypeAttributes.Sealed;
2500 SecurityType declarative_security;
2502 protected ClassOrStruct (TypeContainer parent, MemberName name, Attributes attrs, MemberKind kind)
2503 : base (parent, name, attrs, kind)
2507 protected override TypeAttributes TypeAttr {
2509 TypeAttributes ta = base.TypeAttr;
2510 if (!has_static_constructor)
2511 ta |= TypeAttributes.BeforeFieldInit;
2513 if (Kind == MemberKind.Class) {
2514 ta |= TypeAttributes.AutoLayout | TypeAttributes.Class;
2516 ta |= StaticClassAttribute;
2518 ta |= TypeAttributes.SequentialLayout;
2525 public override void AddNameToContainer (MemberCore symbol, string name)
2527 if (!(symbol is Constructor) && symbol.MemberName.Name == MemberName.Name) {
2528 if (symbol is TypeParameter) {
2529 Report.Error (694, symbol.Location,
2530 "Type parameter `{0}' has same name as containing type, or method",
2531 symbol.GetSignatureForError ());
2535 InterfaceMemberBase imb = symbol as InterfaceMemberBase;
2536 if (imb == null || !imb.IsExplicitImpl) {
2537 Report.SymbolRelatedToPreviousError (this);
2538 Report.Error (542, symbol.Location, "`{0}': member names cannot be the same as their enclosing type",
2539 symbol.GetSignatureForError ());
2544 base.AddNameToContainer (symbol, name);
2547 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
2549 if (a.IsValidSecurityAttribute ()) {
2550 a.ExtractSecurityPermissionSet (ctor, ref declarative_security);
2554 if (a.Type == pa.StructLayout) {
2555 PartialContainer.HasStructLayout = true;
2556 if (a.IsExplicitLayoutKind ())
2557 PartialContainer.HasExplicitLayout = true;
2560 if (a.Type == pa.Dynamic) {
2561 a.Error_MisusedDynamicAttribute ();
2565 base.ApplyAttributeBuilder (a, ctor, cdata, pa);
2569 /// Defines the default constructors
2571 protected virtual Constructor DefineDefaultConstructor (bool is_static)
2573 // The default instance constructor is public
2574 // If the class is abstract, the default constructor is protected
2575 // The default static constructor is private
2579 mods = Modifiers.STATIC | Modifiers.PRIVATE;
2581 mods = ((ModFlags & Modifiers.ABSTRACT) != 0) ? Modifiers.PROTECTED : Modifiers.PUBLIC;
2584 var c = new Constructor (this, MemberName.Name, mods, null, ParametersCompiled.EmptyReadOnlyParameters, Location);
2585 c.Initializer = new GeneratedBaseInitializer (Location);
2587 AddConstructor (c, true);
2588 c.Block = new ToplevelBlock (Compiler, ParametersCompiled.EmptyReadOnlyParameters, Location) {
2589 IsCompilerGenerated = true
2595 protected override bool DoDefineMembers ()
2597 CheckProtectedModifier ();
2599 base.DoDefineMembers ();
2604 public override void Emit ()
2606 if (!has_static_constructor && HasStaticFieldInitializer) {
2607 var c = DefineDefaultConstructor (true);
2613 if (declarative_security != null) {
2614 foreach (var de in declarative_security) {
2616 TypeBuilder.__AddDeclarativeSecurity (de);
2618 TypeBuilder.AddDeclarativeSecurity (de.Key, de.Value);
2626 public sealed class Class : ClassOrStruct
2628 const Modifiers AllowedModifiers =
2631 Modifiers.PROTECTED |
2632 Modifiers.INTERNAL |
2634 Modifiers.ABSTRACT |
2639 public Class (TypeContainer parent, MemberName name, Modifiers mod, Attributes attrs)
2640 : base (parent, name, attrs, MemberKind.Class)
2642 var accmods = IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE;
2643 this.ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, accmods, Location, Report);
2644 spec = new TypeSpec (Kind, null, this, null, ModFlags);
2647 public override void Accept (StructuralVisitor visitor)
2649 visitor.Visit (this);
2652 public override void SetBaseTypes (List<FullNamedExpression> baseTypes)
2654 var pmn = MemberName;
2655 if (pmn.Name == "Object" && !pmn.IsGeneric && Parent.MemberName.Name == "System" && Parent.MemberName.Left == null)
2656 Report.Error (537, Location,
2657 "The class System.Object cannot have a base class or implement an interface.");
2659 base.SetBaseTypes (baseTypes);
2662 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
2664 if (a.Type == pa.AttributeUsage) {
2665 if (!BaseType.IsAttribute && spec.BuiltinType != BuiltinTypeSpec.Type.Attribute) {
2666 Report.Error (641, a.Location, "Attribute `{0}' is only valid on classes derived from System.Attribute", a.GetSignatureForError ());
2670 if (a.Type == pa.Conditional && !BaseType.IsAttribute) {
2671 Report.Error (1689, a.Location, "Attribute `System.Diagnostics.ConditionalAttribute' is only valid on methods or attribute classes");
2675 if (a.Type == pa.ComImport && !attributes.Contains (pa.Guid)) {
2676 a.Error_MissingGuidAttribute ();
2680 if (a.Type == pa.Extension) {
2681 a.Error_MisusedExtensionAttribute ();
2685 if (a.Type.IsConditionallyExcluded (this))
2688 base.ApplyAttributeBuilder (a, ctor, cdata, pa);
2691 public override AttributeTargets AttributeTargets {
2693 return AttributeTargets.Class;
2697 protected override bool DoDefineMembers ()
2699 if ((ModFlags & Modifiers.ABSTRACT) == Modifiers.ABSTRACT && (ModFlags & (Modifiers.SEALED | Modifiers.STATIC)) != 0) {
2700 Report.Error (418, Location, "`{0}': an abstract class cannot be sealed or static", GetSignatureForError ());
2703 if ((ModFlags & (Modifiers.SEALED | Modifiers.STATIC)) == (Modifiers.SEALED | Modifiers.STATIC)) {
2704 Report.Error (441, Location, "`{0}': a class cannot be both static and sealed", GetSignatureForError ());
2708 foreach (var m in Members) {
2709 if (m is Operator) {
2710 Report.Error (715, m.Location, "`{0}': Static classes cannot contain user-defined operators", m.GetSignatureForError ());
2714 if (m is Destructor) {
2715 Report.Error (711, m.Location, "`{0}': Static classes cannot contain destructor", GetSignatureForError ());
2720 Report.Error (720, m.Location, "`{0}': cannot declare indexers in a static class", m.GetSignatureForError ());
2724 if ((m.ModFlags & Modifiers.STATIC) != 0 || m is TypeContainer)
2727 if (m is Constructor) {
2728 Report.Error (710, m.Location, "`{0}': Static classes cannot have instance constructors", GetSignatureForError ());
2732 Report.Error (708, m.Location, "`{0}': cannot declare instance members in a static class", m.GetSignatureForError ());
2735 if (!PartialContainer.HasInstanceConstructor)
2736 DefineDefaultConstructor (false);
2739 return base.DoDefineMembers ();
2742 public override void Emit ()
2746 if ((ModFlags & Modifiers.METHOD_EXTENSION) != 0)
2747 Module.PredefinedAttributes.Extension.EmitAttribute (TypeBuilder);
2749 if (base_type != null && base_type.HasDynamicElement) {
2750 Module.PredefinedAttributes.Dynamic.EmitAttribute (TypeBuilder, base_type, Location);
2754 protected override TypeSpec[] ResolveBaseTypes (out FullNamedExpression base_class)
2756 var ifaces = base.ResolveBaseTypes (out base_class);
2758 if (base_class == null) {
2759 if (spec.BuiltinType != BuiltinTypeSpec.Type.Object)
2760 base_type = Compiler.BuiltinTypes.Object;
2762 if (base_type.IsGenericParameter){
2763 Report.Error (689, base_class.Location, "`{0}': Cannot derive from type parameter `{1}'",
2764 GetSignatureForError (), base_type.GetSignatureForError ());
2765 } else if (base_type.IsStatic) {
2766 Report.SymbolRelatedToPreviousError (base_type);
2767 Report.Error (709, Location, "`{0}': Cannot derive from static class `{1}'",
2768 GetSignatureForError (), base_type.GetSignatureForError ());
2769 } else if (base_type.IsSealed) {
2770 Report.SymbolRelatedToPreviousError (base_type);
2771 Report.Error (509, Location, "`{0}': cannot derive from sealed type `{1}'",
2772 GetSignatureForError (), base_type.GetSignatureForError ());
2773 } else if (PartialContainer.IsStatic && base_type.BuiltinType != BuiltinTypeSpec.Type.Object) {
2774 Report.Error (713, Location, "Static class `{0}' cannot derive from type `{1}'. Static classes must derive from object",
2775 GetSignatureForError (), base_type.GetSignatureForError ());
2778 switch (base_type.BuiltinType) {
2779 case BuiltinTypeSpec.Type.Enum:
2780 case BuiltinTypeSpec.Type.ValueType:
2781 case BuiltinTypeSpec.Type.MulticastDelegate:
2782 case BuiltinTypeSpec.Type.Delegate:
2783 case BuiltinTypeSpec.Type.Array:
2784 if (!(spec is BuiltinTypeSpec)) {
2785 Report.Error (644, Location, "`{0}' cannot derive from special class `{1}'",
2786 GetSignatureForError (), base_type.GetSignatureForError ());
2788 base_type = Compiler.BuiltinTypes.Object;
2793 if (!IsAccessibleAs (base_type)) {
2794 Report.SymbolRelatedToPreviousError (base_type);
2795 Report.Error (60, Location, "Inconsistent accessibility: base class `{0}' is less accessible than class `{1}'",
2796 base_type.GetSignatureForError (), GetSignatureForError ());
2800 if (PartialContainer.IsStatic && ifaces != null) {
2801 foreach (var t in ifaces)
2802 Report.SymbolRelatedToPreviousError (t);
2803 Report.Error (714, Location, "Static class `{0}' cannot implement interfaces", GetSignatureForError ());
2809 /// Search for at least one defined condition in ConditionalAttribute of attribute class
2810 /// Valid only for attribute classes.
2811 public override string[] ConditionalConditions ()
2813 if ((caching_flags & (Flags.Excluded_Undetected | Flags.Excluded)) == 0)
2816 caching_flags &= ~Flags.Excluded_Undetected;
2818 if (OptAttributes == null)
2821 Attribute[] attrs = OptAttributes.SearchMulti (Module.PredefinedAttributes.Conditional);
2825 string[] conditions = new string[attrs.Length];
2826 for (int i = 0; i < conditions.Length; ++i)
2827 conditions[i] = attrs[i].GetConditionalAttributeValue ();
2829 caching_flags |= Flags.Excluded;
2834 public sealed class Struct : ClassOrStruct
2836 bool is_unmanaged, has_unmanaged_check_done;
2840 // Modifiers allowed in a struct declaration
2842 const Modifiers AllowedModifiers =
2845 Modifiers.PROTECTED |
2846 Modifiers.INTERNAL |
2850 public Struct (TypeContainer parent, MemberName name, Modifiers mod, Attributes attrs)
2851 : base (parent, name, attrs, MemberKind.Struct)
2853 var accmods = IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE;
2854 this.ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, accmods, Location, Report) | Modifiers.SEALED ;
2855 spec = new TypeSpec (Kind, null, this, null, ModFlags);
2858 public override AttributeTargets AttributeTargets {
2860 return AttributeTargets.Struct;
2864 public override void Accept (StructuralVisitor visitor)
2866 visitor.Visit (this);
2869 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
2871 base.ApplyAttributeBuilder (a, ctor, cdata, pa);
2874 // When struct constains fixed fixed and struct layout has explicitly
2875 // set CharSet, its value has to be propagated to compiler generated
2878 if (a.Type == pa.StructLayout) {
2879 var value = a.GetNamedValue ("CharSet");
2883 for (int i = 0; i < Members.Count; ++i) {
2884 FixedField ff = Members [i] as FixedField;
2888 ff.CharSet = (CharSet) System.Enum.Parse (typeof (CharSet), value.GetValue ().ToString ());
2893 bool CheckStructCycles ()
2899 foreach (var member in Members) {
2900 var field = member as Field;
2904 TypeSpec ftype = field.Spec.MemberType;
2905 if (!ftype.IsStruct)
2908 if (ftype is BuiltinTypeSpec)
2911 foreach (var targ in ftype.TypeArguments) {
2912 if (!CheckFieldTypeCycle (targ)) {
2913 Report.Error (523, field.Location,
2914 "Struct member `{0}' of type `{1}' causes a cycle in the struct layout",
2915 field.GetSignatureForError (), ftype.GetSignatureForError ());
2921 // Static fields of exactly same type are allowed
2923 if (field.IsStatic && ftype == CurrentType)
2926 if (!CheckFieldTypeCycle (ftype)) {
2927 Report.Error (523, field.Location,
2928 "Struct member `{0}' of type `{1}' causes a cycle in the struct layout",
2929 field.GetSignatureForError (), ftype.GetSignatureForError ());
2938 static bool CheckFieldTypeCycle (TypeSpec ts)
2940 var fts = ts.MemberDefinition as Struct;
2944 return fts.CheckStructCycles ();
2947 public override void Emit ()
2949 CheckStructCycles ();
2954 public override bool IsUnmanagedType ()
2956 if (has_unmanaged_check_done)
2957 return is_unmanaged;
2959 if (requires_delayed_unmanagedtype_check)
2962 var parent_def = Parent.PartialContainer;
2963 if (parent_def != null && parent_def.IsGenericOrParentIsGeneric) {
2964 has_unmanaged_check_done = true;
2968 if (first_nonstatic_field != null) {
2969 requires_delayed_unmanagedtype_check = true;
2971 foreach (var member in Members) {
2972 var f = member as Field;
2979 // It can happen when recursive unmanaged types are defined
2980 // struct S { S* s; }
2981 TypeSpec mt = f.MemberType;
2989 has_unmanaged_check_done = true;
2993 has_unmanaged_check_done = true;
2996 is_unmanaged = true;
3000 protected override TypeSpec[] ResolveBaseTypes (out FullNamedExpression base_class)
3002 var ifaces = base.ResolveBaseTypes (out base_class);
3003 base_type = Compiler.BuiltinTypes.ValueType;
3007 public override void RegisterFieldForInitialization (MemberCore field, FieldInitializer expression)
3009 if ((field.ModFlags & Modifiers.STATIC) == 0) {
3010 Report.Error (573, field.Location, "`{0}': Structs cannot have instance field initializers",
3011 field.GetSignatureForError ());
3014 base.RegisterFieldForInitialization (field, expression);
3022 public sealed class Interface : TypeDefinition {
3025 /// Modifiers allowed in a class declaration
3027 const Modifiers AllowedModifiers =
3030 Modifiers.PROTECTED |
3031 Modifiers.INTERNAL |
3035 public Interface (TypeContainer parent, MemberName name, Modifiers mod, Attributes attrs)
3036 : base (parent, name, attrs, MemberKind.Interface)
3038 var accmods = IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE;
3040 this.ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, accmods, name.Location, Report);
3041 spec = new TypeSpec (Kind, null, this, null, ModFlags);
3046 public override AttributeTargets AttributeTargets {
3048 return AttributeTargets.Interface;
3052 protected override TypeAttributes TypeAttr {
3054 const TypeAttributes DefaultTypeAttributes =
3055 TypeAttributes.AutoLayout |
3056 TypeAttributes.Abstract |
3057 TypeAttributes.Interface;
3059 return base.TypeAttr | DefaultTypeAttributes;
3065 public override void Accept (StructuralVisitor visitor)
3067 visitor.Visit (this);
3070 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
3072 if (a.Type == pa.ComImport && !attributes.Contains (pa.Guid)) {
3073 a.Error_MissingGuidAttribute ();
3077 base.ApplyAttributeBuilder (a, ctor, cdata, pa);
3080 protected override bool VerifyClsCompliance ()
3082 if (!base.VerifyClsCompliance ())
3085 if (iface_exprs != null) {
3086 foreach (var iface in iface_exprs) {
3087 if (iface.IsCLSCompliant ())
3090 Report.SymbolRelatedToPreviousError (iface);
3091 Report.Warning (3027, 1, Location, "`{0}' is not CLS-compliant because base interface `{1}' is not CLS-compliant",
3092 GetSignatureForError (), iface.GetSignatureForError ());
3100 public abstract class InterfaceMemberBase : MemberBase
3103 // Common modifiers allowed in a class declaration
3105 protected const Modifiers AllowedModifiersClass =
3108 Modifiers.PROTECTED |
3109 Modifiers.INTERNAL |
3114 Modifiers.OVERRIDE |
3115 Modifiers.ABSTRACT |
3120 // Common modifiers allowed in a struct declaration
3122 protected const Modifiers AllowedModifiersStruct =
3125 Modifiers.PROTECTED |
3126 Modifiers.INTERNAL |
3129 Modifiers.OVERRIDE |
3134 // Common modifiers allowed in a interface declaration
3136 protected const Modifiers AllowedModifiersInterface =
3141 // Whether this is an interface member.
3143 public bool IsInterface;
3146 // If true, this is an explicit interface implementation
3148 public readonly bool IsExplicitImpl;
3150 protected bool is_external_implementation;
3153 // The interface type we are explicitly implementing
3155 public TypeSpec InterfaceType;
3158 // The method we're overriding if this is an override method.
3160 protected MethodSpec base_method;
3162 readonly Modifiers explicit_mod_flags;
3163 public MethodAttributes flags;
3165 protected InterfaceMemberBase (TypeDefinition parent, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, MemberName name, Attributes attrs)
3166 : base (parent, type, mod, allowed_mod, Modifiers.PRIVATE, name, attrs)
3168 IsInterface = parent.Kind == MemberKind.Interface;
3169 IsExplicitImpl = (MemberName.ExplicitInterface != null);
3170 explicit_mod_flags = mod;
3173 public abstract Variance ExpectedMemberTypeVariance { get; }
3175 protected override bool CheckBase ()
3177 if (!base.CheckBase ())
3180 if ((caching_flags & Flags.MethodOverloadsExist) != 0)
3181 CheckForDuplications ();
3186 // For System.Object only
3187 if (Parent.BaseType == null)
3190 MemberSpec candidate;
3191 bool overrides = false;
3192 var base_member = FindBaseMember (out candidate, ref overrides);
3194 if ((ModFlags & Modifiers.OVERRIDE) != 0) {
3195 if (base_member == null) {
3196 if (candidate == null) {
3197 if (this is Method && ((Method)this).ParameterInfo.IsEmpty && MemberName.Name == Destructor.MetadataName && MemberName.Arity == 0) {
3198 Report.Error (249, Location, "Do not override `{0}'. Use destructor syntax instead",
3199 "object.Finalize()");
3201 Report.Error (115, Location, "`{0}' is marked as an override but no suitable {1} found to override",
3202 GetSignatureForError (), SimpleName.GetMemberType (this));
3205 Report.SymbolRelatedToPreviousError (candidate);
3207 Report.Error (72, Location, "`{0}': cannot override because `{1}' is not an event",
3208 GetSignatureForError (), TypeManager.GetFullNameSignature (candidate));
3209 else if (this is PropertyBase)
3210 Report.Error (544, Location, "`{0}': cannot override because `{1}' is not a property",
3211 GetSignatureForError (), TypeManager.GetFullNameSignature (candidate));
3213 Report.Error (505, Location, "`{0}': cannot override because `{1}' is not a method",
3214 GetSignatureForError (), TypeManager.GetFullNameSignature (candidate));
3221 // Handles ambiguous overrides
3223 if (candidate != null) {
3224 Report.SymbolRelatedToPreviousError (candidate);
3225 Report.SymbolRelatedToPreviousError (base_member);
3227 // Get member definition for error reporting
3228 var m1 = MemberCache.GetMember (base_member.DeclaringType.GetDefinition (), base_member);
3229 var m2 = MemberCache.GetMember (candidate.DeclaringType.GetDefinition (), candidate);
3231 Report.Error (462, Location,
3232 "`{0}' cannot override inherited members `{1}' and `{2}' because they have the same signature when used in type `{3}'",
3233 GetSignatureForError (), m1.GetSignatureForError (), m2.GetSignatureForError (), Parent.GetSignatureForError ());
3236 if (!CheckOverrideAgainstBase (base_member))
3239 ObsoleteAttribute oa = base_member.GetAttributeObsolete ();
3241 if (OptAttributes == null || !OptAttributes.Contains (Module.PredefinedAttributes.Obsolete)) {
3242 Report.SymbolRelatedToPreviousError (base_member);
3243 Report.Warning (672, 1, Location, "Member `{0}' overrides obsolete member `{1}'. Add the Obsolete attribute to `{0}'",
3244 GetSignatureForError (), base_member.GetSignatureForError ());
3247 if (OptAttributes != null && OptAttributes.Contains (Module.PredefinedAttributes.Obsolete)) {
3248 Report.SymbolRelatedToPreviousError (base_member);
3249 Report.Warning (809, 1, Location, "Obsolete member `{0}' overrides non-obsolete member `{1}'",
3250 GetSignatureForError (), base_member.GetSignatureForError ());
3254 base_method = base_member as MethodSpec;
3258 if (base_member == null && candidate != null && (!(candidate is IParametersMember) || !(this is IParametersMember)))
3259 base_member = candidate;
3261 if (base_member == null) {
3262 if ((ModFlags & Modifiers.NEW) != 0) {
3263 if (base_member == null) {
3264 Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required",
3265 GetSignatureForError ());
3269 if ((ModFlags & Modifiers.NEW) == 0) {
3270 ModFlags |= Modifiers.NEW;
3271 if (!IsCompilerGenerated) {
3272 Report.SymbolRelatedToPreviousError (base_member);
3273 if (!IsInterface && (base_member.Modifiers & (Modifiers.ABSTRACT | Modifiers.VIRTUAL | Modifiers.OVERRIDE)) != 0) {
3274 Report.Warning (114, 2, Location, "`{0}' hides inherited member `{1}'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword",
3275 GetSignatureForError (), base_member.GetSignatureForError ());
3277 Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
3278 GetSignatureForError (), base_member.GetSignatureForError ());
3283 if (!IsInterface && base_member.IsAbstract && !overrides && !IsStatic) {
3284 Report.SymbolRelatedToPreviousError (base_member);
3285 Report.Error (533, Location, "`{0}' hides inherited abstract member `{1}'",
3286 GetSignatureForError (), base_member.GetSignatureForError ());
3293 protected virtual bool CheckForDuplications ()
3295 return Parent.MemberCache.CheckExistingMembersOverloads (this, ParametersCompiled.EmptyReadOnlyParameters);
3299 // Performs various checks on the MethodInfo `mb' regarding the modifier flags
3300 // that have been defined.
3302 protected virtual bool CheckOverrideAgainstBase (MemberSpec base_member)
3306 if ((base_member.Modifiers & (Modifiers.ABSTRACT | Modifiers.VIRTUAL | Modifiers.OVERRIDE)) == 0) {
3307 Report.SymbolRelatedToPreviousError (base_member);
3308 Report.Error (506, Location,
3309 "`{0}': cannot override inherited member `{1}' because it is not marked virtual, abstract or override",
3310 GetSignatureForError (), TypeManager.CSharpSignature (base_member));
3314 // Now we check that the overriden method is not final
3315 if ((base_member.Modifiers & Modifiers.SEALED) != 0) {
3316 Report.SymbolRelatedToPreviousError (base_member);
3317 Report.Error (239, Location, "`{0}': cannot override inherited member `{1}' because it is sealed",
3318 GetSignatureForError (), TypeManager.CSharpSignature (base_member));
3322 var base_member_type = ((IInterfaceMemberSpec) base_member).MemberType;
3323 if (!TypeSpecComparer.Override.IsEqual (MemberType, base_member_type)) {
3324 Report.SymbolRelatedToPreviousError (base_member);
3325 if (this is PropertyBasedMember) {
3326 Report.Error (1715, Location, "`{0}': type must be `{1}' to match overridden member `{2}'",
3327 GetSignatureForError (), base_member_type.GetSignatureForError (), base_member.GetSignatureForError ());
3329 Report.Error (508, Location, "`{0}': return type must be `{1}' to match overridden member `{2}'",
3330 GetSignatureForError (), base_member_type.GetSignatureForError (), base_member.GetSignatureForError ());
3338 protected static bool CheckAccessModifiers (MemberCore this_member, MemberSpec base_member)
3340 var thisp = this_member.ModFlags & Modifiers.AccessibilityMask;
3341 var base_classp = base_member.Modifiers & Modifiers.AccessibilityMask;
3343 if ((base_classp & (Modifiers.PROTECTED | Modifiers.INTERNAL)) == (Modifiers.PROTECTED | Modifiers.INTERNAL)) {
3345 // It must be at least "protected"
3347 if ((thisp & Modifiers.PROTECTED) == 0) {
3352 // when overriding protected internal, the method can be declared
3353 // protected internal only within the same assembly or assembly
3354 // which has InternalsVisibleTo
3356 if ((thisp & Modifiers.INTERNAL) != 0) {
3357 return base_member.DeclaringType.MemberDefinition.IsInternalAsPublic (this_member.Module.DeclaringAssembly);
3361 // protected overriding protected internal inside same assembly
3362 // requires internal modifier as well
3364 if (base_member.DeclaringType.MemberDefinition.IsInternalAsPublic (this_member.Module.DeclaringAssembly)) {
3371 return thisp == base_classp;
3374 public override bool Define ()
3377 ModFlags = Modifiers.PUBLIC | Modifiers.ABSTRACT |
3378 Modifiers.VIRTUAL | (ModFlags & (Modifiers.UNSAFE | Modifiers.NEW));
3380 flags = MethodAttributes.Public |
3381 MethodAttributes.Abstract |
3382 MethodAttributes.HideBySig |
3383 MethodAttributes.NewSlot |
3384 MethodAttributes.Virtual;
3386 Parent.PartialContainer.MethodModifiersValid (this);
3388 flags = ModifiersExtensions.MethodAttr (ModFlags);
3391 if (IsExplicitImpl) {
3392 InterfaceType = MemberName.ExplicitInterface.ResolveAsType (Parent);
3393 if (InterfaceType == null)
3396 if ((ModFlags & Modifiers.PARTIAL) != 0) {
3397 Report.Error (754, Location, "A partial method `{0}' cannot explicitly implement an interface",
3398 GetSignatureForError ());
3401 if (!InterfaceType.IsInterface) {
3402 Report.SymbolRelatedToPreviousError (InterfaceType);
3403 Report.Error (538, Location, "The type `{0}' in explicit interface declaration is not an interface",
3404 InterfaceType.GetSignatureForError ());
3406 Parent.PartialContainer.VerifyImplements (this);
3409 Modifiers allowed_explicit = Modifiers.AllowedExplicitImplFlags;
3411 allowed_explicit |= Modifiers.ASYNC;
3413 ModifiersExtensions.Check (allowed_explicit, explicit_mod_flags, 0, Location, Report);
3416 return base.Define ();
3419 protected bool DefineParameters (ParametersCompiled parameters)
3421 if (!parameters.Resolve (this))
3425 for (int i = 0; i < parameters.Count; ++i) {
3426 Parameter p = parameters [i];
3428 if (p.HasDefaultValue && (IsExplicitImpl || this is Operator || (this is Indexer && parameters.Count == 1)))
3429 p.Warning_UselessOptionalParameter (Report);
3431 if (p.CheckAccessibility (this))
3434 TypeSpec t = parameters.Types [i];
3435 Report.SymbolRelatedToPreviousError (t);
3436 if (this is Indexer)
3437 Report.Error (55, Location,
3438 "Inconsistent accessibility: parameter type `{0}' is less accessible than indexer `{1}'",
3439 t.GetSignatureForError (), GetSignatureForError ());
3440 else if (this is Operator)
3441 Report.Error (57, Location,
3442 "Inconsistent accessibility: parameter type `{0}' is less accessible than operator `{1}'",
3443 t.GetSignatureForError (), GetSignatureForError ());
3445 Report.Error (51, Location,
3446 "Inconsistent accessibility: parameter type `{0}' is less accessible than method `{1}'",
3447 t.GetSignatureForError (), GetSignatureForError ());
3453 protected override void DoMemberTypeDependentChecks ()
3455 base.DoMemberTypeDependentChecks ();
3457 VarianceDecl.CheckTypeVariance (MemberType, ExpectedMemberTypeVariance, this);
3460 public override void Emit()
3462 // for extern static method must be specified either DllImport attribute or MethodImplAttribute.
3463 // We are more strict than csc and report this as an error because SRE does not allow emit that
3464 if ((ModFlags & Modifiers.EXTERN) != 0 && !is_external_implementation && (OptAttributes == null || !OptAttributes.HasResolveError ())) {
3465 if (this is Constructor) {
3466 Report.Warning (824, 1, Location,
3467 "Constructor `{0}' is marked `external' but has no external implementation specified", GetSignatureForError ());
3469 Report.Warning (626, 1, Location,
3470 "`{0}' is marked as an external but has no DllImport attribute. Consider adding a DllImport attribute to specify the external implementation",
3471 GetSignatureForError ());
3478 public override bool EnableOverloadChecks (MemberCore overload)
3481 // Two members can differ in their explicit interface
3482 // type parameter only
3484 InterfaceMemberBase imb = overload as InterfaceMemberBase;
3485 if (imb != null && imb.IsExplicitImpl) {
3486 if (IsExplicitImpl) {
3487 caching_flags |= Flags.MethodOverloadsExist;
3492 return IsExplicitImpl;
3495 protected void Error_CannotChangeAccessModifiers (MemberCore member, MemberSpec base_member)
3497 var base_modifiers = base_member.Modifiers;
3499 // Remove internal modifier from types which are not internally accessible
3500 if ((base_modifiers & Modifiers.AccessibilityMask) == (Modifiers.PROTECTED | Modifiers.INTERNAL) &&
3501 !base_member.DeclaringType.MemberDefinition.IsInternalAsPublic (member.Module.DeclaringAssembly))
3502 base_modifiers = Modifiers.PROTECTED;
3504 Report.SymbolRelatedToPreviousError (base_member);
3505 Report.Error (507, member.Location,
3506 "`{0}': cannot change access modifiers when overriding `{1}' inherited member `{2}'",
3507 member.GetSignatureForError (),
3508 ModifiersExtensions.AccessibilityName (base_modifiers),
3509 base_member.GetSignatureForError ());
3512 protected void Error_StaticReturnType ()
3514 Report.Error (722, Location,
3515 "`{0}': static types cannot be used as return types",
3516 MemberType.GetSignatureForError ());
3520 /// Gets base method and its return type
3522 protected virtual MemberSpec FindBaseMember (out MemberSpec bestCandidate, ref bool overrides)
3524 return MemberCache.FindBaseMember (this, out bestCandidate, ref overrides);
3528 // The "short" name of this property / indexer / event. This is the
3529 // name without the explicit interface.
3531 public string ShortName {
3532 get { return MemberName.Name; }
3536 // Returns full metadata method name
3538 public string GetFullName (MemberName name)
3540 return GetFullName (name.Name);
3543 public string GetFullName (string name)
3545 if (!IsExplicitImpl)
3549 // When dealing with explicit members a full interface type
3550 // name is added to member name to avoid possible name conflicts
3552 // We use CSharpName which gets us full name with benefit of
3553 // replacing predefined names which saves some space and name
3556 return InterfaceType.GetSignatureForError () + "." + name;
3559 public override string GetSignatureForDocumentation ()
3562 return Parent.GetSignatureForDocumentation () + "." + InterfaceType.GetExplicitNameSignatureForDocumentation () + "#" + ShortName;
3564 return Parent.GetSignatureForDocumentation () + "." + ShortName;
3567 public override bool IsUsed
3569 get { return IsExplicitImpl || base.IsUsed; }
3572 public override void SetConstraints (List<Constraints> constraints_list)
3574 if (((ModFlags & Modifiers.OVERRIDE) != 0 || IsExplicitImpl)) {
3575 Report.Error (460, Location,
3576 "`{0}': Cannot specify constraints for overrides and explicit interface implementation methods",
3577 GetSignatureForError ());
3580 base.SetConstraints (constraints_list);
3584 public abstract class MemberBase : MemberCore
3586 protected FullNamedExpression type_expr;
3587 protected TypeSpec member_type;
3588 public new TypeDefinition Parent;
3590 protected MemberBase (TypeDefinition parent, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, Modifiers def_mod, MemberName name, Attributes attrs)
3591 : base (parent, name, attrs)
3593 this.Parent = parent;
3594 this.type_expr = type;
3596 if (name != MemberName.Null)
3597 ModFlags = ModifiersExtensions.Check (allowed_mod, mod, def_mod, Location, Report);
3602 public TypeSpec MemberType {
3608 public FullNamedExpression TypeExpression {
3617 // Main member define entry
3619 public override bool Define ()
3621 DoMemberTypeIndependentChecks ();
3624 // Returns false only when type resolution failed
3626 if (!ResolveMemberType ())
3629 DoMemberTypeDependentChecks ();
3634 // Any type_name independent checks
3636 protected virtual void DoMemberTypeIndependentChecks ()
3638 if ((Parent.ModFlags & Modifiers.SEALED) != 0 &&
3639 (ModFlags & (Modifiers.VIRTUAL | Modifiers.ABSTRACT)) != 0) {
3640 Report.Error (549, Location, "New virtual member `{0}' is declared in a sealed class `{1}'",
3641 GetSignatureForError (), Parent.GetSignatureForError ());
3646 // Any type_name dependent checks
3648 protected virtual void DoMemberTypeDependentChecks ()
3650 // verify accessibility
3651 if (!IsAccessibleAs (MemberType)) {
3652 Report.SymbolRelatedToPreviousError (MemberType);
3653 if (this is Property)
3654 Report.Error (53, Location,
3655 "Inconsistent accessibility: property type `" +
3656 MemberType.GetSignatureForError () + "' is less " +
3657 "accessible than property `" + GetSignatureForError () + "'");
3658 else if (this is Indexer)
3659 Report.Error (54, Location,
3660 "Inconsistent accessibility: indexer return type `" +
3661 MemberType.GetSignatureForError () + "' is less " +
3662 "accessible than indexer `" + GetSignatureForError () + "'");
3663 else if (this is MethodCore) {
3664 if (this is Operator)
3665 Report.Error (56, Location,
3666 "Inconsistent accessibility: return type `" +
3667 MemberType.GetSignatureForError () + "' is less " +
3668 "accessible than operator `" + GetSignatureForError () + "'");
3670 Report.Error (50, Location,
3671 "Inconsistent accessibility: return type `" +
3672 MemberType.GetSignatureForError () + "' is less " +
3673 "accessible than method `" + GetSignatureForError () + "'");
3675 Report.Error (52, Location,
3676 "Inconsistent accessibility: field type `" +
3677 MemberType.GetSignatureForError () + "' is less " +
3678 "accessible than field `" + GetSignatureForError () + "'");
3683 protected void IsTypePermitted ()
3685 if (MemberType.IsSpecialRuntimeType) {
3686 if (Parent is StateMachine) {
3687 Report.Error (4012, Location,
3688 "Parameters or local variables of type `{0}' cannot be declared in async methods or iterators",
3689 MemberType.GetSignatureForError ());
3690 } else if (Parent is HoistedStoreyClass) {
3691 Report.Error (4013, Location,
3692 "Local variables of type `{0}' cannot be used inside anonymous methods, lambda expressions or query expressions",
3693 MemberType.GetSignatureForError ());
3695 Report.Error (610, Location,
3696 "Field or property cannot be of type `{0}'", MemberType.GetSignatureForError ());
3701 protected virtual bool CheckBase ()
3703 CheckProtectedModifier ();
3708 public override string GetSignatureForDocumentation ()
3710 return Parent.GetSignatureForDocumentation () + "." + MemberName.Basename;
3713 protected virtual bool ResolveMemberType ()
3715 if (member_type != null)
3716 throw new InternalErrorException ("Multi-resolve");
3718 member_type = type_expr.ResolveAsType (this);
3719 return member_type != null;