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 {
696 // Returns true for secondary partial containers
700 return PartialContainer != this;
704 public MemberCache MemberCache {
706 return spec.MemberCache;
710 public List<MemberCore> Members {
716 string ITypeDefinition.Namespace {
719 while (p.Kind != MemberKind.Namespace)
722 return p.MemberName == null ? null : p.GetSignatureForError ();
726 public TypeParameters TypeParametersAll {
728 return all_type_parameters;
732 public override string[] ValidAttributeTargets {
734 return attribute_targets;
740 public override void Accept (StructuralVisitor visitor)
742 visitor.Visit (this);
745 public void AddMember (MemberCore symbol)
747 if (symbol.MemberName.ExplicitInterface != null) {
748 if (!(Kind == MemberKind.Class || Kind == MemberKind.Struct)) {
749 Report.Error (541, symbol.Location,
750 "`{0}': explicit interface declaration can only be declared in a class or struct",
751 symbol.GetSignatureForError ());
755 AddNameToContainer (symbol, symbol.MemberName.Name);
756 members.Add (symbol);
759 public override void AddTypeContainer (TypeContainer tc)
761 AddNameToContainer (tc, tc.Basename);
763 base.AddTypeContainer (tc);
766 protected override void AddTypeContainerMember (TypeContainer tc)
770 if (containers == null)
771 containers = new List<TypeContainer> ();
773 base.AddTypeContainerMember (tc);
777 // Adds the member to defined_names table. It tests for duplications and enclosing name conflicts
779 public virtual void AddNameToContainer (MemberCore symbol, string name)
781 if (((ModFlags | symbol.ModFlags) & Modifiers.COMPILER_GENERATED) != 0)
785 if (!PartialContainer.defined_names.TryGetValue (name, out mc)) {
786 PartialContainer.defined_names.Add (name, symbol);
790 if (symbol.EnableOverloadChecks (mc))
793 InterfaceMemberBase im = mc as InterfaceMemberBase;
794 if (im != null && im.IsExplicitImpl)
797 Report.SymbolRelatedToPreviousError (mc);
798 if ((mc.ModFlags & Modifiers.PARTIAL) != 0 && (symbol is ClassOrStruct || symbol is Interface)) {
799 Error_MissingPartialModifier (symbol);
803 if (symbol is TypeParameter) {
804 Report.Error (692, symbol.Location,
805 "Duplicate type parameter `{0}'", symbol.GetSignatureForError ());
807 Report.Error (102, symbol.Location,
808 "The type `{0}' already contains a definition for `{1}'",
809 GetSignatureForError (), name);
815 public void AddConstructor (Constructor c)
817 AddConstructor (c, false);
820 public void AddConstructor (Constructor c, bool isDefault)
822 bool is_static = (c.ModFlags & Modifiers.STATIC) != 0;
824 AddNameToContainer (c, is_static ? Constructor.TypeConstructorName : Constructor.ConstructorName);
826 if (is_static && c.ParameterInfo.IsEmpty) {
827 PartialContainer.has_static_constructor = true;
829 PartialContainer.HasInstanceConstructor = true;
835 public bool AddField (FieldBase field)
839 if ((field.ModFlags & Modifiers.STATIC) != 0)
842 var first_field = PartialContainer.first_nonstatic_field;
843 if (first_field == null) {
844 PartialContainer.first_nonstatic_field = field;
848 if (Kind == MemberKind.Struct && first_field.Parent != field.Parent) {
849 Report.SymbolRelatedToPreviousError (first_field.Parent);
850 Report.Warning (282, 3, field.Location,
851 "struct instance field `{0}' found in different declaration from instance field `{1}'",
852 field.GetSignatureForError (), first_field.GetSignatureForError ());
858 /// Indexer has special handling in constrast to other AddXXX because the name can be driven by IndexerNameAttribute
860 public void AddIndexer (Indexer i)
865 public void AddOperator (Operator op)
867 PartialContainer.HasOperators = true;
871 public void AddPartialPart (TypeDefinition part)
873 if (Kind != MemberKind.Class)
876 if (class_partial_parts == null)
877 class_partial_parts = new List<TypeDefinition> ();
879 class_partial_parts.Add (part);
882 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
884 if (has_normal_indexers && a.Type == pa.DefaultMember) {
885 Report.Error (646, a.Location, "Cannot specify the `DefaultMember' attribute on type containing an indexer");
889 if (a.Type == pa.Required) {
890 Report.Error (1608, a.Location, "The RequiredAttribute attribute is not permitted on C# types");
894 TypeBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
897 public override AttributeTargets AttributeTargets {
899 throw new NotSupportedException ();
903 public TypeSpec BaseType {
905 return spec.BaseType;
909 protected virtual TypeAttributes TypeAttr {
911 return ModifiersExtensions.TypeAttr (ModFlags, IsTopLevel);
915 public int TypeParametersCount {
917 return MemberName.Arity;
921 TypeParameterSpec[] ITypeDefinition.TypeParameters {
923 return PartialContainer.CurrentTypeParameters.Types;
927 public string GetAttributeDefaultMember ()
929 return indexer_name ?? DefaultIndexerName;
932 public bool IsComImport {
934 if (OptAttributes == null)
937 return OptAttributes.Contains (Module.PredefinedAttributes.ComImport);
941 public virtual void RegisterFieldForInitialization (MemberCore field, FieldInitializer expression)
944 PartialContainer.RegisterFieldForInitialization (field, expression);
946 if ((field.ModFlags & Modifiers.STATIC) != 0){
947 if (initialized_static_fields == null) {
948 HasStaticFieldInitializer = true;
949 initialized_static_fields = new List<FieldInitializer> (4);
952 initialized_static_fields.Add (expression);
954 if (initialized_fields == null)
955 initialized_fields = new List<FieldInitializer> (4);
957 initialized_fields.Add (expression);
961 public void ResolveFieldInitializers (BlockContext ec)
963 Debug.Assert (!IsPartialPart);
966 if (initialized_static_fields == null)
969 bool has_complex_initializer = !ec.Module.Compiler.Settings.Optimize;
971 ExpressionStatement [] init = new ExpressionStatement [initialized_static_fields.Count];
972 for (i = 0; i < initialized_static_fields.Count; ++i) {
973 FieldInitializer fi = initialized_static_fields [i];
974 ExpressionStatement s = fi.ResolveStatement (ec);
976 s = EmptyExpressionStatement.Instance;
977 } else if (!fi.IsSideEffectFree) {
978 has_complex_initializer = true;
984 for (i = 0; i < initialized_static_fields.Count; ++i) {
985 FieldInitializer fi = initialized_static_fields [i];
987 // Need special check to not optimize code like this
988 // static int a = b = 5;
991 if (!has_complex_initializer && fi.IsDefaultInitializer)
994 ec.AssignmentInfoOffset += fi.AssignmentOffset;
995 ec.CurrentBlock.AddScopeStatement (new StatementExpression (init [i]));
1001 if (initialized_fields == null)
1004 for (int i = 0; i < initialized_fields.Count; ++i) {
1005 FieldInitializer fi = initialized_fields [i];
1006 ExpressionStatement s = fi.ResolveStatement (ec);
1011 // Field is re-initialized to its default value => removed
1013 if (fi.IsDefaultInitializer && ec.Module.Compiler.Settings.Optimize)
1016 ec.AssignmentInfoOffset += fi.AssignmentOffset;
1017 ec.CurrentBlock.AddScopeStatement (new StatementExpression (s));
1021 public override string DocComment {
1033 public PendingImplementation PendingImplementations {
1034 get { return pending; }
1037 internal override void GenerateDocComment (DocumentationBuilder builder)
1042 base.GenerateDocComment (builder);
1044 foreach (var member in members)
1045 member.GenerateDocComment (builder);
1048 public TypeSpec GetAttributeCoClass ()
1050 if (OptAttributes == null)
1053 Attribute a = OptAttributes.Search (Module.PredefinedAttributes.CoClass);
1057 return a.GetCoClassAttributeValue ();
1060 public AttributeUsageAttribute GetAttributeUsage (PredefinedAttribute pa)
1063 if (OptAttributes != null) {
1064 a = OptAttributes.Search (pa);
1070 return a.GetAttributeUsageAttribute ();
1073 public virtual CompilationSourceFile GetCompilationSourceFile ()
1075 TypeContainer ns = Parent;
1077 var sf = ns as CompilationSourceFile;
1085 public virtual void SetBaseTypes (List<FullNamedExpression> baseTypes)
1087 type_bases = baseTypes;
1091 /// This function computes the Base class and also the
1092 /// list of interfaces that the class or struct @c implements.
1094 /// The return value is an array (might be null) of
1095 /// interfaces implemented (as Types).
1097 /// The @base_class argument is set to the base object or null
1098 /// if this is `System.Object'.
1100 protected virtual TypeSpec[] ResolveBaseTypes (out FullNamedExpression base_class)
1103 if (type_bases == null)
1106 int count = type_bases.Count;
1107 TypeSpec[] ifaces = null;
1108 var base_context = new BaseContext (this);
1109 for (int i = 0, j = 0; i < count; i++){
1110 FullNamedExpression fne = type_bases [i];
1112 var fne_resolved = fne.ResolveAsType (base_context);
1113 if (fne_resolved == null)
1116 if (i == 0 && Kind == MemberKind.Class && !fne_resolved.IsInterface) {
1117 if (fne_resolved.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
1118 Report.Error (1965, Location, "Class `{0}' cannot derive from the dynamic type",
1119 GetSignatureForError ());
1124 base_type = fne_resolved;
1130 ifaces = new TypeSpec [count - i];
1132 if (fne_resolved.IsInterface) {
1133 for (int ii = 0; ii < j; ++ii) {
1134 if (fne_resolved == ifaces [ii]) {
1135 Report.Error (528, Location, "`{0}' is already listed in interface list",
1136 fne_resolved.GetSignatureForError ());
1141 if (Kind == MemberKind.Interface && !IsAccessibleAs (fne_resolved)) {
1142 Report.Error (61, fne.Location,
1143 "Inconsistent accessibility: base interface `{0}' is less accessible than interface `{1}'",
1144 fne_resolved.GetSignatureForError (), GetSignatureForError ());
1147 Report.SymbolRelatedToPreviousError (fne_resolved);
1148 if (Kind != MemberKind.Class) {
1149 Report.Error (527, fne.Location, "Type `{0}' in interface list is not an interface", fne_resolved.GetSignatureForError ());
1150 } else if (base_class != null)
1151 Report.Error (1721, fne.Location, "`{0}': Classes cannot have multiple base classes (`{1}' and `{2}')",
1152 GetSignatureForError (), base_class.GetSignatureForError (), fne_resolved.GetSignatureForError ());
1154 Report.Error (1722, fne.Location, "`{0}': Base class `{1}' must be specified as first",
1155 GetSignatureForError (), fne_resolved.GetSignatureForError ());
1159 ifaces [j++] = fne_resolved;
1166 // Checks that some operators come in pairs:
1172 // They are matched based on the return type and the argument types
1174 void CheckPairedOperators ()
1176 bool has_equality_or_inequality = false;
1177 List<Operator.OpType> found_matched = new List<Operator.OpType> ();
1179 for (int i = 0; i < members.Count; ++i) {
1180 var o_a = members[i] as Operator;
1184 var o_type = o_a.OperatorType;
1185 if (o_type == Operator.OpType.Equality || o_type == Operator.OpType.Inequality)
1186 has_equality_or_inequality = true;
1188 if (found_matched.Contains (o_type))
1191 var matching_type = o_a.GetMatchingOperator ();
1192 if (matching_type == Operator.OpType.TOP) {
1196 bool pair_found = false;
1197 for (int ii = 0; ii < members.Count; ++ii) {
1198 var o_b = members[ii] as Operator;
1199 if (o_b == null || o_b.OperatorType != matching_type)
1202 if (!TypeSpecComparer.IsEqual (o_a.ReturnType, o_b.ReturnType))
1205 if (!TypeSpecComparer.Equals (o_a.ParameterTypes, o_b.ParameterTypes))
1208 found_matched.Add (matching_type);
1214 Report.Error (216, o_a.Location,
1215 "The operator `{0}' requires a matching operator `{1}' to also be defined",
1216 o_a.GetSignatureForError (), Operator.GetName (matching_type));
1220 if (has_equality_or_inequality) {
1222 Report.Warning (660, 2, Location, "`{0}' defines operator == or operator != but does not override Object.Equals(object o)",
1223 GetSignatureForError ());
1225 if (!HasGetHashCode)
1226 Report.Warning (661, 2, Location, "`{0}' defines operator == or operator != but does not override Object.GetHashCode()",
1227 GetSignatureForError ());
1231 public override void CreateMetadataName (StringBuilder sb)
1233 if (Parent.MemberName != null) {
1234 Parent.CreateMetadataName (sb);
1236 if (sb.Length != 0) {
1241 sb.Append (MemberName.Basename);
1244 bool CreateTypeBuilder ()
1247 // Sets .size to 1 for structs with no instance fields
1249 int type_size = Kind == MemberKind.Struct && first_nonstatic_field == null && !(this is StateMachine) ? 1 : 0;
1251 var parent_def = Parent as TypeDefinition;
1252 if (parent_def == null) {
1253 var sb = new StringBuilder ();
1254 CreateMetadataName (sb);
1255 TypeBuilder = Module.CreateBuilder (sb.ToString (), TypeAttr, type_size);
1257 TypeBuilder = parent_def.TypeBuilder.DefineNestedType (Basename, TypeAttr, null, type_size);
1260 if (DeclaringAssembly.Importer != null)
1261 DeclaringAssembly.Importer.AddCompiledType (TypeBuilder, spec);
1263 spec.SetMetaInfo (TypeBuilder);
1264 spec.MemberCache = new MemberCache (this);
1266 TypeParameters parentAllTypeParameters = null;
1267 if (parent_def != null) {
1268 spec.DeclaringType = Parent.CurrentType;
1269 parent_def.MemberCache.AddMember (spec);
1270 parentAllTypeParameters = parent_def.all_type_parameters;
1273 if (MemberName.TypeParameters != null || parentAllTypeParameters != null) {
1274 var tparam_names = CreateTypeParameters (parentAllTypeParameters);
1276 all_tp_builders = TypeBuilder.DefineGenericParameters (tparam_names);
1278 if (CurrentTypeParameters != null) {
1279 CurrentTypeParameters.Create (spec, CurrentTypeParametersStartIndex, this);
1280 CurrentTypeParameters.Define (all_tp_builders);
1287 string[] CreateTypeParameters (TypeParameters parentAllTypeParameters)
1290 int parent_offset = 0;
1291 if (parentAllTypeParameters != null) {
1292 if (CurrentTypeParameters == null) {
1293 all_type_parameters = parentAllTypeParameters;
1294 return parentAllTypeParameters.GetAllNames ();
1297 names = new string[parentAllTypeParameters.Count + CurrentTypeParameters.Count];
1298 all_type_parameters = new TypeParameters (names.Length);
1299 all_type_parameters.Add (parentAllTypeParameters);
1301 parent_offset = all_type_parameters.Count;
1302 for (int i = 0; i < parent_offset; ++i)
1303 names[i] = all_type_parameters[i].MemberName.Name;
1306 names = new string[CurrentTypeParameters.Count];
1309 for (int i = 0; i < CurrentTypeParameters.Count; ++i) {
1310 if (all_type_parameters != null)
1311 all_type_parameters.Add (MemberName.TypeParameters[i]);
1313 var name = CurrentTypeParameters[i].MemberName.Name;
1314 names[parent_offset + i] = name;
1315 for (int ii = 0; ii < parent_offset + i; ++ii) {
1316 if (names[ii] != name)
1319 var tp = CurrentTypeParameters[i];
1320 var conflict = all_type_parameters[ii];
1322 tp.WarningParentNameConflict (conflict);
1326 if (all_type_parameters == null)
1327 all_type_parameters = CurrentTypeParameters;
1333 public SourceMethodBuilder CreateMethodSymbolEntry ()
1335 if (Module.DeclaringAssembly.SymbolWriter == null)
1338 var source_file = GetCompilationSourceFile ();
1339 if (source_file == null)
1342 return new SourceMethodBuilder (source_file.SymbolUnitEntry);
1346 // Creates a proxy base method call inside this container for hoisted base member calls
1348 public MethodSpec CreateHoistedBaseCallProxy (ResolveContext rc, MethodSpec method)
1350 Method proxy_method;
1353 // One proxy per base method is enough
1355 if (hoisted_base_call_proxies == null) {
1356 hoisted_base_call_proxies = new Dictionary<MethodSpec, Method> ();
1357 proxy_method = null;
1359 hoisted_base_call_proxies.TryGetValue (method, out proxy_method);
1362 if (proxy_method == null) {
1363 string name = CompilerGeneratedContainer.MakeName (method.Name, null, "BaseCallProxy", hoisted_base_call_proxies.Count);
1365 MemberName member_name;
1366 TypeArguments targs = null;
1367 TypeSpec return_type = method.ReturnType;
1368 var local_param_types = method.Parameters.Types;
1370 if (method.IsGeneric) {
1372 // Copy all base generic method type parameters info
1374 var hoisted_tparams = method.GenericDefinition.TypeParameters;
1375 var tparams = new TypeParameters ();
1377 targs = new TypeArguments ();
1378 targs.Arguments = new TypeSpec[hoisted_tparams.Length];
1379 for (int i = 0; i < hoisted_tparams.Length; ++i) {
1380 var tp = hoisted_tparams[i];
1381 var local_tp = new TypeParameter (tp, null, new MemberName (tp.Name, Location), null);
1382 tparams.Add (local_tp);
1384 targs.Add (new SimpleName (tp.Name, Location));
1385 targs.Arguments[i] = local_tp.Type;
1388 member_name = new MemberName (name, tparams, Location);
1391 // Mutate any method type parameters from original
1392 // to newly created hoisted version
1394 var mutator = new TypeParameterMutator (hoisted_tparams, tparams);
1395 return_type = mutator.Mutate (return_type);
1396 local_param_types = mutator.Mutate (local_param_types);
1398 member_name = new MemberName (name);
1401 var base_parameters = new Parameter[method.Parameters.Count];
1402 for (int i = 0; i < base_parameters.Length; ++i) {
1403 var base_param = method.Parameters.FixedParameters[i];
1404 base_parameters[i] = new Parameter (new TypeExpression (local_param_types [i], Location),
1405 base_param.Name, base_param.ModFlags, null, Location);
1406 base_parameters[i].Resolve (this, i);
1409 var cloned_params = ParametersCompiled.CreateFullyResolved (base_parameters, method.Parameters.Types);
1410 if (method.Parameters.HasArglist) {
1411 cloned_params.FixedParameters[0] = new Parameter (null, "__arglist", Parameter.Modifier.NONE, null, Location);
1412 cloned_params.Types[0] = Module.PredefinedTypes.RuntimeArgumentHandle.Resolve ();
1415 // Compiler generated proxy
1416 proxy_method = new Method (this, new TypeExpression (return_type, Location),
1417 Modifiers.PRIVATE | Modifiers.COMPILER_GENERATED | Modifiers.DEBUGGER_HIDDEN,
1418 member_name, cloned_params, null);
1420 var block = new ToplevelBlock (Compiler, proxy_method.ParameterInfo, Location) {
1421 IsCompilerGenerated = true
1424 var mg = MethodGroupExpr.CreatePredefined (method, method.DeclaringType, Location);
1425 mg.InstanceExpression = new BaseThis (method.DeclaringType, Location);
1427 mg.SetTypeArguments (rc, targs);
1429 // Get all the method parameters and pass them as arguments
1430 var real_base_call = new Invocation (mg, block.GetAllParametersArguments ());
1431 Statement statement;
1432 if (method.ReturnType.Kind == MemberKind.Void)
1433 statement = new StatementExpression (real_base_call);
1435 statement = new Return (real_base_call, Location);
1437 block.AddStatement (statement);
1438 proxy_method.Block = block;
1440 members.Add (proxy_method);
1441 proxy_method.Define ();
1442 proxy_method.PrepareEmit ();
1444 hoisted_base_call_proxies.Add (method, proxy_method);
1447 return proxy_method.Spec;
1450 protected bool DefineBaseTypes ()
1452 if (IsPartialPart && Kind == MemberKind.Class)
1455 return DoDefineBaseType ();
1458 bool DoDefineBaseType ()
1460 iface_exprs = ResolveBaseTypes (out base_type_expr);
1463 if (IsPartialPart) {
1464 set_base_type = false;
1466 if (base_type_expr != null) {
1467 if (PartialContainer.base_type_expr != null && PartialContainer.base_type != base_type) {
1468 Report.SymbolRelatedToPreviousError (base_type_expr.Location, "");
1469 Report.Error (263, Location,
1470 "Partial declarations of `{0}' must not specify different base classes",
1471 GetSignatureForError ());
1473 PartialContainer.base_type_expr = base_type_expr;
1474 PartialContainer.base_type = base_type;
1475 set_base_type = true;
1479 if (iface_exprs != null) {
1480 if (PartialContainer.iface_exprs == null)
1481 PartialContainer.iface_exprs = iface_exprs;
1483 var ifaces = new List<TypeSpec> (PartialContainer.iface_exprs);
1484 foreach (var iface_partial in iface_exprs) {
1485 if (ifaces.Contains (iface_partial))
1488 ifaces.Add (iface_partial);
1491 PartialContainer.iface_exprs = ifaces.ToArray ();
1495 PartialContainer.members.AddRange (members);
1496 if (containers != null) {
1497 if (PartialContainer.containers == null)
1498 PartialContainer.containers = new List<TypeContainer> ();
1500 PartialContainer.containers.AddRange (containers);
1503 members_defined = members_defined_ok = true;
1504 caching_flags |= Flags.CloseTypeCreated;
1506 set_base_type = true;
1509 var cycle = CheckRecursiveDefinition (this);
1510 if (cycle != null) {
1511 Report.SymbolRelatedToPreviousError (cycle);
1512 if (this is Interface) {
1513 Report.Error (529, Location,
1514 "Inherited interface `{0}' causes a cycle in the interface hierarchy of `{1}'",
1515 GetSignatureForError (), cycle.GetSignatureForError ());
1518 PartialContainer.iface_exprs = null;
1520 Report.Error (146, Location,
1521 "Circular base class dependency involving `{0}' and `{1}'",
1522 GetSignatureForError (), cycle.GetSignatureForError ());
1525 PartialContainer.base_type = null;
1529 if (iface_exprs != null) {
1530 foreach (var iface_type in iface_exprs) {
1531 // Prevents a crash, the interface might not have been resolved: 442144
1532 if (iface_type == null)
1535 if (!spec.AddInterfaceDefined (iface_type))
1538 TypeBuilder.AddInterfaceImplementation (iface_type.GetMetaInfo ());
1542 if (Kind == MemberKind.Interface) {
1543 spec.BaseType = Compiler.BuiltinTypes.Object;
1547 if (set_base_type) {
1552 // Base type of partial container has to be resolved before we
1553 // resolve any nested types of the container. We need to know
1554 // partial parts because the base type can be specified in file
1555 // defined after current container
1557 if (class_partial_parts != null) {
1558 foreach (var pp in class_partial_parts)
1559 pp.DoDefineBaseType ();
1568 if (base_type == null) {
1569 TypeBuilder.SetParent (null);
1573 if (spec.BaseType == base_type)
1576 spec.BaseType = base_type;
1579 spec.UpdateInflatedInstancesBaseType ();
1581 // Set base type after type creation
1582 TypeBuilder.SetParent (base_type.GetMetaInfo ());
1585 public override void ExpandBaseInterfaces ()
1588 DoExpandBaseInterfaces ();
1590 base.ExpandBaseInterfaces ();
1593 public void DoExpandBaseInterfaces ()
1595 if ((caching_flags & Flags.InterfacesExpanded) != 0)
1598 caching_flags |= Flags.InterfacesExpanded;
1601 // Expand base interfaces. It cannot be done earlier because all partial
1602 // interface parts need to be defined before the type they are used from
1604 if (iface_exprs != null) {
1605 foreach (var iface in iface_exprs) {
1609 var td = iface.MemberDefinition as TypeDefinition;
1611 td.DoExpandBaseInterfaces ();
1613 if (iface.Interfaces == null)
1616 foreach (var biface in iface.Interfaces) {
1617 if (spec.AddInterfaceDefined (biface)) {
1618 TypeBuilder.AddInterfaceImplementation (biface.GetMetaInfo ());
1625 // Include all base type interfaces too, see ImportTypeBase for details
1627 if (base_type != null) {
1628 var td = base_type.MemberDefinition as TypeDefinition;
1630 td.DoExpandBaseInterfaces ();
1633 // Simply use base interfaces only, they are all expanded which makes
1634 // it easy to handle generic type argument propagation with single
1637 // interface IA<T> : IB<T>
1638 // interface IB<U> : IC<U>
1641 if (base_type.Interfaces != null) {
1642 foreach (var iface in base_type.Interfaces) {
1643 spec.AddInterfaceDefined (iface);
1649 public override void PrepareEmit ()
1651 if ((caching_flags & Flags.CloseTypeCreated) != 0)
1654 foreach (var member in members) {
1655 var pm = member as IParametersMember;
1657 var mc = member as MethodOrOperator;
1662 var p = pm.Parameters;
1666 ((ParametersCompiled) p).ResolveDefaultValues (member);
1669 var c = member as Const;
1674 base.PrepareEmit ();
1678 // Defines the type in the appropriate ModuleBuilder or TypeBuilder.
1680 public override bool CreateContainer ()
1682 if (TypeBuilder != null)
1688 if (IsPartialPart) {
1689 spec = PartialContainer.spec;
1690 TypeBuilder = PartialContainer.TypeBuilder;
1691 all_tp_builders = PartialContainer.all_tp_builders;
1692 all_type_parameters = PartialContainer.all_type_parameters;
1694 if (!CreateTypeBuilder ()) {
1700 return base.CreateContainer ();
1703 protected override void DoDefineContainer ()
1707 DoResolveTypeParameters ();
1711 // Replaces normal spec with predefined one when compiling corlib
1712 // and this type container defines predefined type
1714 public void SetPredefinedSpec (BuiltinTypeSpec spec)
1716 // When compiling build-in types we start with two
1717 // version of same type. One is of BuiltinTypeSpec and
1718 // second one is ordinary TypeSpec. The unification
1719 // happens at later stage when we know which type
1720 // really matches the builtin type signature. However
1721 // that means TypeSpec create during CreateType of this
1722 // type has to be replaced with builtin one
1724 spec.SetMetaInfo (TypeBuilder);
1725 spec.MemberCache = this.spec.MemberCache;
1726 spec.DeclaringType = this.spec.DeclaringType;
1729 current_type = null;
1732 public override void RemoveContainer (TypeContainer cont)
1734 base.RemoveContainer (cont);
1735 Members.Remove (cont);
1736 Cache.Remove (cont.Basename);
1739 protected virtual bool DoResolveTypeParameters ()
1741 var tparams = CurrentTypeParameters;
1742 if (tparams == null)
1745 var base_context = new BaseContext (this);
1746 for (int i = 0; i < tparams.Count; ++i) {
1747 var tp = tparams[i];
1749 if (!tp.ResolveConstraints (base_context)) {
1755 if (IsPartialPart) {
1756 PartialContainer.CurrentTypeParameters.UpdateConstraints (this);
1762 TypeSpec CheckRecursiveDefinition (TypeDefinition tc)
1764 if (InTransit != null)
1769 if (base_type != null) {
1770 var ptc = base_type.MemberDefinition as TypeDefinition;
1771 if (ptc != null && ptc.CheckRecursiveDefinition (this) != null)
1775 if (iface_exprs != null) {
1776 foreach (var iface in iface_exprs) {
1777 // the interface might not have been resolved, prevents a crash, see #442144
1780 var ptc = iface.MemberDefinition as Interface;
1781 if (ptc != null && ptc.CheckRecursiveDefinition (this) != null)
1786 if (!IsTopLevel && Parent.PartialContainer.CheckRecursiveDefinition (this) != null)
1794 /// Populates our TypeBuilder with fields and methods
1796 public sealed override bool Define ()
1798 if (members_defined)
1799 return members_defined_ok;
1801 members_defined_ok = DoDefineMembers ();
1802 members_defined = true;
1806 return members_defined_ok;
1809 protected virtual bool DoDefineMembers ()
1811 Debug.Assert (!IsPartialPart);
1813 if (iface_exprs != null) {
1814 foreach (var iface_type in iface_exprs) {
1815 if (iface_type == null)
1818 // Ensure the base is always setup
1819 var compiled_iface = iface_type.MemberDefinition as Interface;
1820 if (compiled_iface != null)
1821 compiled_iface.Define ();
1823 ObsoleteAttribute oa = iface_type.GetAttributeObsolete ();
1824 if (oa != null && !IsObsolete)
1825 AttributeTester.Report_ObsoleteMessage (oa, iface_type.GetSignatureForError (), Location, Report);
1827 if (iface_type.Arity > 0) {
1828 // TODO: passing `this' is wrong, should be base type iface instead
1829 VarianceDecl.CheckTypeVariance (iface_type, Variance.Covariant, this);
1831 if (((InflatedTypeSpec) iface_type).HasDynamicArgument () && !IsCompilerGenerated) {
1832 Report.Error (1966, Location,
1833 "`{0}': cannot implement a dynamic interface `{1}'",
1834 GetSignatureForError (), iface_type.GetSignatureForError ());
1839 if (iface_type.IsGenericOrParentIsGeneric) {
1840 foreach (var prev_iface in iface_exprs) {
1841 if (prev_iface == iface_type || prev_iface == null)
1844 if (!TypeSpecComparer.Unify.IsEqual (iface_type, prev_iface))
1847 Report.Error (695, Location,
1848 "`{0}' cannot implement both `{1}' and `{2}' because they may unify for some type parameter substitutions",
1849 GetSignatureForError (), prev_iface.GetSignatureForError (), iface_type.GetSignatureForError ());
1854 if (Kind == MemberKind.Interface) {
1855 foreach (var iface in spec.Interfaces) {
1856 MemberCache.AddInterface (iface);
1861 if (base_type != null) {
1863 // Run checks skipped during DefineType (e.g FullNamedExpression::ResolveAsType)
1865 if (base_type_expr != null) {
1866 ObsoleteAttribute obsolete_attr = base_type.GetAttributeObsolete ();
1867 if (obsolete_attr != null && !IsObsolete)
1868 AttributeTester.Report_ObsoleteMessage (obsolete_attr, base_type.GetSignatureForError (), base_type_expr.Location, Report);
1870 if (IsGenericOrParentIsGeneric && base_type.IsAttribute) {
1871 Report.Error (698, base_type_expr.Location,
1872 "A generic type cannot derive from `{0}' because it is an attribute class",
1873 base_type.GetSignatureForError ());
1877 var baseContainer = base_type.MemberDefinition as ClassOrStruct;
1878 if (baseContainer != null) {
1879 baseContainer.Define ();
1882 // It can trigger define of this type (for generic types only)
1884 if (HasMembersDefined)
1889 if (Kind == MemberKind.Struct || Kind == MemberKind.Class) {
1890 pending = PendingImplementation.GetPendingImplementations (this);
1893 var count = members.Count;
1894 for (int i = 0; i < count; ++i) {
1895 var mc = members[i] as InterfaceMemberBase;
1896 if (mc == null || !mc.IsExplicitImpl)
1901 } catch (Exception e) {
1902 throw new InternalErrorException (mc, e);
1906 for (int i = 0; i < count; ++i) {
1907 var mc = members[i] as InterfaceMemberBase;
1908 if (mc != null && mc.IsExplicitImpl)
1911 if (members[i] is TypeContainer)
1915 members[i].Define ();
1916 } catch (Exception e) {
1917 throw new InternalErrorException (members[i], e);
1922 CheckPairedOperators ();
1925 if (requires_delayed_unmanagedtype_check) {
1926 requires_delayed_unmanagedtype_check = false;
1927 foreach (var member in members) {
1928 var f = member as Field;
1929 if (f != null && f.MemberType != null && f.MemberType.IsPointer)
1930 TypeManager.VerifyUnmanaged (Module, f.MemberType, f.Location);
1934 ComputeIndexerName();
1936 if (HasEquals && !HasGetHashCode) {
1937 Report.Warning (659, 3, Location,
1938 "`{0}' overrides Object.Equals(object) but does not override Object.GetHashCode()", GetSignatureForError ());
1941 if (Kind == MemberKind.Interface && iface_exprs != null) {
1942 MemberCache.RemoveHiddenMembers (spec);
1948 void ComputeIndexerName ()
1950 var indexers = MemberCache.FindMembers (spec, MemberCache.IndexerNameAlias, true);
1951 if (indexers == null)
1954 string class_indexer_name = null;
1957 // Check normal indexers for consistent name, explicit interface implementation
1958 // indexers are ignored
1960 foreach (var indexer in indexers) {
1962 // FindMembers can return unfiltered full hierarchy names
1964 if (indexer.DeclaringType != spec)
1967 has_normal_indexers = true;
1969 if (class_indexer_name == null) {
1970 indexer_name = class_indexer_name = indexer.Name;
1974 if (indexer.Name != class_indexer_name)
1975 Report.Error (668, ((Indexer)indexer.MemberDefinition).Location,
1976 "Two indexers have different names; the IndexerName attribute must be used with the same name on every indexer within a type");
1980 void EmitIndexerName ()
1982 if (!has_normal_indexers)
1985 var ctor = Module.PredefinedMembers.DefaultMemberAttributeCtor.Get ();
1989 var encoder = new AttributeEncoder ();
1990 encoder.Encode (GetAttributeDefaultMember ());
1991 encoder.EncodeEmptyNamedArguments ();
1993 TypeBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray ());
1996 public override void VerifyMembers ()
1999 // Check for internal or private fields that were never assigned
2001 if (!IsCompilerGenerated && Compiler.Settings.WarningLevel >= 3 && this == PartialContainer) {
2002 bool is_type_exposed = Kind == MemberKind.Struct || IsExposedFromAssembly ();
2003 foreach (var member in members) {
2004 if (member is Event) {
2006 // An event can be assigned from same class only, so we can report
2007 // this warning for all accessibility modes
2010 Report.Warning (67, 3, member.Location, "The event `{0}' is never used", member.GetSignatureForError ());
2015 if ((member.ModFlags & Modifiers.AccessibilityMask) != Modifiers.PRIVATE) {
2016 if (is_type_exposed)
2019 member.SetIsUsed ();
2022 var f = member as Field;
2026 if (!member.IsUsed) {
2027 if ((member.caching_flags & Flags.IsAssigned) == 0) {
2028 Report.Warning (169, 3, member.Location, "The private field `{0}' is never used", member.GetSignatureForError ());
2030 Report.Warning (414, 3, member.Location, "The private field `{0}' is assigned but its value is never used",
2031 member.GetSignatureForError ());
2036 if ((f.caching_flags & Flags.IsAssigned) != 0)
2040 // Only report 649 on level 4
2042 if (Compiler.Settings.WarningLevel < 4)
2046 // Don't be pedantic when type requires specific layout
2048 if (f.OptAttributes != null || PartialContainer.HasStructLayout)
2051 Constant c = New.Constantify (f.MemberType, f.Location);
2054 value = c.GetValueAsLiteral ();
2055 } else if (TypeSpec.IsReferenceType (f.MemberType)) {
2062 value = " `" + value + "'";
2064 Report.Warning (649, 4, f.Location, "Field `{0}' is never assigned to, and will always have its default value{1}",
2065 f.GetSignatureForError (), value);
2069 base.VerifyMembers ();
2072 public override void Emit ()
2074 if (OptAttributes != null)
2075 OptAttributes.Emit ();
2077 if (!IsCompilerGenerated) {
2079 MemberSpec candidate;
2080 bool overrides = false;
2081 var conflict_symbol = MemberCache.FindBaseMember (this, out candidate, ref overrides);
2082 if (conflict_symbol == null && candidate == null) {
2083 if ((ModFlags & Modifiers.NEW) != 0)
2084 Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required",
2085 GetSignatureForError ());
2087 if ((ModFlags & Modifiers.NEW) == 0) {
2088 if (candidate == null)
2089 candidate = conflict_symbol;
2091 Report.SymbolRelatedToPreviousError (candidate);
2092 Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
2093 GetSignatureForError (), candidate.GetSignatureForError ());
2098 // Run constraints check on all possible generic types
2099 if (base_type != null && base_type_expr != null) {
2100 ConstraintChecker.Check (this, base_type, base_type_expr.Location);
2103 if (iface_exprs != null) {
2104 foreach (var iface_type in iface_exprs) {
2105 if (iface_type == null)
2108 ConstraintChecker.Check (this, iface_type, Location); // TODO: Location is wrong
2113 if (all_tp_builders != null) {
2114 int current_starts_index = CurrentTypeParametersStartIndex;
2115 for (int i = 0; i < all_tp_builders.Length; i++) {
2116 if (i < current_starts_index) {
2117 all_type_parameters[i].EmitConstraints (all_tp_builders [i]);
2119 var tp = CurrentTypeParameters [i - current_starts_index];
2120 tp.CheckGenericConstraints (!IsObsolete);
2126 if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0 && !Parent.IsCompilerGenerated)
2127 Module.PredefinedAttributes.CompilerGenerated.EmitAttribute (TypeBuilder);
2130 if ((TypeBuilder.Attributes & TypeAttributes.StringFormatMask) == 0 && Module.HasDefaultCharSet)
2131 TypeBuilder.__SetAttributes (TypeBuilder.Attributes | Module.DefaultCharSetType);
2136 for (int i = 0; i < members.Count; i++) {
2138 if ((m.caching_flags & Flags.CloseTypeCreated) != 0)
2145 CheckAttributeClsCompliance ();
2147 if (pending != null)
2148 pending.VerifyPendingMethods ();
2152 void CheckAttributeClsCompliance ()
2154 if (!spec.IsAttribute || !IsExposedFromAssembly () || !Compiler.Settings.VerifyClsCompliance || !IsClsComplianceRequired ())
2157 foreach (var m in members) {
2158 var c = m as Constructor;
2162 if (c.HasCompliantArgs)
2166 Report.Warning (3015, 1, Location, "`{0}' has no accessible constructors which use only CLS-compliant types", GetSignatureForError ());
2169 public sealed override void EmitContainer ()
2171 if ((caching_flags & Flags.CloseTypeCreated) != 0)
2177 public override void CloseContainer ()
2179 if ((caching_flags & Flags.CloseTypeCreated) != 0)
2182 // Close base type container first to avoid TypeLoadException
2183 if (spec.BaseType != null) {
2184 var btype = spec.BaseType.MemberDefinition as TypeContainer;
2185 if (btype != null) {
2186 btype.CloseContainer ();
2188 if ((caching_flags & Flags.CloseTypeCreated) != 0)
2194 caching_flags |= Flags.CloseTypeCreated;
2195 TypeBuilder.CreateType ();
2196 } catch (TypeLoadException) {
2198 // This is fine, the code still created the type
2200 } catch (Exception e) {
2201 throw new InternalErrorException (this, e);
2204 base.CloseContainer ();
2207 initialized_fields = null;
2208 initialized_static_fields = null;
2210 OptAttributes = null;
2214 // Performs the validation on a Method's modifiers (properties have
2215 // the same properties).
2217 // TODO: Why is it not done at parse stage, move to Modifiers::Check
2219 public bool MethodModifiersValid (MemberCore mc)
2221 const Modifiers vao = (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE);
2222 const Modifiers nv = (Modifiers.NEW | Modifiers.VIRTUAL);
2224 var flags = mc.ModFlags;
2227 // At most one of static, virtual or override
2229 if ((flags & Modifiers.STATIC) != 0){
2230 if ((flags & vao) != 0){
2231 Report.Error (112, mc.Location, "A static member `{0}' cannot be marked as override, virtual or abstract",
2232 mc.GetSignatureForError ());
2237 if ((flags & Modifiers.OVERRIDE) != 0 && (flags & nv) != 0){
2238 Report.Error (113, mc.Location, "A member `{0}' marked as override cannot be marked as new or virtual",
2239 mc.GetSignatureForError ());
2244 // If the declaration includes the abstract modifier, then the
2245 // declaration does not include static, virtual or extern
2247 if ((flags & Modifiers.ABSTRACT) != 0){
2248 if ((flags & Modifiers.EXTERN) != 0){
2250 180, mc.Location, "`{0}' cannot be both extern and abstract", mc.GetSignatureForError ());
2254 if ((flags & Modifiers.SEALED) != 0) {
2255 Report.Error (502, mc.Location, "`{0}' cannot be both abstract and sealed", mc.GetSignatureForError ());
2259 if ((flags & Modifiers.VIRTUAL) != 0){
2260 Report.Error (503, mc.Location, "The abstract method `{0}' cannot be marked virtual", mc.GetSignatureForError ());
2264 if ((ModFlags & Modifiers.ABSTRACT) == 0){
2265 Report.SymbolRelatedToPreviousError (this);
2266 Report.Error (513, mc.Location, "`{0}' is abstract but it is declared in the non-abstract class `{1}'",
2267 mc.GetSignatureForError (), GetSignatureForError ());
2272 if ((flags & Modifiers.PRIVATE) != 0){
2273 if ((flags & vao) != 0){
2274 Report.Error (621, mc.Location, "`{0}': virtual or abstract members cannot be private", mc.GetSignatureForError ());
2279 if ((flags & Modifiers.SEALED) != 0){
2280 if ((flags & Modifiers.OVERRIDE) == 0){
2281 Report.Error (238, mc.Location, "`{0}' cannot be sealed because it is not an override", mc.GetSignatureForError ());
2289 protected override bool VerifyClsCompliance ()
2291 if (!base.VerifyClsCompliance ())
2294 // Check all container names for user classes
2295 if (Kind != MemberKind.Delegate)
2296 MemberCache.VerifyClsCompliance (Definition, Report);
2298 if (BaseType != null && !BaseType.IsCLSCompliant ()) {
2299 Report.Warning (3009, 1, Location, "`{0}': base type `{1}' is not CLS-compliant",
2300 GetSignatureForError (), BaseType.GetSignatureForError ());
2306 /// Performs checks for an explicit interface implementation. First it
2307 /// checks whether the `interface_type' is a base inteface implementation.
2308 /// Then it checks whether `name' exists in the interface type.
2310 public bool VerifyImplements (InterfaceMemberBase mb)
2312 var ifaces = PartialContainer.Interfaces;
2313 if (ifaces != null) {
2314 foreach (TypeSpec t in ifaces){
2315 if (t == mb.InterfaceType)
2318 var expanded_base = t.Interfaces;
2319 if (expanded_base == null)
2322 foreach (var bt in expanded_base) {
2323 if (bt == mb.InterfaceType)
2329 Report.SymbolRelatedToPreviousError (mb.InterfaceType);
2330 Report.Error (540, mb.Location, "`{0}': containing type does not implement interface `{1}'",
2331 mb.GetSignatureForError (), mb.InterfaceType.GetSignatureForError ());
2336 // Used for visiblity checks to tests whether this definition shares
2337 // base type baseType, it does member-definition search
2339 public bool IsBaseTypeDefinition (TypeSpec baseType)
2341 // RootContext check
2342 if (TypeBuilder == null)
2347 if (type.MemberDefinition == baseType.MemberDefinition)
2350 type = type.BaseType;
2351 } while (type != null);
2356 public override bool IsClsComplianceRequired ()
2359 return PartialContainer.IsClsComplianceRequired ();
2361 return base.IsClsComplianceRequired ();
2364 bool ITypeDefinition.IsInternalAsPublic (IAssemblyDefinition assembly)
2366 return Module.DeclaringAssembly == assembly;
2369 public virtual bool IsUnmanagedType ()
2374 public void LoadMembers (TypeSpec declaringType, bool onlyTypes, ref MemberCache cache)
2376 throw new NotSupportedException ("Not supported for compiled definition " + GetSignatureForError ());
2380 // Public function used to locate types.
2382 // Returns: Type or null if they type can not be found.
2384 public override FullNamedExpression LookupNamespaceOrType (string name, int arity, LookupMode mode, Location loc)
2386 FullNamedExpression e;
2387 if (arity == 0 && Cache.TryGetValue (name, out e) && mode != LookupMode.IgnoreAccessibility)
2393 var tp = CurrentTypeParameters;
2395 TypeParameter tparam = tp.Find (name);
2397 e = new TypeParameterExpr (tparam, Location.Null);
2402 TypeSpec t = LookupNestedTypeInHierarchy (name, arity);
2404 if (t != null && (t.IsAccessible (this) || mode == LookupMode.IgnoreAccessibility))
2405 e = new TypeExpression (t, Location.Null);
2407 var errors = Compiler.Report.Errors;
2408 e = Parent.LookupNamespaceOrType (name, arity, mode, loc);
2410 // TODO: LookupNamespaceOrType does more than just lookup. The result
2411 // cannot be cached or the error reporting won't happen
2412 if (errors != Compiler.Report.Errors)
2417 // TODO MemberCache: How to cache arity stuff ?
2418 if (arity == 0 && mode == LookupMode.Normal)
2424 TypeSpec LookupNestedTypeInHierarchy (string name, int arity)
2426 // Has any nested type
2427 // Does not work, because base type can have
2428 //if (PartialContainer.Types == null)
2431 var container = PartialContainer.CurrentType;
2432 return MemberCache.FindNestedType (container, name, arity);
2435 public void Mark_HasEquals ()
2437 cached_method |= CachedMethods.Equals;
2440 public void Mark_HasGetHashCode ()
2442 cached_method |= CachedMethods.GetHashCode;
2445 public override void WriteDebugSymbol (MonoSymbolFile file)
2450 foreach (var m in members) {
2451 m.WriteDebugSymbol (file);
2456 /// Method container contains Equals method
2458 public bool HasEquals {
2460 return (cached_method & CachedMethods.Equals) != 0;
2465 /// Method container contains GetHashCode method
2467 public bool HasGetHashCode {
2469 return (cached_method & CachedMethods.GetHashCode) != 0;
2473 public bool HasStaticFieldInitializer {
2475 return (cached_method & CachedMethods.HasStaticFieldInitializer) != 0;
2479 cached_method |= CachedMethods.HasStaticFieldInitializer;
2481 cached_method &= ~CachedMethods.HasStaticFieldInitializer;
2485 public override string DocCommentHeader {
2486 get { return "T:"; }
2490 public abstract class ClassOrStruct : TypeDefinition
2492 public const TypeAttributes StaticClassAttribute = TypeAttributes.Abstract | TypeAttributes.Sealed;
2494 SecurityType declarative_security;
2496 protected ClassOrStruct (TypeContainer parent, MemberName name, Attributes attrs, MemberKind kind)
2497 : base (parent, name, attrs, kind)
2501 protected override TypeAttributes TypeAttr {
2503 TypeAttributes ta = base.TypeAttr;
2504 if (!has_static_constructor)
2505 ta |= TypeAttributes.BeforeFieldInit;
2507 if (Kind == MemberKind.Class) {
2508 ta |= TypeAttributes.AutoLayout | TypeAttributes.Class;
2510 ta |= StaticClassAttribute;
2512 ta |= TypeAttributes.SequentialLayout;
2519 public override void AddNameToContainer (MemberCore symbol, string name)
2521 if (!(symbol is Constructor) && symbol.MemberName.Name == MemberName.Name) {
2522 if (symbol is TypeParameter) {
2523 Report.Error (694, symbol.Location,
2524 "Type parameter `{0}' has same name as containing type, or method",
2525 symbol.GetSignatureForError ());
2529 InterfaceMemberBase imb = symbol as InterfaceMemberBase;
2530 if (imb == null || !imb.IsExplicitImpl) {
2531 Report.SymbolRelatedToPreviousError (this);
2532 Report.Error (542, symbol.Location, "`{0}': member names cannot be the same as their enclosing type",
2533 symbol.GetSignatureForError ());
2538 base.AddNameToContainer (symbol, name);
2541 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
2543 if (a.IsValidSecurityAttribute ()) {
2544 a.ExtractSecurityPermissionSet (ctor, ref declarative_security);
2548 if (a.Type == pa.StructLayout) {
2549 PartialContainer.HasStructLayout = true;
2550 if (a.IsExplicitLayoutKind ())
2551 PartialContainer.HasExplicitLayout = true;
2554 if (a.Type == pa.Dynamic) {
2555 a.Error_MisusedDynamicAttribute ();
2559 base.ApplyAttributeBuilder (a, ctor, cdata, pa);
2563 /// Defines the default constructors
2565 protected virtual Constructor DefineDefaultConstructor (bool is_static)
2567 // The default instance constructor is public
2568 // If the class is abstract, the default constructor is protected
2569 // The default static constructor is private
2573 mods = Modifiers.STATIC | Modifiers.PRIVATE;
2575 mods = ((ModFlags & Modifiers.ABSTRACT) != 0) ? Modifiers.PROTECTED : Modifiers.PUBLIC;
2578 var c = new Constructor (this, MemberName.Name, mods, null, ParametersCompiled.EmptyReadOnlyParameters, Location);
2579 c.Initializer = new GeneratedBaseInitializer (Location);
2581 AddConstructor (c, true);
2582 c.Block = new ToplevelBlock (Compiler, ParametersCompiled.EmptyReadOnlyParameters, Location) {
2583 IsCompilerGenerated = true
2589 protected override bool DoDefineMembers ()
2591 CheckProtectedModifier ();
2593 base.DoDefineMembers ();
2598 public override void Emit ()
2600 if (!has_static_constructor && HasStaticFieldInitializer) {
2601 var c = DefineDefaultConstructor (true);
2607 if (declarative_security != null) {
2608 foreach (var de in declarative_security) {
2610 TypeBuilder.__AddDeclarativeSecurity (de);
2612 TypeBuilder.AddDeclarativeSecurity (de.Key, de.Value);
2620 public sealed class Class : ClassOrStruct
2622 const Modifiers AllowedModifiers =
2625 Modifiers.PROTECTED |
2626 Modifiers.INTERNAL |
2628 Modifiers.ABSTRACT |
2633 public Class (TypeContainer parent, MemberName name, Modifiers mod, Attributes attrs)
2634 : base (parent, name, attrs, MemberKind.Class)
2636 var accmods = IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE;
2637 this.ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, accmods, Location, Report);
2638 spec = new TypeSpec (Kind, null, this, null, ModFlags);
2641 public override void Accept (StructuralVisitor visitor)
2643 visitor.Visit (this);
2646 public override void SetBaseTypes (List<FullNamedExpression> baseTypes)
2648 var pmn = MemberName;
2649 if (pmn.Name == "Object" && !pmn.IsGeneric && Parent.MemberName.Name == "System" && Parent.MemberName.Left == null)
2650 Report.Error (537, Location,
2651 "The class System.Object cannot have a base class or implement an interface.");
2653 base.SetBaseTypes (baseTypes);
2656 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
2658 if (a.Type == pa.AttributeUsage) {
2659 if (!BaseType.IsAttribute && spec.BuiltinType != BuiltinTypeSpec.Type.Attribute) {
2660 Report.Error (641, a.Location, "Attribute `{0}' is only valid on classes derived from System.Attribute", a.GetSignatureForError ());
2664 if (a.Type == pa.Conditional && !BaseType.IsAttribute) {
2665 Report.Error (1689, a.Location, "Attribute `System.Diagnostics.ConditionalAttribute' is only valid on methods or attribute classes");
2669 if (a.Type == pa.ComImport && !attributes.Contains (pa.Guid)) {
2670 a.Error_MissingGuidAttribute ();
2674 if (a.Type == pa.Extension) {
2675 a.Error_MisusedExtensionAttribute ();
2679 if (a.Type.IsConditionallyExcluded (this))
2682 base.ApplyAttributeBuilder (a, ctor, cdata, pa);
2685 public override AttributeTargets AttributeTargets {
2687 return AttributeTargets.Class;
2691 protected override bool DoDefineMembers ()
2693 if ((ModFlags & Modifiers.ABSTRACT) == Modifiers.ABSTRACT && (ModFlags & (Modifiers.SEALED | Modifiers.STATIC)) != 0) {
2694 Report.Error (418, Location, "`{0}': an abstract class cannot be sealed or static", GetSignatureForError ());
2697 if ((ModFlags & (Modifiers.SEALED | Modifiers.STATIC)) == (Modifiers.SEALED | Modifiers.STATIC)) {
2698 Report.Error (441, Location, "`{0}': a class cannot be both static and sealed", GetSignatureForError ());
2702 foreach (var m in Members) {
2703 if (m is Operator) {
2704 Report.Error (715, m.Location, "`{0}': Static classes cannot contain user-defined operators", m.GetSignatureForError ());
2708 if (m is Destructor) {
2709 Report.Error (711, m.Location, "`{0}': Static classes cannot contain destructor", GetSignatureForError ());
2714 Report.Error (720, m.Location, "`{0}': cannot declare indexers in a static class", m.GetSignatureForError ());
2718 if ((m.ModFlags & Modifiers.STATIC) != 0 || m is TypeContainer)
2721 if (m is Constructor) {
2722 Report.Error (710, m.Location, "`{0}': Static classes cannot have instance constructors", GetSignatureForError ());
2726 Report.Error (708, m.Location, "`{0}': cannot declare instance members in a static class", m.GetSignatureForError ());
2729 if (!PartialContainer.HasInstanceConstructor)
2730 DefineDefaultConstructor (false);
2733 return base.DoDefineMembers ();
2736 public override void Emit ()
2740 if ((ModFlags & Modifiers.METHOD_EXTENSION) != 0)
2741 Module.PredefinedAttributes.Extension.EmitAttribute (TypeBuilder);
2743 if (base_type != null && base_type.HasDynamicElement) {
2744 Module.PredefinedAttributes.Dynamic.EmitAttribute (TypeBuilder, base_type, Location);
2748 protected override TypeSpec[] ResolveBaseTypes (out FullNamedExpression base_class)
2750 var ifaces = base.ResolveBaseTypes (out base_class);
2752 if (base_class == null) {
2753 if (spec.BuiltinType != BuiltinTypeSpec.Type.Object)
2754 base_type = Compiler.BuiltinTypes.Object;
2756 if (base_type.IsGenericParameter){
2757 Report.Error (689, base_class.Location, "`{0}': Cannot derive from type parameter `{1}'",
2758 GetSignatureForError (), base_type.GetSignatureForError ());
2759 } else if (base_type.IsStatic) {
2760 Report.SymbolRelatedToPreviousError (base_type);
2761 Report.Error (709, Location, "`{0}': Cannot derive from static class `{1}'",
2762 GetSignatureForError (), base_type.GetSignatureForError ());
2763 } else if (base_type.IsSealed) {
2764 Report.SymbolRelatedToPreviousError (base_type);
2765 Report.Error (509, Location, "`{0}': cannot derive from sealed type `{1}'",
2766 GetSignatureForError (), base_type.GetSignatureForError ());
2767 } else if (PartialContainer.IsStatic && base_type.BuiltinType != BuiltinTypeSpec.Type.Object) {
2768 Report.Error (713, Location, "Static class `{0}' cannot derive from type `{1}'. Static classes must derive from object",
2769 GetSignatureForError (), base_type.GetSignatureForError ());
2772 switch (base_type.BuiltinType) {
2773 case BuiltinTypeSpec.Type.Enum:
2774 case BuiltinTypeSpec.Type.ValueType:
2775 case BuiltinTypeSpec.Type.MulticastDelegate:
2776 case BuiltinTypeSpec.Type.Delegate:
2777 case BuiltinTypeSpec.Type.Array:
2778 if (!(spec is BuiltinTypeSpec)) {
2779 Report.Error (644, Location, "`{0}' cannot derive from special class `{1}'",
2780 GetSignatureForError (), base_type.GetSignatureForError ());
2782 base_type = Compiler.BuiltinTypes.Object;
2787 if (!IsAccessibleAs (base_type)) {
2788 Report.SymbolRelatedToPreviousError (base_type);
2789 Report.Error (60, Location, "Inconsistent accessibility: base class `{0}' is less accessible than class `{1}'",
2790 base_type.GetSignatureForError (), GetSignatureForError ());
2794 if (PartialContainer.IsStatic && ifaces != null) {
2795 foreach (var t in ifaces)
2796 Report.SymbolRelatedToPreviousError (t);
2797 Report.Error (714, Location, "Static class `{0}' cannot implement interfaces", GetSignatureForError ());
2803 /// Search for at least one defined condition in ConditionalAttribute of attribute class
2804 /// Valid only for attribute classes.
2805 public override string[] ConditionalConditions ()
2807 if ((caching_flags & (Flags.Excluded_Undetected | Flags.Excluded)) == 0)
2810 caching_flags &= ~Flags.Excluded_Undetected;
2812 if (OptAttributes == null)
2815 Attribute[] attrs = OptAttributes.SearchMulti (Module.PredefinedAttributes.Conditional);
2819 string[] conditions = new string[attrs.Length];
2820 for (int i = 0; i < conditions.Length; ++i)
2821 conditions[i] = attrs[i].GetConditionalAttributeValue ();
2823 caching_flags |= Flags.Excluded;
2828 public sealed class Struct : ClassOrStruct
2830 bool is_unmanaged, has_unmanaged_check_done;
2834 // Modifiers allowed in a struct declaration
2836 const Modifiers AllowedModifiers =
2839 Modifiers.PROTECTED |
2840 Modifiers.INTERNAL |
2844 public Struct (TypeContainer parent, MemberName name, Modifiers mod, Attributes attrs)
2845 : base (parent, name, attrs, MemberKind.Struct)
2847 var accmods = IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE;
2848 this.ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, accmods, Location, Report) | Modifiers.SEALED ;
2849 spec = new TypeSpec (Kind, null, this, null, ModFlags);
2852 public override AttributeTargets AttributeTargets {
2854 return AttributeTargets.Struct;
2858 public override void Accept (StructuralVisitor visitor)
2860 visitor.Visit (this);
2863 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
2865 base.ApplyAttributeBuilder (a, ctor, cdata, pa);
2868 // When struct constains fixed fixed and struct layout has explicitly
2869 // set CharSet, its value has to be propagated to compiler generated
2872 if (a.Type == pa.StructLayout) {
2873 var value = a.GetNamedValue ("CharSet");
2877 for (int i = 0; i < Members.Count; ++i) {
2878 FixedField ff = Members [i] as FixedField;
2882 ff.CharSet = (CharSet) System.Enum.Parse (typeof (CharSet), value.GetValue ().ToString ());
2887 bool CheckStructCycles ()
2893 foreach (var member in Members) {
2894 var field = member as Field;
2898 TypeSpec ftype = field.Spec.MemberType;
2899 if (!ftype.IsStruct)
2902 if (ftype is BuiltinTypeSpec)
2905 foreach (var targ in ftype.TypeArguments) {
2906 if (!CheckFieldTypeCycle (targ)) {
2907 Report.Error (523, field.Location,
2908 "Struct member `{0}' of type `{1}' causes a cycle in the struct layout",
2909 field.GetSignatureForError (), ftype.GetSignatureForError ());
2915 // Static fields of exactly same type are allowed
2917 if (field.IsStatic && ftype == CurrentType)
2920 if (!CheckFieldTypeCycle (ftype)) {
2921 Report.Error (523, field.Location,
2922 "Struct member `{0}' of type `{1}' causes a cycle in the struct layout",
2923 field.GetSignatureForError (), ftype.GetSignatureForError ());
2932 static bool CheckFieldTypeCycle (TypeSpec ts)
2934 var fts = ts.MemberDefinition as Struct;
2938 return fts.CheckStructCycles ();
2941 public override void Emit ()
2943 CheckStructCycles ();
2948 public override bool IsUnmanagedType ()
2950 if (has_unmanaged_check_done)
2951 return is_unmanaged;
2953 if (requires_delayed_unmanagedtype_check)
2956 var parent_def = Parent.PartialContainer;
2957 if (parent_def != null && parent_def.IsGenericOrParentIsGeneric) {
2958 has_unmanaged_check_done = true;
2962 if (first_nonstatic_field != null) {
2963 requires_delayed_unmanagedtype_check = true;
2965 foreach (var member in Members) {
2966 var f = member as Field;
2973 // It can happen when recursive unmanaged types are defined
2974 // struct S { S* s; }
2975 TypeSpec mt = f.MemberType;
2983 has_unmanaged_check_done = true;
2987 has_unmanaged_check_done = true;
2990 is_unmanaged = true;
2994 protected override TypeSpec[] ResolveBaseTypes (out FullNamedExpression base_class)
2996 var ifaces = base.ResolveBaseTypes (out base_class);
2997 base_type = Compiler.BuiltinTypes.ValueType;
3001 public override void RegisterFieldForInitialization (MemberCore field, FieldInitializer expression)
3003 if ((field.ModFlags & Modifiers.STATIC) == 0) {
3004 Report.Error (573, field.Location, "`{0}': Structs cannot have instance field initializers",
3005 field.GetSignatureForError ());
3008 base.RegisterFieldForInitialization (field, expression);
3016 public sealed class Interface : TypeDefinition {
3019 /// Modifiers allowed in a class declaration
3021 const Modifiers AllowedModifiers =
3024 Modifiers.PROTECTED |
3025 Modifiers.INTERNAL |
3029 public Interface (TypeContainer parent, MemberName name, Modifiers mod, Attributes attrs)
3030 : base (parent, name, attrs, MemberKind.Interface)
3032 var accmods = IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE;
3034 this.ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, accmods, name.Location, Report);
3035 spec = new TypeSpec (Kind, null, this, null, ModFlags);
3040 public override AttributeTargets AttributeTargets {
3042 return AttributeTargets.Interface;
3046 protected override TypeAttributes TypeAttr {
3048 const TypeAttributes DefaultTypeAttributes =
3049 TypeAttributes.AutoLayout |
3050 TypeAttributes.Abstract |
3051 TypeAttributes.Interface;
3053 return base.TypeAttr | DefaultTypeAttributes;
3059 public override void Accept (StructuralVisitor visitor)
3061 visitor.Visit (this);
3064 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
3066 if (a.Type == pa.ComImport && !attributes.Contains (pa.Guid)) {
3067 a.Error_MissingGuidAttribute ();
3071 base.ApplyAttributeBuilder (a, ctor, cdata, pa);
3074 protected override bool VerifyClsCompliance ()
3076 if (!base.VerifyClsCompliance ())
3079 if (iface_exprs != null) {
3080 foreach (var iface in iface_exprs) {
3081 if (iface.IsCLSCompliant ())
3084 Report.SymbolRelatedToPreviousError (iface);
3085 Report.Warning (3027, 1, Location, "`{0}' is not CLS-compliant because base interface `{1}' is not CLS-compliant",
3086 GetSignatureForError (), iface.GetSignatureForError ());
3094 public abstract class InterfaceMemberBase : MemberBase
3097 // Common modifiers allowed in a class declaration
3099 protected const Modifiers AllowedModifiersClass =
3102 Modifiers.PROTECTED |
3103 Modifiers.INTERNAL |
3108 Modifiers.OVERRIDE |
3109 Modifiers.ABSTRACT |
3114 // Common modifiers allowed in a struct declaration
3116 protected const Modifiers AllowedModifiersStruct =
3119 Modifiers.PROTECTED |
3120 Modifiers.INTERNAL |
3123 Modifiers.OVERRIDE |
3128 // Common modifiers allowed in a interface declaration
3130 protected const Modifiers AllowedModifiersInterface =
3135 // Whether this is an interface member.
3137 public bool IsInterface;
3140 // If true, this is an explicit interface implementation
3142 public readonly bool IsExplicitImpl;
3144 protected bool is_external_implementation;
3147 // The interface type we are explicitly implementing
3149 public TypeSpec InterfaceType;
3152 // The method we're overriding if this is an override method.
3154 protected MethodSpec base_method;
3156 readonly Modifiers explicit_mod_flags;
3157 public MethodAttributes flags;
3159 protected InterfaceMemberBase (TypeDefinition parent, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, MemberName name, Attributes attrs)
3160 : base (parent, type, mod, allowed_mod, Modifiers.PRIVATE, name, attrs)
3162 IsInterface = parent.Kind == MemberKind.Interface;
3163 IsExplicitImpl = (MemberName.ExplicitInterface != null);
3164 explicit_mod_flags = mod;
3167 public abstract Variance ExpectedMemberTypeVariance { get; }
3169 protected override bool CheckBase ()
3171 if (!base.CheckBase ())
3174 if ((caching_flags & Flags.MethodOverloadsExist) != 0)
3175 CheckForDuplications ();
3180 // For System.Object only
3181 if (Parent.BaseType == null)
3184 MemberSpec candidate;
3185 bool overrides = false;
3186 var base_member = FindBaseMember (out candidate, ref overrides);
3188 if ((ModFlags & Modifiers.OVERRIDE) != 0) {
3189 if (base_member == null) {
3190 if (candidate == null) {
3191 if (this is Method && ((Method)this).ParameterInfo.IsEmpty && MemberName.Name == Destructor.MetadataName && MemberName.Arity == 0) {
3192 Report.Error (249, Location, "Do not override `{0}'. Use destructor syntax instead",
3193 "object.Finalize()");
3195 Report.Error (115, Location, "`{0}' is marked as an override but no suitable {1} found to override",
3196 GetSignatureForError (), SimpleName.GetMemberType (this));
3199 Report.SymbolRelatedToPreviousError (candidate);
3201 Report.Error (72, Location, "`{0}': cannot override because `{1}' is not an event",
3202 GetSignatureForError (), TypeManager.GetFullNameSignature (candidate));
3203 else if (this is PropertyBase)
3204 Report.Error (544, Location, "`{0}': cannot override because `{1}' is not a property",
3205 GetSignatureForError (), TypeManager.GetFullNameSignature (candidate));
3207 Report.Error (505, Location, "`{0}': cannot override because `{1}' is not a method",
3208 GetSignatureForError (), TypeManager.GetFullNameSignature (candidate));
3215 // Handles ambiguous overrides
3217 if (candidate != null) {
3218 Report.SymbolRelatedToPreviousError (candidate);
3219 Report.SymbolRelatedToPreviousError (base_member);
3221 // Get member definition for error reporting
3222 var m1 = MemberCache.GetMember (base_member.DeclaringType.GetDefinition (), base_member);
3223 var m2 = MemberCache.GetMember (candidate.DeclaringType.GetDefinition (), candidate);
3225 Report.Error (462, Location,
3226 "`{0}' cannot override inherited members `{1}' and `{2}' because they have the same signature when used in type `{3}'",
3227 GetSignatureForError (), m1.GetSignatureForError (), m2.GetSignatureForError (), Parent.GetSignatureForError ());
3230 if (!CheckOverrideAgainstBase (base_member))
3233 ObsoleteAttribute oa = base_member.GetAttributeObsolete ();
3235 if (OptAttributes == null || !OptAttributes.Contains (Module.PredefinedAttributes.Obsolete)) {
3236 Report.SymbolRelatedToPreviousError (base_member);
3237 Report.Warning (672, 1, Location, "Member `{0}' overrides obsolete member `{1}'. Add the Obsolete attribute to `{0}'",
3238 GetSignatureForError (), base_member.GetSignatureForError ());
3241 if (OptAttributes != null && OptAttributes.Contains (Module.PredefinedAttributes.Obsolete)) {
3242 Report.SymbolRelatedToPreviousError (base_member);
3243 Report.Warning (809, 1, Location, "Obsolete member `{0}' overrides non-obsolete member `{1}'",
3244 GetSignatureForError (), base_member.GetSignatureForError ());
3248 base_method = base_member as MethodSpec;
3252 if (base_member == null && candidate != null && (!(candidate is IParametersMember) || !(this is IParametersMember)))
3253 base_member = candidate;
3255 if (base_member == null) {
3256 if ((ModFlags & Modifiers.NEW) != 0) {
3257 if (base_member == null) {
3258 Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required",
3259 GetSignatureForError ());
3263 if ((ModFlags & Modifiers.NEW) == 0) {
3264 ModFlags |= Modifiers.NEW;
3265 if (!IsCompilerGenerated) {
3266 Report.SymbolRelatedToPreviousError (base_member);
3267 if (!IsInterface && (base_member.Modifiers & (Modifiers.ABSTRACT | Modifiers.VIRTUAL | Modifiers.OVERRIDE)) != 0) {
3268 Report.Warning (114, 2, Location, "`{0}' hides inherited member `{1}'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword",
3269 GetSignatureForError (), base_member.GetSignatureForError ());
3271 Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
3272 GetSignatureForError (), base_member.GetSignatureForError ());
3277 if (!IsInterface && base_member.IsAbstract && !overrides && !IsStatic) {
3278 Report.SymbolRelatedToPreviousError (base_member);
3279 Report.Error (533, Location, "`{0}' hides inherited abstract member `{1}'",
3280 GetSignatureForError (), base_member.GetSignatureForError ());
3287 protected virtual bool CheckForDuplications ()
3289 return Parent.MemberCache.CheckExistingMembersOverloads (this, ParametersCompiled.EmptyReadOnlyParameters);
3293 // Performs various checks on the MethodInfo `mb' regarding the modifier flags
3294 // that have been defined.
3296 protected virtual bool CheckOverrideAgainstBase (MemberSpec base_member)
3300 if ((base_member.Modifiers & (Modifiers.ABSTRACT | Modifiers.VIRTUAL | Modifiers.OVERRIDE)) == 0) {
3301 Report.SymbolRelatedToPreviousError (base_member);
3302 Report.Error (506, Location,
3303 "`{0}': cannot override inherited member `{1}' because it is not marked virtual, abstract or override",
3304 GetSignatureForError (), TypeManager.CSharpSignature (base_member));
3308 // Now we check that the overriden method is not final
3309 if ((base_member.Modifiers & Modifiers.SEALED) != 0) {
3310 Report.SymbolRelatedToPreviousError (base_member);
3311 Report.Error (239, Location, "`{0}': cannot override inherited member `{1}' because it is sealed",
3312 GetSignatureForError (), TypeManager.CSharpSignature (base_member));
3316 var base_member_type = ((IInterfaceMemberSpec) base_member).MemberType;
3317 if (!TypeSpecComparer.Override.IsEqual (MemberType, base_member_type)) {
3318 Report.SymbolRelatedToPreviousError (base_member);
3319 if (this is PropertyBasedMember) {
3320 Report.Error (1715, Location, "`{0}': type must be `{1}' to match overridden member `{2}'",
3321 GetSignatureForError (), base_member_type.GetSignatureForError (), base_member.GetSignatureForError ());
3323 Report.Error (508, Location, "`{0}': return type must be `{1}' to match overridden member `{2}'",
3324 GetSignatureForError (), base_member_type.GetSignatureForError (), base_member.GetSignatureForError ());
3332 protected static bool CheckAccessModifiers (MemberCore this_member, MemberSpec base_member)
3334 var thisp = this_member.ModFlags & Modifiers.AccessibilityMask;
3335 var base_classp = base_member.Modifiers & Modifiers.AccessibilityMask;
3337 if ((base_classp & (Modifiers.PROTECTED | Modifiers.INTERNAL)) == (Modifiers.PROTECTED | Modifiers.INTERNAL)) {
3339 // It must be at least "protected"
3341 if ((thisp & Modifiers.PROTECTED) == 0) {
3346 // when overriding protected internal, the method can be declared
3347 // protected internal only within the same assembly or assembly
3348 // which has InternalsVisibleTo
3350 if ((thisp & Modifiers.INTERNAL) != 0) {
3351 return base_member.DeclaringType.MemberDefinition.IsInternalAsPublic (this_member.Module.DeclaringAssembly);
3355 // protected overriding protected internal inside same assembly
3356 // requires internal modifier as well
3358 if (base_member.DeclaringType.MemberDefinition.IsInternalAsPublic (this_member.Module.DeclaringAssembly)) {
3365 return thisp == base_classp;
3368 public override bool Define ()
3371 ModFlags = Modifiers.PUBLIC | Modifiers.ABSTRACT |
3372 Modifiers.VIRTUAL | (ModFlags & (Modifiers.UNSAFE | Modifiers.NEW));
3374 flags = MethodAttributes.Public |
3375 MethodAttributes.Abstract |
3376 MethodAttributes.HideBySig |
3377 MethodAttributes.NewSlot |
3378 MethodAttributes.Virtual;
3380 Parent.PartialContainer.MethodModifiersValid (this);
3382 flags = ModifiersExtensions.MethodAttr (ModFlags);
3385 if (IsExplicitImpl) {
3386 InterfaceType = MemberName.ExplicitInterface.ResolveAsType (Parent);
3387 if (InterfaceType == null)
3390 if ((ModFlags & Modifiers.PARTIAL) != 0) {
3391 Report.Error (754, Location, "A partial method `{0}' cannot explicitly implement an interface",
3392 GetSignatureForError ());
3395 if (!InterfaceType.IsInterface) {
3396 Report.SymbolRelatedToPreviousError (InterfaceType);
3397 Report.Error (538, Location, "The type `{0}' in explicit interface declaration is not an interface",
3398 InterfaceType.GetSignatureForError ());
3400 Parent.PartialContainer.VerifyImplements (this);
3403 Modifiers allowed_explicit = Modifiers.AllowedExplicitImplFlags;
3405 allowed_explicit |= Modifiers.ASYNC;
3407 ModifiersExtensions.Check (allowed_explicit, explicit_mod_flags, 0, Location, Report);
3410 return base.Define ();
3413 protected bool DefineParameters (ParametersCompiled parameters)
3415 if (!parameters.Resolve (this))
3419 for (int i = 0; i < parameters.Count; ++i) {
3420 Parameter p = parameters [i];
3422 if (p.HasDefaultValue && (IsExplicitImpl || this is Operator || (this is Indexer && parameters.Count == 1)))
3423 p.Warning_UselessOptionalParameter (Report);
3425 if (p.CheckAccessibility (this))
3428 TypeSpec t = parameters.Types [i];
3429 Report.SymbolRelatedToPreviousError (t);
3430 if (this is Indexer)
3431 Report.Error (55, Location,
3432 "Inconsistent accessibility: parameter type `{0}' is less accessible than indexer `{1}'",
3433 t.GetSignatureForError (), GetSignatureForError ());
3434 else if (this is Operator)
3435 Report.Error (57, Location,
3436 "Inconsistent accessibility: parameter type `{0}' is less accessible than operator `{1}'",
3437 t.GetSignatureForError (), GetSignatureForError ());
3439 Report.Error (51, Location,
3440 "Inconsistent accessibility: parameter type `{0}' is less accessible than method `{1}'",
3441 t.GetSignatureForError (), GetSignatureForError ());
3447 protected override void DoMemberTypeDependentChecks ()
3449 base.DoMemberTypeDependentChecks ();
3451 VarianceDecl.CheckTypeVariance (MemberType, ExpectedMemberTypeVariance, this);
3454 public override void Emit()
3456 // for extern static method must be specified either DllImport attribute or MethodImplAttribute.
3457 // We are more strict than csc and report this as an error because SRE does not allow emit that
3458 if ((ModFlags & Modifiers.EXTERN) != 0 && !is_external_implementation && (OptAttributes == null || !OptAttributes.HasResolveError ())) {
3459 if (this is Constructor) {
3460 Report.Warning (824, 1, Location,
3461 "Constructor `{0}' is marked `external' but has no external implementation specified", GetSignatureForError ());
3463 Report.Warning (626, 1, Location,
3464 "`{0}' is marked as an external but has no DllImport attribute. Consider adding a DllImport attribute to specify the external implementation",
3465 GetSignatureForError ());
3472 public override bool EnableOverloadChecks (MemberCore overload)
3475 // Two members can differ in their explicit interface
3476 // type parameter only
3478 InterfaceMemberBase imb = overload as InterfaceMemberBase;
3479 if (imb != null && imb.IsExplicitImpl) {
3480 if (IsExplicitImpl) {
3481 caching_flags |= Flags.MethodOverloadsExist;
3486 return IsExplicitImpl;
3489 protected void Error_CannotChangeAccessModifiers (MemberCore member, MemberSpec base_member)
3491 var base_modifiers = base_member.Modifiers;
3493 // Remove internal modifier from types which are not internally accessible
3494 if ((base_modifiers & Modifiers.AccessibilityMask) == (Modifiers.PROTECTED | Modifiers.INTERNAL) &&
3495 !base_member.DeclaringType.MemberDefinition.IsInternalAsPublic (member.Module.DeclaringAssembly))
3496 base_modifiers = Modifiers.PROTECTED;
3498 Report.SymbolRelatedToPreviousError (base_member);
3499 Report.Error (507, member.Location,
3500 "`{0}': cannot change access modifiers when overriding `{1}' inherited member `{2}'",
3501 member.GetSignatureForError (),
3502 ModifiersExtensions.AccessibilityName (base_modifiers),
3503 base_member.GetSignatureForError ());
3506 protected void Error_StaticReturnType ()
3508 Report.Error (722, Location,
3509 "`{0}': static types cannot be used as return types",
3510 MemberType.GetSignatureForError ());
3514 /// Gets base method and its return type
3516 protected virtual MemberSpec FindBaseMember (out MemberSpec bestCandidate, ref bool overrides)
3518 return MemberCache.FindBaseMember (this, out bestCandidate, ref overrides);
3522 // The "short" name of this property / indexer / event. This is the
3523 // name without the explicit interface.
3525 public string ShortName {
3526 get { return MemberName.Name; }
3530 // Returns full metadata method name
3532 public string GetFullName (MemberName name)
3534 return GetFullName (name.Name);
3537 public string GetFullName (string name)
3539 if (!IsExplicitImpl)
3543 // When dealing with explicit members a full interface type
3544 // name is added to member name to avoid possible name conflicts
3546 // We use CSharpName which gets us full name with benefit of
3547 // replacing predefined names which saves some space and name
3550 return InterfaceType.GetSignatureForError () + "." + name;
3553 public override string GetSignatureForDocumentation ()
3556 return Parent.GetSignatureForDocumentation () + "." + InterfaceType.GetExplicitNameSignatureForDocumentation () + "#" + ShortName;
3558 return Parent.GetSignatureForDocumentation () + "." + ShortName;
3561 public override bool IsUsed
3563 get { return IsExplicitImpl || base.IsUsed; }
3566 public override void SetConstraints (List<Constraints> constraints_list)
3568 if (((ModFlags & Modifiers.OVERRIDE) != 0 || IsExplicitImpl)) {
3569 Report.Error (460, Location,
3570 "`{0}': Cannot specify constraints for overrides and explicit interface implementation methods",
3571 GetSignatureForError ());
3574 base.SetConstraints (constraints_list);
3578 public abstract class MemberBase : MemberCore
3580 protected FullNamedExpression type_expr;
3581 protected TypeSpec member_type;
3582 public new TypeDefinition Parent;
3584 protected MemberBase (TypeDefinition parent, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, Modifiers def_mod, MemberName name, Attributes attrs)
3585 : base (parent, name, attrs)
3587 this.Parent = parent;
3588 this.type_expr = type;
3590 if (name != MemberName.Null)
3591 ModFlags = ModifiersExtensions.Check (allowed_mod, mod, def_mod, Location, Report);
3596 public TypeSpec MemberType {
3602 public FullNamedExpression TypeExpression {
3611 // Main member define entry
3613 public override bool Define ()
3615 DoMemberTypeIndependentChecks ();
3618 // Returns false only when type resolution failed
3620 if (!ResolveMemberType ())
3623 DoMemberTypeDependentChecks ();
3628 // Any type_name independent checks
3630 protected virtual void DoMemberTypeIndependentChecks ()
3632 if ((Parent.ModFlags & Modifiers.SEALED) != 0 &&
3633 (ModFlags & (Modifiers.VIRTUAL | Modifiers.ABSTRACT)) != 0) {
3634 Report.Error (549, Location, "New virtual member `{0}' is declared in a sealed class `{1}'",
3635 GetSignatureForError (), Parent.GetSignatureForError ());
3640 // Any type_name dependent checks
3642 protected virtual void DoMemberTypeDependentChecks ()
3644 // verify accessibility
3645 if (!IsAccessibleAs (MemberType)) {
3646 Report.SymbolRelatedToPreviousError (MemberType);
3647 if (this is Property)
3648 Report.Error (53, Location,
3649 "Inconsistent accessibility: property type `" +
3650 MemberType.GetSignatureForError () + "' is less " +
3651 "accessible than property `" + GetSignatureForError () + "'");
3652 else if (this is Indexer)
3653 Report.Error (54, Location,
3654 "Inconsistent accessibility: indexer return type `" +
3655 MemberType.GetSignatureForError () + "' is less " +
3656 "accessible than indexer `" + GetSignatureForError () + "'");
3657 else if (this is MethodCore) {
3658 if (this is Operator)
3659 Report.Error (56, Location,
3660 "Inconsistent accessibility: return type `" +
3661 MemberType.GetSignatureForError () + "' is less " +
3662 "accessible than operator `" + GetSignatureForError () + "'");
3664 Report.Error (50, Location,
3665 "Inconsistent accessibility: return type `" +
3666 MemberType.GetSignatureForError () + "' is less " +
3667 "accessible than method `" + GetSignatureForError () + "'");
3669 Report.Error (52, Location,
3670 "Inconsistent accessibility: field type `" +
3671 MemberType.GetSignatureForError () + "' is less " +
3672 "accessible than field `" + GetSignatureForError () + "'");
3677 protected void IsTypePermitted ()
3679 if (MemberType.IsSpecialRuntimeType) {
3680 if (Parent is StateMachine) {
3681 Report.Error (4012, Location,
3682 "Parameters or local variables of type `{0}' cannot be declared in async methods or iterators",
3683 MemberType.GetSignatureForError ());
3684 } else if (Parent is HoistedStoreyClass) {
3685 Report.Error (4013, Location,
3686 "Local variables of type `{0}' cannot be used inside anonymous methods, lambda expressions or query expressions",
3687 MemberType.GetSignatureForError ());
3689 Report.Error (610, Location,
3690 "Field or property cannot be of type `{0}'", MemberType.GetSignatureForError ());
3695 protected virtual bool CheckBase ()
3697 CheckProtectedModifier ();
3702 public override string GetSignatureForDocumentation ()
3704 return Parent.GetSignatureForDocumentation () + "." + MemberName.Basename;
3707 protected virtual bool ResolveMemberType ()
3709 if (member_type != null)
3710 throw new InternalErrorException ("Multi-resolve");
3712 member_type = type_expr.ResolveAsType (this);
3713 return member_type != null;