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)
17 using System.Collections.Generic;
18 using System.Runtime.InteropServices;
19 using System.Security;
20 using System.Security.Permissions;
22 using System.Diagnostics;
23 using Mono.CompilerServices.SymbolWriter;
26 using XmlElement = System.Object;
30 using SecurityType = System.Collections.Generic.List<IKVM.Reflection.Emit.CustomAttributeBuilder>;
31 using IKVM.Reflection;
32 using IKVM.Reflection.Emit;
34 using SecurityType = System.Collections.Generic.Dictionary<System.Security.Permissions.SecurityAction, System.Security.PermissionSet>;
35 using System.Reflection;
36 using System.Reflection.Emit;
42 // General types container, used as a base class for all constructs which can hold types
44 public abstract class TypeContainer : MemberCore
46 public readonly MemberKind Kind;
47 public readonly string Basename;
49 protected List<TypeContainer> containers;
51 TypeDefinition main_container;
53 protected Dictionary<string, MemberCore> defined_names;
55 protected bool is_defined;
57 public int CounterAnonymousMethods { get; set; }
58 public int CounterAnonymousContainers { get; set; }
59 public int CounterSwitchTypes { get; set; }
61 protected TypeContainer (TypeContainer parent, MemberName name, Attributes attrs, MemberKind kind)
62 : base (parent, name, attrs)
66 this.Basename = name.Basename;
68 defined_names = new Dictionary<string, MemberCore> ();
71 public override TypeSpec CurrentType {
77 public Dictionary<string, MemberCore> DefinedNames {
83 public TypeDefinition PartialContainer {
85 return main_container;
88 main_container = value;
92 public IList<TypeContainer> Containers {
99 // Any unattached attributes during parsing get added here. User
102 public Attributes UnattachedAttributes {
106 public void AddCompilerGeneratedClass (CompilerGeneratedContainer c)
108 AddTypeContainerMember (c);
111 public virtual void AddPartial (TypeDefinition next_part)
114 (PartialContainer ?? this).defined_names.TryGetValue (next_part.Basename, out mc);
116 AddPartial (next_part, mc as TypeDefinition);
119 protected void AddPartial (TypeDefinition next_part, TypeDefinition existing)
121 next_part.ModFlags |= Modifiers.PARTIAL;
123 if (existing == null) {
124 AddTypeContainer (next_part);
128 if ((existing.ModFlags & Modifiers.PARTIAL) == 0) {
129 if (existing.Kind != next_part.Kind) {
130 AddTypeContainer (next_part);
132 Report.SymbolRelatedToPreviousError (next_part);
133 Error_MissingPartialModifier (existing);
139 if (existing.Kind != next_part.Kind) {
140 Report.SymbolRelatedToPreviousError (existing);
141 Report.Error (261, next_part.Location,
142 "Partial declarations of `{0}' must be all classes, all structs or all interfaces",
143 next_part.GetSignatureForError ());
146 if ((existing.ModFlags & Modifiers.AccessibilityMask) != (next_part.ModFlags & Modifiers.AccessibilityMask) &&
147 ((existing.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) == 0 &&
148 (next_part.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) == 0)) {
149 Report.SymbolRelatedToPreviousError (existing);
150 Report.Error (262, next_part.Location,
151 "Partial declarations of `{0}' have conflicting accessibility modifiers",
152 next_part.GetSignatureForError ());
155 var tc_names = existing.CurrentTypeParameters;
156 if (tc_names != null) {
157 for (int i = 0; i < tc_names.Count; ++i) {
158 var tp = next_part.MemberName.TypeParameters[i];
159 if (tc_names[i].MemberName.Name != tp.MemberName.Name) {
160 Report.SymbolRelatedToPreviousError (existing.Location, "");
161 Report.Error (264, next_part.Location, "Partial declarations of `{0}' must have the same type parameter names in the same order",
162 next_part.GetSignatureForError ());
166 if (tc_names[i].Variance != tp.Variance) {
167 Report.SymbolRelatedToPreviousError (existing.Location, "");
168 Report.Error (1067, next_part.Location, "Partial declarations of `{0}' must have the same type parameter variance modifiers",
169 next_part.GetSignatureForError ());
175 if ((next_part.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) != 0) {
176 existing.ModFlags |= next_part.ModFlags & ~(Modifiers.DEFAULT_ACCESS_MODIFER | Modifiers.AccessibilityMask);
177 } else if ((existing.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) != 0) {
178 existing.ModFlags &= ~(Modifiers.DEFAULT_ACCESS_MODIFER | Modifiers.AccessibilityMask);
179 existing.ModFlags |= next_part.ModFlags;
181 existing.ModFlags |= next_part.ModFlags;
184 existing.Definition.Modifiers = existing.ModFlags;
186 if (next_part.attributes != null) {
187 if (existing.attributes == null)
188 existing.attributes = next_part.attributes;
190 existing.attributes.AddAttributes (next_part.attributes.Attrs);
193 next_part.PartialContainer = existing;
195 existing.AddPartialPart (next_part);
197 AddTypeContainerMember (next_part);
200 public virtual void AddTypeContainer (TypeContainer tc)
202 AddTypeContainerMember (tc);
204 var tparams = tc.MemberName.TypeParameters;
205 if (tparams != null && tc.PartialContainer != null) {
206 var td = (TypeDefinition) tc;
207 for (int i = 0; i < tparams.Count; ++i) {
209 if (tp.MemberName == null)
212 td.AddNameToContainer (tp, tp.Name);
217 protected virtual void AddTypeContainerMember (TypeContainer tc)
222 public virtual void CloseContainer ()
224 if (containers != null) {
225 foreach (TypeContainer tc in containers) {
226 tc.CloseContainer ();
231 public virtual void CreateMetadataName (StringBuilder sb)
233 if (Parent != null && Parent.MemberName != null)
234 Parent.CreateMetadataName (sb);
236 MemberName.CreateMetadataName (sb);
239 public virtual bool CreateContainer ()
241 if (containers != null) {
242 foreach (TypeContainer tc in containers) {
243 tc.CreateContainer ();
250 public override bool Define ()
252 if (containers != null) {
253 foreach (TypeContainer tc in containers) {
258 // Release cache used by parser only
259 if (Module.Evaluator == null) {
260 defined_names = null;
262 defined_names.Clear ();
268 public virtual void PrepareEmit ()
270 if (containers != null) {
271 foreach (var t in containers) {
274 } catch (Exception e) {
275 if (MemberName == MemberName.Null)
278 throw new InternalErrorException (t, e);
284 public virtual bool DefineContainer ()
291 DoDefineContainer ();
293 if (containers != null) {
294 foreach (TypeContainer tc in containers) {
296 tc.DefineContainer ();
297 } catch (Exception e) {
298 if (MemberName == MemberName.Null)
301 throw new InternalErrorException (tc, e);
309 public virtual void ExpandBaseInterfaces ()
311 if (containers != null) {
312 foreach (TypeContainer tc in containers) {
313 tc.ExpandBaseInterfaces ();
318 protected virtual void DefineNamespace ()
320 if (containers != null) {
321 foreach (var tc in containers) {
323 tc.DefineNamespace ();
324 } catch (Exception e) {
325 throw new InternalErrorException (tc, e);
331 protected virtual void DoDefineContainer ()
335 public virtual void EmitContainer ()
337 if (containers != null) {
338 for (int i = 0; i < containers.Count; ++i)
339 containers[i].EmitContainer ();
343 protected void Error_MissingPartialModifier (MemberCore type)
345 Report.Error (260, type.Location,
346 "Missing partial modifier on declaration of type `{0}'. Another partial declaration of this type exists",
347 type.GetSignatureForError ());
350 public override string GetSignatureForDocumentation ()
352 if (Parent != null && Parent.MemberName != null)
353 return Parent.GetSignatureForDocumentation () + "." + MemberName.GetSignatureForDocumentation ();
355 return MemberName.GetSignatureForDocumentation ();
358 public override string GetSignatureForError ()
360 if (Parent != null && Parent.MemberName != null)
361 return Parent.GetSignatureForError () + "." + MemberName.GetSignatureForError ();
363 return MemberName.GetSignatureForError ();
366 public string GetSignatureForMetadata ()
368 if (Parent is TypeDefinition) {
369 return Parent.GetSignatureForMetadata () + "+" + TypeNameParser.Escape (MemberName.Basename);
372 var sb = new StringBuilder ();
373 CreateMetadataName (sb);
374 return sb.ToString ();
377 public virtual void RemoveContainer (TypeContainer cont)
379 if (containers != null)
380 containers.Remove (cont);
382 var tc = Parent == Module ? Module : this;
383 tc.defined_names.Remove (cont.Basename);
386 public virtual void VerifyMembers ()
388 if (containers != null) {
389 foreach (TypeContainer tc in containers)
394 public override void WriteDebugSymbol (MonoSymbolFile file)
396 if (containers != null) {
397 foreach (TypeContainer tc in containers) {
398 tc.WriteDebugSymbol (file);
404 public abstract class TypeDefinition : TypeContainer, ITypeDefinition
407 // Different context is needed when resolving type container base
408 // types. Type names come from the parent scope but type parameter
409 // names from the container scope.
411 public struct BaseContext : IMemberContext
415 public BaseContext (TypeContainer tc)
420 #region IMemberContext Members
422 public CompilerContext Compiler {
423 get { return tc.Compiler; }
426 public TypeSpec CurrentType {
427 get { return tc.Parent.CurrentType; }
430 public TypeParameters CurrentTypeParameters {
431 get { return tc.PartialContainer.CurrentTypeParameters; }
434 public MemberCore CurrentMemberDefinition {
438 public bool IsObsolete {
439 get { return tc.IsObsolete; }
442 public bool IsUnsafe {
443 get { return tc.IsUnsafe; }
446 public bool IsStatic {
447 get { return tc.IsStatic; }
450 public ModuleContainer Module {
451 get { return tc.Module; }
454 public string GetSignatureForError ()
456 return tc.GetSignatureForError ();
459 public ExtensionMethodCandidates LookupExtensionMethod (TypeSpec extensionType, string name, int arity)
464 public FullNamedExpression LookupNamespaceAlias (string name)
466 return tc.Parent.LookupNamespaceAlias (name);
469 public FullNamedExpression LookupNamespaceOrType (string name, int arity, LookupMode mode, Location loc)
472 var tp = CurrentTypeParameters;
474 TypeParameter t = tp.Find (name);
476 return new TypeParameterExpr (t, loc);
480 return tc.Parent.LookupNamespaceOrType (name, arity, mode, loc);
490 GetHashCode = 1 << 1,
491 HasStaticFieldInitializer = 1 << 2
494 readonly List<MemberCore> members;
496 // Holds a list of fields that have initializers
497 protected List<FieldInitializer> initialized_fields;
499 // Holds a list of static fields that have initializers
500 protected List<FieldInitializer> initialized_static_fields;
502 Dictionary<MethodSpec, Method> hoisted_base_call_proxies;
504 Dictionary<string, FullNamedExpression> Cache = new Dictionary<string, FullNamedExpression> ();
507 // Points to the first non-static field added to the container.
509 // This is an arbitrary choice. We are interested in looking at _some_ non-static field,
510 // and the first one's as good as any.
512 protected FieldBase first_nonstatic_field;
515 // This one is computed after we can distinguish interfaces
516 // from classes from the arraylist `type_bases'
518 protected TypeSpec base_type;
519 FullNamedExpression base_type_expr; // TODO: It's temporary variable
520 protected TypeSpec[] iface_exprs;
522 protected List<FullNamedExpression> type_bases;
524 // Partial parts for classes only
525 List<TypeDefinition> class_partial_parts;
527 TypeDefinition InTransit;
529 public TypeBuilder TypeBuilder;
530 GenericTypeParameterBuilder[] all_tp_builders;
532 // All recursive type parameters put together sharing same
533 // TypeParameter instances
535 TypeParameters all_type_parameters;
537 public const string DefaultIndexerName = "Item";
539 bool has_normal_indexers;
541 protected bool requires_delayed_unmanagedtype_check;
543 bool members_defined;
544 bool members_defined_ok;
545 protected bool has_static_constructor;
547 private CachedMethods cached_method;
549 protected TypeSpec spec;
550 TypeSpec current_type;
552 public int DynamicSitesCounter;
553 public int AnonymousMethodsCounter;
554 public int MethodGroupsCounter;
556 static readonly string[] attribute_targets = new string[] { "type" };
559 /// The pending methods that need to be implemented
560 // (interfaces or abstract methods)
562 PendingImplementation pending;
564 protected TypeDefinition (TypeContainer parent, MemberName name, Attributes attrs, MemberKind kind)
565 : base (parent, name, attrs, kind)
567 PartialContainer = this;
568 members = new List<MemberCore> ();
573 public List<FullNamedExpression> BaseTypeExpressions {
579 public override TypeSpec CurrentType {
581 if (current_type == null) {
582 if (IsGenericOrParentIsGeneric) {
584 // Switch to inflated version as it's used by all expressions
586 var targs = CurrentTypeParameters == null ? TypeSpec.EmptyTypes : CurrentTypeParameters.Types;
587 current_type = spec.MakeGenericType (this, targs);
597 public override TypeParameters CurrentTypeParameters {
599 return PartialContainer.MemberName.TypeParameters;
603 int CurrentTypeParametersStartIndex {
605 int total = all_tp_builders.Length;
606 if (CurrentTypeParameters != null) {
607 return total - CurrentTypeParameters.Count;
613 public virtual AssemblyDefinition DeclaringAssembly {
615 return Module.DeclaringAssembly;
619 IAssemblyDefinition ITypeDefinition.DeclaringAssembly {
621 return Module.DeclaringAssembly;
625 public TypeSpec Definition {
631 public bool HasMembersDefined {
633 return members_defined;
637 public bool HasInstanceConstructor {
639 return (caching_flags & Flags.HasInstanceConstructor) != 0;
642 caching_flags |= Flags.HasInstanceConstructor;
646 // Indicated whether container has StructLayout attribute set Explicit
647 public bool HasExplicitLayout {
648 get { return (caching_flags & Flags.HasExplicitLayout) != 0; }
649 set { caching_flags |= Flags.HasExplicitLayout; }
652 public bool HasOperators {
654 return (caching_flags & Flags.HasUserOperators) != 0;
657 caching_flags |= Flags.HasUserOperators;
661 public bool HasStructLayout {
662 get { return (caching_flags & Flags.HasStructLayout) != 0; }
663 set { caching_flags |= Flags.HasStructLayout; }
666 public TypeSpec[] Interfaces {
672 public bool IsGenericOrParentIsGeneric {
674 return all_type_parameters != null;
678 public bool IsTopLevel {
680 return !(Parent is TypeDefinition);
684 public bool IsPartial {
686 return (ModFlags & Modifiers.PARTIAL) != 0;
690 bool ITypeDefinition.IsTypeForwarder {
696 bool ITypeDefinition.IsCyclicTypeForwarder {
703 // Returns true for secondary partial containers
707 return PartialContainer != this;
711 public MemberCache MemberCache {
713 return spec.MemberCache;
717 public List<MemberCore> Members {
723 string ITypeDefinition.Namespace {
726 while (p.Kind != MemberKind.Namespace)
729 return p.MemberName == null ? null : p.GetSignatureForError ();
733 public TypeParameters TypeParametersAll {
735 return all_type_parameters;
739 public override string[] ValidAttributeTargets {
741 return attribute_targets;
747 public override void Accept (StructuralVisitor visitor)
749 visitor.Visit (this);
752 public void AddMember (MemberCore symbol)
754 if (symbol.MemberName.ExplicitInterface != null) {
755 if (!(Kind == MemberKind.Class || Kind == MemberKind.Struct)) {
756 Report.Error (541, symbol.Location,
757 "`{0}': explicit interface declaration can only be declared in a class or struct",
758 symbol.GetSignatureForError ());
762 AddNameToContainer (symbol, symbol.MemberName.Name);
763 members.Add (symbol);
766 public override void AddTypeContainer (TypeContainer tc)
768 AddNameToContainer (tc, tc.Basename);
770 base.AddTypeContainer (tc);
773 protected override void AddTypeContainerMember (TypeContainer tc)
777 if (containers == null)
778 containers = new List<TypeContainer> ();
780 base.AddTypeContainerMember (tc);
784 // Adds the member to defined_names table. It tests for duplications and enclosing name conflicts
786 public virtual void AddNameToContainer (MemberCore symbol, string name)
788 if (((ModFlags | symbol.ModFlags) & Modifiers.COMPILER_GENERATED) != 0)
792 if (!PartialContainer.defined_names.TryGetValue (name, out mc)) {
793 PartialContainer.defined_names.Add (name, symbol);
797 if (symbol.EnableOverloadChecks (mc))
800 InterfaceMemberBase im = mc as InterfaceMemberBase;
801 if (im != null && im.IsExplicitImpl)
804 Report.SymbolRelatedToPreviousError (mc);
805 if ((mc.ModFlags & Modifiers.PARTIAL) != 0 && (symbol is ClassOrStruct || symbol is Interface)) {
806 Error_MissingPartialModifier (symbol);
810 if (symbol is TypeParameter) {
811 Report.Error (692, symbol.Location,
812 "Duplicate type parameter `{0}'", symbol.GetSignatureForError ());
814 Report.Error (102, symbol.Location,
815 "The type `{0}' already contains a definition for `{1}'",
816 GetSignatureForError (), name);
822 public void AddConstructor (Constructor c)
824 AddConstructor (c, false);
827 public void AddConstructor (Constructor c, bool isDefault)
829 bool is_static = (c.ModFlags & Modifiers.STATIC) != 0;
831 AddNameToContainer (c, is_static ? Constructor.TypeConstructorName : Constructor.ConstructorName);
833 if (is_static && c.ParameterInfo.IsEmpty) {
834 PartialContainer.has_static_constructor = true;
836 PartialContainer.HasInstanceConstructor = true;
842 public bool AddField (FieldBase field)
846 if ((field.ModFlags & Modifiers.STATIC) != 0)
849 var first_field = PartialContainer.first_nonstatic_field;
850 if (first_field == null) {
851 PartialContainer.first_nonstatic_field = field;
855 if (Kind == MemberKind.Struct && first_field.Parent != field.Parent) {
856 Report.SymbolRelatedToPreviousError (first_field.Parent);
857 Report.Warning (282, 3, field.Location,
858 "struct instance field `{0}' found in different declaration from instance field `{1}'",
859 field.GetSignatureForError (), first_field.GetSignatureForError ());
865 /// Indexer has special handling in constrast to other AddXXX because the name can be driven by IndexerNameAttribute
867 public void AddIndexer (Indexer i)
872 public void AddOperator (Operator op)
874 PartialContainer.HasOperators = true;
878 public void AddPartialPart (TypeDefinition part)
880 if (Kind != MemberKind.Class)
883 if (class_partial_parts == null)
884 class_partial_parts = new List<TypeDefinition> ();
886 class_partial_parts.Add (part);
889 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
891 if (has_normal_indexers && a.Type == pa.DefaultMember) {
892 Report.Error (646, a.Location, "Cannot specify the `DefaultMember' attribute on type containing an indexer");
896 if (a.Type == pa.Required) {
897 Report.Error (1608, a.Location, "The RequiredAttribute attribute is not permitted on C# types");
901 TypeBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
904 public override AttributeTargets AttributeTargets {
906 throw new NotSupportedException ();
910 public TypeSpec BaseType {
912 return spec.BaseType;
916 protected virtual TypeAttributes TypeAttr {
918 return ModifiersExtensions.TypeAttr (ModFlags, IsTopLevel);
922 public int TypeParametersCount {
924 return MemberName.Arity;
928 TypeParameterSpec[] ITypeDefinition.TypeParameters {
930 return PartialContainer.CurrentTypeParameters.Types;
934 public string GetAttributeDefaultMember ()
936 return indexer_name ?? DefaultIndexerName;
939 public bool IsComImport {
941 if (OptAttributes == null)
944 return OptAttributes.Contains (Module.PredefinedAttributes.ComImport);
948 public virtual void RegisterFieldForInitialization (MemberCore field, FieldInitializer expression)
951 PartialContainer.RegisterFieldForInitialization (field, expression);
953 if ((field.ModFlags & Modifiers.STATIC) != 0){
954 if (initialized_static_fields == null) {
955 HasStaticFieldInitializer = true;
956 initialized_static_fields = new List<FieldInitializer> (4);
959 initialized_static_fields.Add (expression);
961 if (initialized_fields == null)
962 initialized_fields = new List<FieldInitializer> (4);
964 initialized_fields.Add (expression);
968 public void ResolveFieldInitializers (BlockContext ec)
970 Debug.Assert (!IsPartialPart);
973 if (initialized_static_fields == null)
976 bool has_complex_initializer = !ec.Module.Compiler.Settings.Optimize;
978 ExpressionStatement [] init = new ExpressionStatement [initialized_static_fields.Count];
979 for (i = 0; i < initialized_static_fields.Count; ++i) {
980 FieldInitializer fi = initialized_static_fields [i];
981 ExpressionStatement s = fi.ResolveStatement (ec);
983 s = EmptyExpressionStatement.Instance;
984 } else if (!fi.IsSideEffectFree) {
985 has_complex_initializer = true;
991 for (i = 0; i < initialized_static_fields.Count; ++i) {
992 FieldInitializer fi = initialized_static_fields [i];
994 // Need special check to not optimize code like this
995 // static int a = b = 5;
998 if (!has_complex_initializer && fi.IsDefaultInitializer)
1001 ec.AssignmentInfoOffset += fi.AssignmentOffset;
1002 ec.CurrentBlock.AddScopeStatement (new StatementExpression (init [i]));
1008 if (initialized_fields == null)
1011 for (int i = 0; i < initialized_fields.Count; ++i) {
1012 FieldInitializer fi = initialized_fields [i];
1013 ExpressionStatement s = fi.ResolveStatement (ec);
1018 // Field is re-initialized to its default value => removed
1020 if (fi.IsDefaultInitializer && ec.Module.Compiler.Settings.Optimize)
1023 ec.AssignmentInfoOffset += fi.AssignmentOffset;
1024 ec.CurrentBlock.AddScopeStatement (new StatementExpression (s));
1028 public override string DocComment {
1040 public PendingImplementation PendingImplementations {
1041 get { return pending; }
1044 internal override void GenerateDocComment (DocumentationBuilder builder)
1049 base.GenerateDocComment (builder);
1051 foreach (var member in members)
1052 member.GenerateDocComment (builder);
1055 public TypeSpec GetAttributeCoClass ()
1057 if (OptAttributes == null)
1060 Attribute a = OptAttributes.Search (Module.PredefinedAttributes.CoClass);
1064 return a.GetCoClassAttributeValue ();
1067 public AttributeUsageAttribute GetAttributeUsage (PredefinedAttribute pa)
1070 if (OptAttributes != null) {
1071 a = OptAttributes.Search (pa);
1077 return a.GetAttributeUsageAttribute ();
1080 public virtual CompilationSourceFile GetCompilationSourceFile ()
1082 TypeContainer ns = Parent;
1084 var sf = ns as CompilationSourceFile;
1092 public virtual void SetBaseTypes (List<FullNamedExpression> baseTypes)
1094 type_bases = baseTypes;
1098 /// This function computes the Base class and also the
1099 /// list of interfaces that the class or struct @c implements.
1101 /// The return value is an array (might be null) of
1102 /// interfaces implemented (as Types).
1104 /// The @base_class argument is set to the base object or null
1105 /// if this is `System.Object'.
1107 protected virtual TypeSpec[] ResolveBaseTypes (out FullNamedExpression base_class)
1110 if (type_bases == null)
1113 int count = type_bases.Count;
1114 TypeSpec[] ifaces = null;
1115 var base_context = new BaseContext (this);
1116 for (int i = 0, j = 0; i < count; i++){
1117 FullNamedExpression fne = type_bases [i];
1119 var fne_resolved = fne.ResolveAsType (base_context);
1120 if (fne_resolved == null)
1123 if (i == 0 && Kind == MemberKind.Class && !fne_resolved.IsInterface) {
1124 if (fne_resolved.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
1125 Report.Error (1965, Location, "Class `{0}' cannot derive from the dynamic type",
1126 GetSignatureForError ());
1131 base_type = fne_resolved;
1137 ifaces = new TypeSpec [count - i];
1139 if (fne_resolved.IsInterface) {
1140 for (int ii = 0; ii < j; ++ii) {
1141 if (fne_resolved == ifaces [ii]) {
1142 Report.Error (528, Location, "`{0}' is already listed in interface list",
1143 fne_resolved.GetSignatureForError ());
1148 if (Kind == MemberKind.Interface && !IsAccessibleAs (fne_resolved)) {
1149 Report.Error (61, fne.Location,
1150 "Inconsistent accessibility: base interface `{0}' is less accessible than interface `{1}'",
1151 fne_resolved.GetSignatureForError (), GetSignatureForError ());
1154 Report.SymbolRelatedToPreviousError (fne_resolved);
1155 if (Kind != MemberKind.Class) {
1156 Report.Error (527, fne.Location, "Type `{0}' in interface list is not an interface", fne_resolved.GetSignatureForError ());
1157 } else if (base_class != null)
1158 Report.Error (1721, fne.Location, "`{0}': Classes cannot have multiple base classes (`{1}' and `{2}')",
1159 GetSignatureForError (), base_class.GetSignatureForError (), fne_resolved.GetSignatureForError ());
1161 Report.Error (1722, fne.Location, "`{0}': Base class `{1}' must be specified as first",
1162 GetSignatureForError (), fne_resolved.GetSignatureForError ());
1166 ifaces [j++] = fne_resolved;
1173 // Checks that some operators come in pairs:
1179 // They are matched based on the return type and the argument types
1181 void CheckPairedOperators ()
1183 bool has_equality_or_inequality = false;
1184 List<Operator.OpType> found_matched = new List<Operator.OpType> ();
1186 for (int i = 0; i < members.Count; ++i) {
1187 var o_a = members[i] as Operator;
1191 var o_type = o_a.OperatorType;
1192 if (o_type == Operator.OpType.Equality || o_type == Operator.OpType.Inequality)
1193 has_equality_or_inequality = true;
1195 if (found_matched.Contains (o_type))
1198 var matching_type = o_a.GetMatchingOperator ();
1199 if (matching_type == Operator.OpType.TOP) {
1203 bool pair_found = false;
1204 for (int ii = 0; ii < members.Count; ++ii) {
1205 var o_b = members[ii] as Operator;
1206 if (o_b == null || o_b.OperatorType != matching_type)
1209 if (!TypeSpecComparer.IsEqual (o_a.ReturnType, o_b.ReturnType))
1212 if (!TypeSpecComparer.Equals (o_a.ParameterTypes, o_b.ParameterTypes))
1215 found_matched.Add (matching_type);
1221 Report.Error (216, o_a.Location,
1222 "The operator `{0}' requires a matching operator `{1}' to also be defined",
1223 o_a.GetSignatureForError (), Operator.GetName (matching_type));
1227 if (has_equality_or_inequality) {
1229 Report.Warning (660, 2, Location, "`{0}' defines operator == or operator != but does not override Object.Equals(object o)",
1230 GetSignatureForError ());
1232 if (!HasGetHashCode)
1233 Report.Warning (661, 2, Location, "`{0}' defines operator == or operator != but does not override Object.GetHashCode()",
1234 GetSignatureForError ());
1238 public override void CreateMetadataName (StringBuilder sb)
1240 if (Parent.MemberName != null) {
1241 Parent.CreateMetadataName (sb);
1243 if (sb.Length != 0) {
1248 sb.Append (MemberName.Basename);
1251 bool CreateTypeBuilder ()
1254 // Sets .size to 1 for structs with no instance fields
1256 int type_size = Kind == MemberKind.Struct && first_nonstatic_field == null && !(this is StateMachine) ? 1 : 0;
1258 var parent_def = Parent as TypeDefinition;
1259 if (parent_def == null) {
1260 var sb = new StringBuilder ();
1261 CreateMetadataName (sb);
1262 TypeBuilder = Module.CreateBuilder (sb.ToString (), TypeAttr, type_size);
1264 TypeBuilder = parent_def.TypeBuilder.DefineNestedType (Basename, TypeAttr, null, type_size);
1267 if (DeclaringAssembly.Importer != null)
1268 DeclaringAssembly.Importer.AddCompiledType (TypeBuilder, spec);
1270 spec.SetMetaInfo (TypeBuilder);
1271 spec.MemberCache = new MemberCache (this);
1273 TypeParameters parentAllTypeParameters = null;
1274 if (parent_def != null) {
1275 spec.DeclaringType = Parent.CurrentType;
1276 parent_def.MemberCache.AddMember (spec);
1277 parentAllTypeParameters = parent_def.all_type_parameters;
1280 if (MemberName.TypeParameters != null || parentAllTypeParameters != null) {
1281 var tparam_names = CreateTypeParameters (parentAllTypeParameters);
1283 all_tp_builders = TypeBuilder.DefineGenericParameters (tparam_names);
1285 if (CurrentTypeParameters != null) {
1286 CurrentTypeParameters.Create (spec, CurrentTypeParametersStartIndex, this);
1287 CurrentTypeParameters.Define (all_tp_builders);
1294 string[] CreateTypeParameters (TypeParameters parentAllTypeParameters)
1297 int parent_offset = 0;
1298 if (parentAllTypeParameters != null) {
1299 if (CurrentTypeParameters == null) {
1300 all_type_parameters = parentAllTypeParameters;
1301 return parentAllTypeParameters.GetAllNames ();
1304 names = new string[parentAllTypeParameters.Count + CurrentTypeParameters.Count];
1305 all_type_parameters = new TypeParameters (names.Length);
1306 all_type_parameters.Add (parentAllTypeParameters);
1308 parent_offset = all_type_parameters.Count;
1309 for (int i = 0; i < parent_offset; ++i)
1310 names[i] = all_type_parameters[i].MemberName.Name;
1313 names = new string[CurrentTypeParameters.Count];
1316 for (int i = 0; i < CurrentTypeParameters.Count; ++i) {
1317 if (all_type_parameters != null)
1318 all_type_parameters.Add (MemberName.TypeParameters[i]);
1320 var name = CurrentTypeParameters[i].MemberName.Name;
1321 names[parent_offset + i] = name;
1322 for (int ii = 0; ii < parent_offset + i; ++ii) {
1323 if (names[ii] != name)
1326 var tp = CurrentTypeParameters[i];
1327 var conflict = all_type_parameters[ii];
1329 tp.WarningParentNameConflict (conflict);
1333 if (all_type_parameters == null)
1334 all_type_parameters = CurrentTypeParameters;
1340 public SourceMethodBuilder CreateMethodSymbolEntry ()
1342 if (Module.DeclaringAssembly.SymbolWriter == null)
1345 var source_file = GetCompilationSourceFile ();
1346 if (source_file == null)
1349 return new SourceMethodBuilder (source_file.SymbolUnitEntry);
1353 // Creates a proxy base method call inside this container for hoisted base member calls
1355 public MethodSpec CreateHoistedBaseCallProxy (ResolveContext rc, MethodSpec method)
1357 Method proxy_method;
1360 // One proxy per base method is enough
1362 if (hoisted_base_call_proxies == null) {
1363 hoisted_base_call_proxies = new Dictionary<MethodSpec, Method> ();
1364 proxy_method = null;
1366 hoisted_base_call_proxies.TryGetValue (method, out proxy_method);
1369 if (proxy_method == null) {
1370 string name = CompilerGeneratedContainer.MakeName (method.Name, null, "BaseCallProxy", hoisted_base_call_proxies.Count);
1372 MemberName member_name;
1373 TypeArguments targs = null;
1374 TypeSpec return_type = method.ReturnType;
1375 var local_param_types = method.Parameters.Types;
1377 if (method.IsGeneric) {
1379 // Copy all base generic method type parameters info
1381 var hoisted_tparams = method.GenericDefinition.TypeParameters;
1382 var tparams = new TypeParameters ();
1384 targs = new TypeArguments ();
1385 targs.Arguments = new TypeSpec[hoisted_tparams.Length];
1386 for (int i = 0; i < hoisted_tparams.Length; ++i) {
1387 var tp = hoisted_tparams[i];
1388 var local_tp = new TypeParameter (tp, null, new MemberName (tp.Name, Location), null);
1389 tparams.Add (local_tp);
1391 targs.Add (new SimpleName (tp.Name, Location));
1392 targs.Arguments[i] = local_tp.Type;
1395 member_name = new MemberName (name, tparams, Location);
1398 // Mutate any method type parameters from original
1399 // to newly created hoisted version
1401 var mutator = new TypeParameterMutator (hoisted_tparams, tparams);
1402 return_type = mutator.Mutate (return_type);
1403 local_param_types = mutator.Mutate (local_param_types);
1405 member_name = new MemberName (name);
1408 var base_parameters = new Parameter[method.Parameters.Count];
1409 for (int i = 0; i < base_parameters.Length; ++i) {
1410 var base_param = method.Parameters.FixedParameters[i];
1411 base_parameters[i] = new Parameter (new TypeExpression (local_param_types [i], Location),
1412 base_param.Name, base_param.ModFlags, null, Location);
1413 base_parameters[i].Resolve (this, i);
1416 var cloned_params = ParametersCompiled.CreateFullyResolved (base_parameters, method.Parameters.Types);
1417 if (method.Parameters.HasArglist) {
1418 cloned_params.FixedParameters[0] = new Parameter (null, "__arglist", Parameter.Modifier.NONE, null, Location);
1419 cloned_params.Types[0] = Module.PredefinedTypes.RuntimeArgumentHandle.Resolve ();
1422 // Compiler generated proxy
1423 proxy_method = new Method (this, new TypeExpression (return_type, Location),
1424 Modifiers.PRIVATE | Modifiers.COMPILER_GENERATED | Modifiers.DEBUGGER_HIDDEN,
1425 member_name, cloned_params, null);
1427 var block = new ToplevelBlock (Compiler, proxy_method.ParameterInfo, Location) {
1428 IsCompilerGenerated = true
1431 var mg = MethodGroupExpr.CreatePredefined (method, method.DeclaringType, Location);
1432 mg.InstanceExpression = new BaseThis (method.DeclaringType, Location);
1434 mg.SetTypeArguments (rc, targs);
1436 // Get all the method parameters and pass them as arguments
1437 var real_base_call = new Invocation (mg, block.GetAllParametersArguments ());
1438 Statement statement;
1439 if (method.ReturnType.Kind == MemberKind.Void)
1440 statement = new StatementExpression (real_base_call);
1442 statement = new Return (real_base_call, Location);
1444 block.AddStatement (statement);
1445 proxy_method.Block = block;
1447 members.Add (proxy_method);
1448 proxy_method.Define ();
1449 proxy_method.PrepareEmit ();
1451 hoisted_base_call_proxies.Add (method, proxy_method);
1454 return proxy_method.Spec;
1457 protected bool DefineBaseTypes ()
1459 if (IsPartialPart && Kind == MemberKind.Class)
1462 return DoDefineBaseType ();
1465 bool DoDefineBaseType ()
1467 iface_exprs = ResolveBaseTypes (out base_type_expr);
1470 if (IsPartialPart) {
1471 set_base_type = false;
1473 if (base_type_expr != null) {
1474 if (PartialContainer.base_type_expr != null && PartialContainer.base_type != base_type) {
1475 Report.SymbolRelatedToPreviousError (base_type_expr.Location, "");
1476 Report.Error (263, Location,
1477 "Partial declarations of `{0}' must not specify different base classes",
1478 GetSignatureForError ());
1480 PartialContainer.base_type_expr = base_type_expr;
1481 PartialContainer.base_type = base_type;
1482 set_base_type = true;
1486 if (iface_exprs != null) {
1487 if (PartialContainer.iface_exprs == null)
1488 PartialContainer.iface_exprs = iface_exprs;
1490 var ifaces = new List<TypeSpec> (PartialContainer.iface_exprs);
1491 foreach (var iface_partial in iface_exprs) {
1492 if (ifaces.Contains (iface_partial))
1495 ifaces.Add (iface_partial);
1498 PartialContainer.iface_exprs = ifaces.ToArray ();
1502 PartialContainer.members.AddRange (members);
1503 if (containers != null) {
1504 if (PartialContainer.containers == null)
1505 PartialContainer.containers = new List<TypeContainer> ();
1507 PartialContainer.containers.AddRange (containers);
1510 members_defined = members_defined_ok = true;
1511 caching_flags |= Flags.CloseTypeCreated;
1513 set_base_type = true;
1516 var cycle = CheckRecursiveDefinition (this);
1517 if (cycle != null) {
1518 Report.SymbolRelatedToPreviousError (cycle);
1519 if (this is Interface) {
1520 Report.Error (529, Location,
1521 "Inherited interface `{0}' causes a cycle in the interface hierarchy of `{1}'",
1522 GetSignatureForError (), cycle.GetSignatureForError ());
1525 PartialContainer.iface_exprs = null;
1527 Report.Error (146, Location,
1528 "Circular base class dependency involving `{0}' and `{1}'",
1529 GetSignatureForError (), cycle.GetSignatureForError ());
1532 PartialContainer.base_type = null;
1536 if (iface_exprs != null) {
1537 foreach (var iface_type in iface_exprs) {
1538 // Prevents a crash, the interface might not have been resolved: 442144
1539 if (iface_type == null)
1542 if (!spec.AddInterfaceDefined (iface_type))
1545 TypeBuilder.AddInterfaceImplementation (iface_type.GetMetaInfo ());
1549 if (Kind == MemberKind.Interface) {
1550 spec.BaseType = Compiler.BuiltinTypes.Object;
1554 if (set_base_type) {
1559 // Base type of partial container has to be resolved before we
1560 // resolve any nested types of the container. We need to know
1561 // partial parts because the base type can be specified in file
1562 // defined after current container
1564 if (class_partial_parts != null) {
1565 foreach (var pp in class_partial_parts)
1566 pp.DoDefineBaseType ();
1575 if (base_type == null) {
1576 TypeBuilder.SetParent (null);
1580 if (spec.BaseType == base_type)
1583 spec.BaseType = base_type;
1586 spec.UpdateInflatedInstancesBaseType ();
1588 // Set base type after type creation
1589 TypeBuilder.SetParent (base_type.GetMetaInfo ());
1592 public override void ExpandBaseInterfaces ()
1595 DoExpandBaseInterfaces ();
1597 base.ExpandBaseInterfaces ();
1600 public void DoExpandBaseInterfaces ()
1602 if ((caching_flags & Flags.InterfacesExpanded) != 0)
1605 caching_flags |= Flags.InterfacesExpanded;
1608 // Expand base interfaces. It cannot be done earlier because all partial
1609 // interface parts need to be defined before the type they are used from
1611 if (iface_exprs != null) {
1612 foreach (var iface in iface_exprs) {
1616 var td = iface.MemberDefinition as TypeDefinition;
1618 td.DoExpandBaseInterfaces ();
1620 if (iface.Interfaces == null)
1623 foreach (var biface in iface.Interfaces) {
1624 if (spec.AddInterfaceDefined (biface)) {
1625 TypeBuilder.AddInterfaceImplementation (biface.GetMetaInfo ());
1632 // Include all base type interfaces too, see ImportTypeBase for details
1634 if (base_type != null) {
1635 var td = base_type.MemberDefinition as TypeDefinition;
1637 td.DoExpandBaseInterfaces ();
1640 // Simply use base interfaces only, they are all expanded which makes
1641 // it easy to handle generic type argument propagation with single
1644 // interface IA<T> : IB<T>
1645 // interface IB<U> : IC<U>
1648 if (base_type.Interfaces != null) {
1649 foreach (var iface in base_type.Interfaces) {
1650 spec.AddInterfaceDefined (iface);
1656 public override void PrepareEmit ()
1658 if ((caching_flags & Flags.CloseTypeCreated) != 0)
1661 foreach (var member in members) {
1662 var pm = member as IParametersMember;
1664 var mc = member as MethodOrOperator;
1669 var p = pm.Parameters;
1673 ((ParametersCompiled) p).ResolveDefaultValues (member);
1676 var c = member as Const;
1681 base.PrepareEmit ();
1685 // Defines the type in the appropriate ModuleBuilder or TypeBuilder.
1687 public override bool CreateContainer ()
1689 if (TypeBuilder != null)
1695 if (IsPartialPart) {
1696 spec = PartialContainer.spec;
1697 TypeBuilder = PartialContainer.TypeBuilder;
1698 all_tp_builders = PartialContainer.all_tp_builders;
1699 all_type_parameters = PartialContainer.all_type_parameters;
1701 if (!CreateTypeBuilder ()) {
1707 return base.CreateContainer ();
1710 protected override void DoDefineContainer ()
1714 DoResolveTypeParameters ();
1718 // Replaces normal spec with predefined one when compiling corlib
1719 // and this type container defines predefined type
1721 public void SetPredefinedSpec (BuiltinTypeSpec spec)
1723 // When compiling build-in types we start with two
1724 // version of same type. One is of BuiltinTypeSpec and
1725 // second one is ordinary TypeSpec. The unification
1726 // happens at later stage when we know which type
1727 // really matches the builtin type signature. However
1728 // that means TypeSpec create during CreateType of this
1729 // type has to be replaced with builtin one
1731 spec.SetMetaInfo (TypeBuilder);
1732 spec.MemberCache = this.spec.MemberCache;
1733 spec.DeclaringType = this.spec.DeclaringType;
1736 current_type = null;
1739 public override void RemoveContainer (TypeContainer cont)
1741 base.RemoveContainer (cont);
1742 Members.Remove (cont);
1743 Cache.Remove (cont.Basename);
1746 protected virtual bool DoResolveTypeParameters ()
1748 var tparams = CurrentTypeParameters;
1749 if (tparams == null)
1752 var base_context = new BaseContext (this);
1753 for (int i = 0; i < tparams.Count; ++i) {
1754 var tp = tparams[i];
1756 if (!tp.ResolveConstraints (base_context)) {
1762 if (IsPartialPart) {
1763 PartialContainer.CurrentTypeParameters.UpdateConstraints (this);
1769 TypeSpec CheckRecursiveDefinition (TypeDefinition tc)
1771 if (InTransit != null)
1776 if (base_type != null) {
1777 var ptc = base_type.MemberDefinition as TypeDefinition;
1778 if (ptc != null && ptc.CheckRecursiveDefinition (this) != null)
1782 if (iface_exprs != null) {
1783 foreach (var iface in iface_exprs) {
1784 // the interface might not have been resolved, prevents a crash, see #442144
1787 var ptc = iface.MemberDefinition as Interface;
1788 if (ptc != null && ptc.CheckRecursiveDefinition (this) != null)
1793 if (!IsTopLevel && Parent.PartialContainer.CheckRecursiveDefinition (this) != null)
1801 /// Populates our TypeBuilder with fields and methods
1803 public sealed override bool Define ()
1805 if (members_defined)
1806 return members_defined_ok;
1808 members_defined_ok = DoDefineMembers ();
1809 members_defined = true;
1813 return members_defined_ok;
1816 protected virtual bool DoDefineMembers ()
1818 Debug.Assert (!IsPartialPart);
1820 if (iface_exprs != null) {
1821 foreach (var iface_type in iface_exprs) {
1822 if (iface_type == null)
1825 // Ensure the base is always setup
1826 var compiled_iface = iface_type.MemberDefinition as Interface;
1827 if (compiled_iface != null)
1828 compiled_iface.Define ();
1830 ObsoleteAttribute oa = iface_type.GetAttributeObsolete ();
1831 if (oa != null && !IsObsolete)
1832 AttributeTester.Report_ObsoleteMessage (oa, iface_type.GetSignatureForError (), Location, Report);
1834 if (iface_type.Arity > 0) {
1835 // TODO: passing `this' is wrong, should be base type iface instead
1836 VarianceDecl.CheckTypeVariance (iface_type, Variance.Covariant, this);
1838 if (((InflatedTypeSpec) iface_type).HasDynamicArgument () && !IsCompilerGenerated) {
1839 Report.Error (1966, Location,
1840 "`{0}': cannot implement a dynamic interface `{1}'",
1841 GetSignatureForError (), iface_type.GetSignatureForError ());
1846 if (iface_type.IsGenericOrParentIsGeneric) {
1847 foreach (var prev_iface in iface_exprs) {
1848 if (prev_iface == iface_type || prev_iface == null)
1851 if (!TypeSpecComparer.Unify.IsEqual (iface_type, prev_iface))
1854 Report.Error (695, Location,
1855 "`{0}' cannot implement both `{1}' and `{2}' because they may unify for some type parameter substitutions",
1856 GetSignatureForError (), prev_iface.GetSignatureForError (), iface_type.GetSignatureForError ());
1861 if (Kind == MemberKind.Interface) {
1862 foreach (var iface in spec.Interfaces) {
1863 MemberCache.AddInterface (iface);
1868 if (base_type != null) {
1870 // Run checks skipped during DefineType (e.g FullNamedExpression::ResolveAsType)
1872 if (base_type_expr != null) {
1873 ObsoleteAttribute obsolete_attr = base_type.GetAttributeObsolete ();
1874 if (obsolete_attr != null && !IsObsolete)
1875 AttributeTester.Report_ObsoleteMessage (obsolete_attr, base_type.GetSignatureForError (), base_type_expr.Location, Report);
1877 if (IsGenericOrParentIsGeneric && base_type.IsAttribute) {
1878 Report.Error (698, base_type_expr.Location,
1879 "A generic type cannot derive from `{0}' because it is an attribute class",
1880 base_type.GetSignatureForError ());
1884 var baseContainer = base_type.MemberDefinition as ClassOrStruct;
1885 if (baseContainer != null) {
1886 baseContainer.Define ();
1889 // It can trigger define of this type (for generic types only)
1891 if (HasMembersDefined)
1896 if (Kind == MemberKind.Struct || Kind == MemberKind.Class) {
1897 pending = PendingImplementation.GetPendingImplementations (this);
1900 var count = members.Count;
1901 for (int i = 0; i < count; ++i) {
1902 var mc = members[i] as InterfaceMemberBase;
1903 if (mc == null || !mc.IsExplicitImpl)
1908 } catch (Exception e) {
1909 throw new InternalErrorException (mc, e);
1913 for (int i = 0; i < count; ++i) {
1914 var mc = members[i] as InterfaceMemberBase;
1915 if (mc != null && mc.IsExplicitImpl)
1918 if (members[i] is TypeContainer)
1922 members[i].Define ();
1923 } catch (Exception e) {
1924 throw new InternalErrorException (members[i], e);
1929 CheckPairedOperators ();
1932 if (requires_delayed_unmanagedtype_check) {
1933 requires_delayed_unmanagedtype_check = false;
1934 foreach (var member in members) {
1935 var f = member as Field;
1936 if (f != null && f.MemberType != null && f.MemberType.IsPointer)
1937 TypeManager.VerifyUnmanaged (Module, f.MemberType, f.Location);
1941 ComputeIndexerName();
1943 if (HasEquals && !HasGetHashCode) {
1944 Report.Warning (659, 3, Location,
1945 "`{0}' overrides Object.Equals(object) but does not override Object.GetHashCode()", GetSignatureForError ());
1948 if (Kind == MemberKind.Interface && iface_exprs != null) {
1949 MemberCache.RemoveHiddenMembers (spec);
1955 void ComputeIndexerName ()
1957 var indexers = MemberCache.FindMembers (spec, MemberCache.IndexerNameAlias, true);
1958 if (indexers == null)
1961 string class_indexer_name = null;
1964 // Check normal indexers for consistent name, explicit interface implementation
1965 // indexers are ignored
1967 foreach (var indexer in indexers) {
1969 // FindMembers can return unfiltered full hierarchy names
1971 if (indexer.DeclaringType != spec)
1974 has_normal_indexers = true;
1976 if (class_indexer_name == null) {
1977 indexer_name = class_indexer_name = indexer.Name;
1981 if (indexer.Name != class_indexer_name)
1982 Report.Error (668, ((Indexer)indexer.MemberDefinition).Location,
1983 "Two indexers have different names; the IndexerName attribute must be used with the same name on every indexer within a type");
1987 void EmitIndexerName ()
1989 if (!has_normal_indexers)
1992 var ctor = Module.PredefinedMembers.DefaultMemberAttributeCtor.Get ();
1996 var encoder = new AttributeEncoder ();
1997 encoder.Encode (GetAttributeDefaultMember ());
1998 encoder.EncodeEmptyNamedArguments ();
2000 TypeBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray ());
2003 public override void VerifyMembers ()
2006 // Check for internal or private fields that were never assigned
2008 if (!IsCompilerGenerated && Compiler.Settings.WarningLevel >= 3 && this == PartialContainer) {
2009 bool is_type_exposed = Kind == MemberKind.Struct || IsExposedFromAssembly ();
2010 foreach (var member in members) {
2011 if (member is Event) {
2013 // An event can be assigned from same class only, so we can report
2014 // this warning for all accessibility modes
2017 Report.Warning (67, 3, member.Location, "The event `{0}' is never used", member.GetSignatureForError ());
2022 if ((member.ModFlags & Modifiers.AccessibilityMask) != Modifiers.PRIVATE) {
2023 if (is_type_exposed)
2026 member.SetIsUsed ();
2029 var f = member as Field;
2033 if (!member.IsUsed) {
2034 if ((member.caching_flags & Flags.IsAssigned) == 0) {
2035 Report.Warning (169, 3, member.Location, "The private field `{0}' is never used", member.GetSignatureForError ());
2037 Report.Warning (414, 3, member.Location, "The private field `{0}' is assigned but its value is never used",
2038 member.GetSignatureForError ());
2043 if ((f.caching_flags & Flags.IsAssigned) != 0)
2047 // Only report 649 on level 4
2049 if (Compiler.Settings.WarningLevel < 4)
2053 // Don't be pedantic when type requires specific layout
2055 if (f.OptAttributes != null || PartialContainer.HasStructLayout)
2058 Constant c = New.Constantify (f.MemberType, f.Location);
2061 value = c.GetValueAsLiteral ();
2062 } else if (TypeSpec.IsReferenceType (f.MemberType)) {
2069 value = " `" + value + "'";
2071 Report.Warning (649, 4, f.Location, "Field `{0}' is never assigned to, and will always have its default value{1}",
2072 f.GetSignatureForError (), value);
2076 base.VerifyMembers ();
2079 public override void Emit ()
2081 if (OptAttributes != null)
2082 OptAttributes.Emit ();
2084 if (!IsCompilerGenerated) {
2086 MemberSpec candidate;
2087 bool overrides = false;
2088 var conflict_symbol = MemberCache.FindBaseMember (this, out candidate, ref overrides);
2089 if (conflict_symbol == null && candidate == null) {
2090 if ((ModFlags & Modifiers.NEW) != 0)
2091 Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required",
2092 GetSignatureForError ());
2094 if ((ModFlags & Modifiers.NEW) == 0) {
2095 if (candidate == null)
2096 candidate = conflict_symbol;
2098 Report.SymbolRelatedToPreviousError (candidate);
2099 Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
2100 GetSignatureForError (), candidate.GetSignatureForError ());
2105 // Run constraints check on all possible generic types
2106 if (base_type != null && base_type_expr != null) {
2107 ConstraintChecker.Check (this, base_type, base_type_expr.Location);
2110 if (iface_exprs != null) {
2111 foreach (var iface_type in iface_exprs) {
2112 if (iface_type == null)
2115 ConstraintChecker.Check (this, iface_type, Location); // TODO: Location is wrong
2120 if (all_tp_builders != null) {
2121 int current_starts_index = CurrentTypeParametersStartIndex;
2122 for (int i = 0; i < all_tp_builders.Length; i++) {
2123 if (i < current_starts_index) {
2124 all_type_parameters[i].EmitConstraints (all_tp_builders [i]);
2126 var tp = CurrentTypeParameters [i - current_starts_index];
2127 tp.CheckGenericConstraints (!IsObsolete);
2133 if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0 && !Parent.IsCompilerGenerated)
2134 Module.PredefinedAttributes.CompilerGenerated.EmitAttribute (TypeBuilder);
2137 if ((TypeBuilder.Attributes & TypeAttributes.StringFormatMask) == 0 && Module.HasDefaultCharSet)
2138 TypeBuilder.__SetAttributes (TypeBuilder.Attributes | Module.DefaultCharSetType);
2143 for (int i = 0; i < members.Count; i++) {
2145 if ((m.caching_flags & Flags.CloseTypeCreated) != 0)
2152 CheckAttributeClsCompliance ();
2154 if (pending != null)
2155 pending.VerifyPendingMethods ();
2159 void CheckAttributeClsCompliance ()
2161 if (!spec.IsAttribute || !IsExposedFromAssembly () || !Compiler.Settings.VerifyClsCompliance || !IsClsComplianceRequired ())
2164 foreach (var m in members) {
2165 var c = m as Constructor;
2169 if (c.HasCompliantArgs)
2173 Report.Warning (3015, 1, Location, "`{0}' has no accessible constructors which use only CLS-compliant types", GetSignatureForError ());
2176 public sealed override void EmitContainer ()
2178 if ((caching_flags & Flags.CloseTypeCreated) != 0)
2184 public override void CloseContainer ()
2186 if ((caching_flags & Flags.CloseTypeCreated) != 0)
2189 // Close base type container first to avoid TypeLoadException
2190 if (spec.BaseType != null) {
2191 var btype = spec.BaseType.MemberDefinition as TypeContainer;
2192 if (btype != null) {
2193 btype.CloseContainer ();
2195 if ((caching_flags & Flags.CloseTypeCreated) != 0)
2201 caching_flags |= Flags.CloseTypeCreated;
2202 TypeBuilder.CreateType ();
2203 } catch (TypeLoadException) {
2205 // This is fine, the code still created the type
2207 } catch (Exception e) {
2208 throw new InternalErrorException (this, e);
2211 base.CloseContainer ();
2214 initialized_fields = null;
2215 initialized_static_fields = null;
2217 OptAttributes = null;
2221 // Performs the validation on a Method's modifiers (properties have
2222 // the same properties).
2224 // TODO: Why is it not done at parse stage, move to Modifiers::Check
2226 public bool MethodModifiersValid (MemberCore mc)
2228 const Modifiers vao = (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE);
2229 const Modifiers nv = (Modifiers.NEW | Modifiers.VIRTUAL);
2231 var flags = mc.ModFlags;
2234 // At most one of static, virtual or override
2236 if ((flags & Modifiers.STATIC) != 0){
2237 if ((flags & vao) != 0){
2238 Report.Error (112, mc.Location, "A static member `{0}' cannot be marked as override, virtual or abstract",
2239 mc.GetSignatureForError ());
2244 if ((flags & Modifiers.OVERRIDE) != 0 && (flags & nv) != 0){
2245 Report.Error (113, mc.Location, "A member `{0}' marked as override cannot be marked as new or virtual",
2246 mc.GetSignatureForError ());
2251 // If the declaration includes the abstract modifier, then the
2252 // declaration does not include static, virtual or extern
2254 if ((flags & Modifiers.ABSTRACT) != 0){
2255 if ((flags & Modifiers.EXTERN) != 0){
2257 180, mc.Location, "`{0}' cannot be both extern and abstract", mc.GetSignatureForError ());
2261 if ((flags & Modifiers.SEALED) != 0) {
2262 Report.Error (502, mc.Location, "`{0}' cannot be both abstract and sealed", mc.GetSignatureForError ());
2266 if ((flags & Modifiers.VIRTUAL) != 0){
2267 Report.Error (503, mc.Location, "The abstract method `{0}' cannot be marked virtual", mc.GetSignatureForError ());
2271 if ((ModFlags & Modifiers.ABSTRACT) == 0){
2272 Report.SymbolRelatedToPreviousError (this);
2273 Report.Error (513, mc.Location, "`{0}' is abstract but it is declared in the non-abstract class `{1}'",
2274 mc.GetSignatureForError (), GetSignatureForError ());
2279 if ((flags & Modifiers.PRIVATE) != 0){
2280 if ((flags & vao) != 0){
2281 Report.Error (621, mc.Location, "`{0}': virtual or abstract members cannot be private", mc.GetSignatureForError ());
2286 if ((flags & Modifiers.SEALED) != 0){
2287 if ((flags & Modifiers.OVERRIDE) == 0){
2288 Report.Error (238, mc.Location, "`{0}' cannot be sealed because it is not an override", mc.GetSignatureForError ());
2296 protected override bool VerifyClsCompliance ()
2298 if (!base.VerifyClsCompliance ())
2301 // Check all container names for user classes
2302 if (Kind != MemberKind.Delegate)
2303 MemberCache.VerifyClsCompliance (Definition, Report);
2305 if (BaseType != null && !BaseType.IsCLSCompliant ()) {
2306 Report.Warning (3009, 1, Location, "`{0}': base type `{1}' is not CLS-compliant",
2307 GetSignatureForError (), BaseType.GetSignatureForError ());
2313 /// Performs checks for an explicit interface implementation. First it
2314 /// checks whether the `interface_type' is a base inteface implementation.
2315 /// Then it checks whether `name' exists in the interface type.
2317 public bool VerifyImplements (InterfaceMemberBase mb)
2319 var ifaces = PartialContainer.Interfaces;
2320 if (ifaces != null) {
2321 foreach (TypeSpec t in ifaces){
2322 if (t == mb.InterfaceType)
2325 var expanded_base = t.Interfaces;
2326 if (expanded_base == null)
2329 foreach (var bt in expanded_base) {
2330 if (bt == mb.InterfaceType)
2336 Report.SymbolRelatedToPreviousError (mb.InterfaceType);
2337 Report.Error (540, mb.Location, "`{0}': containing type does not implement interface `{1}'",
2338 mb.GetSignatureForError (), mb.InterfaceType.GetSignatureForError ());
2343 // Used for visiblity checks to tests whether this definition shares
2344 // base type baseType, it does member-definition search
2346 public bool IsBaseTypeDefinition (TypeSpec baseType)
2348 // RootContext check
2349 if (TypeBuilder == null)
2354 if (type.MemberDefinition == baseType.MemberDefinition)
2357 type = type.BaseType;
2358 } while (type != null);
2363 public override bool IsClsComplianceRequired ()
2366 return PartialContainer.IsClsComplianceRequired ();
2368 return base.IsClsComplianceRequired ();
2371 bool ITypeDefinition.IsInternalAsPublic (IAssemblyDefinition assembly)
2373 return Module.DeclaringAssembly == assembly;
2376 public virtual bool IsUnmanagedType ()
2381 public void LoadMembers (TypeSpec declaringType, bool onlyTypes, ref MemberCache cache)
2383 throw new NotSupportedException ("Not supported for compiled definition " + GetSignatureForError ());
2387 // Public function used to locate types.
2389 // Returns: Type or null if they type can not be found.
2391 public override FullNamedExpression LookupNamespaceOrType (string name, int arity, LookupMode mode, Location loc)
2393 FullNamedExpression e;
2394 if (arity == 0 && Cache.TryGetValue (name, out e) && mode != LookupMode.IgnoreAccessibility)
2400 var tp = CurrentTypeParameters;
2402 TypeParameter tparam = tp.Find (name);
2404 e = new TypeParameterExpr (tparam, Location.Null);
2409 TypeSpec t = LookupNestedTypeInHierarchy (name, arity);
2411 if (t != null && (t.IsAccessible (this) || mode == LookupMode.IgnoreAccessibility))
2412 e = new TypeExpression (t, Location.Null);
2414 var errors = Compiler.Report.Errors;
2415 e = Parent.LookupNamespaceOrType (name, arity, mode, loc);
2417 // TODO: LookupNamespaceOrType does more than just lookup. The result
2418 // cannot be cached or the error reporting won't happen
2419 if (errors != Compiler.Report.Errors)
2424 // TODO MemberCache: How to cache arity stuff ?
2425 if (arity == 0 && mode == LookupMode.Normal)
2431 TypeSpec LookupNestedTypeInHierarchy (string name, int arity)
2433 // Has any nested type
2434 // Does not work, because base type can have
2435 //if (PartialContainer.Types == null)
2438 var container = PartialContainer.CurrentType;
2439 return MemberCache.FindNestedType (container, name, arity);
2442 public void Mark_HasEquals ()
2444 cached_method |= CachedMethods.Equals;
2447 public void Mark_HasGetHashCode ()
2449 cached_method |= CachedMethods.GetHashCode;
2452 public override void WriteDebugSymbol (MonoSymbolFile file)
2457 foreach (var m in members) {
2458 m.WriteDebugSymbol (file);
2463 /// Method container contains Equals method
2465 public bool HasEquals {
2467 return (cached_method & CachedMethods.Equals) != 0;
2472 /// Method container contains GetHashCode method
2474 public bool HasGetHashCode {
2476 return (cached_method & CachedMethods.GetHashCode) != 0;
2480 public bool HasStaticFieldInitializer {
2482 return (cached_method & CachedMethods.HasStaticFieldInitializer) != 0;
2486 cached_method |= CachedMethods.HasStaticFieldInitializer;
2488 cached_method &= ~CachedMethods.HasStaticFieldInitializer;
2492 public override string DocCommentHeader {
2493 get { return "T:"; }
2497 public abstract class ClassOrStruct : TypeDefinition
2499 public const TypeAttributes StaticClassAttribute = TypeAttributes.Abstract | TypeAttributes.Sealed;
2501 SecurityType declarative_security;
2503 protected ClassOrStruct (TypeContainer parent, MemberName name, Attributes attrs, MemberKind kind)
2504 : base (parent, name, attrs, kind)
2508 protected override TypeAttributes TypeAttr {
2510 TypeAttributes ta = base.TypeAttr;
2511 if (!has_static_constructor)
2512 ta |= TypeAttributes.BeforeFieldInit;
2514 if (Kind == MemberKind.Class) {
2515 ta |= TypeAttributes.AutoLayout | TypeAttributes.Class;
2517 ta |= StaticClassAttribute;
2519 ta |= TypeAttributes.SequentialLayout;
2526 public override void AddNameToContainer (MemberCore symbol, string name)
2528 if (!(symbol is Constructor) && symbol.MemberName.Name == MemberName.Name) {
2529 if (symbol is TypeParameter) {
2530 Report.Error (694, symbol.Location,
2531 "Type parameter `{0}' has same name as containing type, or method",
2532 symbol.GetSignatureForError ());
2536 InterfaceMemberBase imb = symbol as InterfaceMemberBase;
2537 if (imb == null || !imb.IsExplicitImpl) {
2538 Report.SymbolRelatedToPreviousError (this);
2539 Report.Error (542, symbol.Location, "`{0}': member names cannot be the same as their enclosing type",
2540 symbol.GetSignatureForError ());
2545 base.AddNameToContainer (symbol, name);
2548 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
2550 if (a.IsValidSecurityAttribute ()) {
2551 a.ExtractSecurityPermissionSet (ctor, ref declarative_security);
2555 if (a.Type == pa.StructLayout) {
2556 PartialContainer.HasStructLayout = true;
2557 if (a.IsExplicitLayoutKind ())
2558 PartialContainer.HasExplicitLayout = true;
2561 if (a.Type == pa.Dynamic) {
2562 a.Error_MisusedDynamicAttribute ();
2566 base.ApplyAttributeBuilder (a, ctor, cdata, pa);
2570 /// Defines the default constructors
2572 protected virtual Constructor DefineDefaultConstructor (bool is_static)
2574 // The default instance constructor is public
2575 // If the class is abstract, the default constructor is protected
2576 // The default static constructor is private
2580 mods = Modifiers.STATIC | Modifiers.PRIVATE;
2582 mods = ((ModFlags & Modifiers.ABSTRACT) != 0) ? Modifiers.PROTECTED : Modifiers.PUBLIC;
2585 var c = new Constructor (this, MemberName.Name, mods, null, ParametersCompiled.EmptyReadOnlyParameters, Location);
2586 c.Initializer = new GeneratedBaseInitializer (Location);
2588 AddConstructor (c, true);
2589 c.Block = new ToplevelBlock (Compiler, ParametersCompiled.EmptyReadOnlyParameters, Location) {
2590 IsCompilerGenerated = true
2596 protected override bool DoDefineMembers ()
2598 CheckProtectedModifier ();
2600 base.DoDefineMembers ();
2605 public override void Emit ()
2607 if (!has_static_constructor && HasStaticFieldInitializer) {
2608 var c = DefineDefaultConstructor (true);
2614 if (declarative_security != null) {
2615 foreach (var de in declarative_security) {
2617 TypeBuilder.__AddDeclarativeSecurity (de);
2619 TypeBuilder.AddDeclarativeSecurity (de.Key, de.Value);
2627 public sealed class Class : ClassOrStruct
2629 const Modifiers AllowedModifiers =
2632 Modifiers.PROTECTED |
2633 Modifiers.INTERNAL |
2635 Modifiers.ABSTRACT |
2640 public Class (TypeContainer parent, MemberName name, Modifiers mod, Attributes attrs)
2641 : base (parent, name, attrs, MemberKind.Class)
2643 var accmods = IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE;
2644 this.ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, accmods, Location, Report);
2645 spec = new TypeSpec (Kind, null, this, null, ModFlags);
2648 public override void Accept (StructuralVisitor visitor)
2650 visitor.Visit (this);
2653 public override void SetBaseTypes (List<FullNamedExpression> baseTypes)
2655 var pmn = MemberName;
2656 if (pmn.Name == "Object" && !pmn.IsGeneric && Parent.MemberName.Name == "System" && Parent.MemberName.Left == null)
2657 Report.Error (537, Location,
2658 "The class System.Object cannot have a base class or implement an interface.");
2660 base.SetBaseTypes (baseTypes);
2663 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
2665 if (a.Type == pa.AttributeUsage) {
2666 if (!BaseType.IsAttribute && spec.BuiltinType != BuiltinTypeSpec.Type.Attribute) {
2667 Report.Error (641, a.Location, "Attribute `{0}' is only valid on classes derived from System.Attribute", a.GetSignatureForError ());
2671 if (a.Type == pa.Conditional && !BaseType.IsAttribute) {
2672 Report.Error (1689, a.Location, "Attribute `System.Diagnostics.ConditionalAttribute' is only valid on methods or attribute classes");
2676 if (a.Type == pa.ComImport && !attributes.Contains (pa.Guid)) {
2677 a.Error_MissingGuidAttribute ();
2681 if (a.Type == pa.Extension) {
2682 a.Error_MisusedExtensionAttribute ();
2686 if (a.Type.IsConditionallyExcluded (this))
2689 base.ApplyAttributeBuilder (a, ctor, cdata, pa);
2692 public override AttributeTargets AttributeTargets {
2694 return AttributeTargets.Class;
2698 protected override bool DoDefineMembers ()
2700 if ((ModFlags & Modifiers.ABSTRACT) == Modifiers.ABSTRACT && (ModFlags & (Modifiers.SEALED | Modifiers.STATIC)) != 0) {
2701 Report.Error (418, Location, "`{0}': an abstract class cannot be sealed or static", GetSignatureForError ());
2704 if ((ModFlags & (Modifiers.SEALED | Modifiers.STATIC)) == (Modifiers.SEALED | Modifiers.STATIC)) {
2705 Report.Error (441, Location, "`{0}': a class cannot be both static and sealed", GetSignatureForError ());
2709 foreach (var m in Members) {
2710 if (m is Operator) {
2711 Report.Error (715, m.Location, "`{0}': Static classes cannot contain user-defined operators", m.GetSignatureForError ());
2715 if (m is Destructor) {
2716 Report.Error (711, m.Location, "`{0}': Static classes cannot contain destructor", GetSignatureForError ());
2721 Report.Error (720, m.Location, "`{0}': cannot declare indexers in a static class", m.GetSignatureForError ());
2725 if ((m.ModFlags & Modifiers.STATIC) != 0 || m is TypeContainer)
2728 if (m is Constructor) {
2729 Report.Error (710, m.Location, "`{0}': Static classes cannot have instance constructors", GetSignatureForError ());
2733 Report.Error (708, m.Location, "`{0}': cannot declare instance members in a static class", m.GetSignatureForError ());
2736 if (!PartialContainer.HasInstanceConstructor)
2737 DefineDefaultConstructor (false);
2740 return base.DoDefineMembers ();
2743 public override void Emit ()
2747 if ((ModFlags & Modifiers.METHOD_EXTENSION) != 0)
2748 Module.PredefinedAttributes.Extension.EmitAttribute (TypeBuilder);
2750 if (base_type != null && base_type.HasDynamicElement) {
2751 Module.PredefinedAttributes.Dynamic.EmitAttribute (TypeBuilder, base_type, Location);
2755 public override void GetCompletionStartingWith (string prefix, List<string> results)
2757 base.GetCompletionStartingWith (prefix, results);
2760 while (bt != null) {
2761 results.AddRange (MemberCache.GetCompletitionMembers (this, bt, prefix).Where (l => l.IsStatic).Select (l => l.Name));
2766 protected override TypeSpec[] ResolveBaseTypes (out FullNamedExpression base_class)
2768 var ifaces = base.ResolveBaseTypes (out base_class);
2770 if (base_class == null) {
2771 if (spec.BuiltinType != BuiltinTypeSpec.Type.Object)
2772 base_type = Compiler.BuiltinTypes.Object;
2774 if (base_type.IsGenericParameter){
2775 Report.Error (689, base_class.Location, "`{0}': Cannot derive from type parameter `{1}'",
2776 GetSignatureForError (), base_type.GetSignatureForError ());
2777 } else if (base_type.IsStatic) {
2778 Report.SymbolRelatedToPreviousError (base_type);
2779 Report.Error (709, Location, "`{0}': Cannot derive from static class `{1}'",
2780 GetSignatureForError (), base_type.GetSignatureForError ());
2781 } else if (base_type.IsSealed) {
2782 Report.SymbolRelatedToPreviousError (base_type);
2783 Report.Error (509, Location, "`{0}': cannot derive from sealed type `{1}'",
2784 GetSignatureForError (), base_type.GetSignatureForError ());
2785 } else if (PartialContainer.IsStatic && base_type.BuiltinType != BuiltinTypeSpec.Type.Object) {
2786 Report.Error (713, Location, "Static class `{0}' cannot derive from type `{1}'. Static classes must derive from object",
2787 GetSignatureForError (), base_type.GetSignatureForError ());
2790 switch (base_type.BuiltinType) {
2791 case BuiltinTypeSpec.Type.Enum:
2792 case BuiltinTypeSpec.Type.ValueType:
2793 case BuiltinTypeSpec.Type.MulticastDelegate:
2794 case BuiltinTypeSpec.Type.Delegate:
2795 case BuiltinTypeSpec.Type.Array:
2796 if (!(spec is BuiltinTypeSpec)) {
2797 Report.Error (644, Location, "`{0}' cannot derive from special class `{1}'",
2798 GetSignatureForError (), base_type.GetSignatureForError ());
2800 base_type = Compiler.BuiltinTypes.Object;
2805 if (!IsAccessibleAs (base_type)) {
2806 Report.SymbolRelatedToPreviousError (base_type);
2807 Report.Error (60, Location, "Inconsistent accessibility: base class `{0}' is less accessible than class `{1}'",
2808 base_type.GetSignatureForError (), GetSignatureForError ());
2812 if (PartialContainer.IsStatic && ifaces != null) {
2813 foreach (var t in ifaces)
2814 Report.SymbolRelatedToPreviousError (t);
2815 Report.Error (714, Location, "Static class `{0}' cannot implement interfaces", GetSignatureForError ());
2821 /// Search for at least one defined condition in ConditionalAttribute of attribute class
2822 /// Valid only for attribute classes.
2823 public override string[] ConditionalConditions ()
2825 if ((caching_flags & (Flags.Excluded_Undetected | Flags.Excluded)) == 0)
2828 caching_flags &= ~Flags.Excluded_Undetected;
2830 if (OptAttributes == null)
2833 Attribute[] attrs = OptAttributes.SearchMulti (Module.PredefinedAttributes.Conditional);
2837 string[] conditions = new string[attrs.Length];
2838 for (int i = 0; i < conditions.Length; ++i)
2839 conditions[i] = attrs[i].GetConditionalAttributeValue ();
2841 caching_flags |= Flags.Excluded;
2846 public sealed class Struct : ClassOrStruct
2848 bool is_unmanaged, has_unmanaged_check_done;
2852 // Modifiers allowed in a struct declaration
2854 const Modifiers AllowedModifiers =
2857 Modifiers.PROTECTED |
2858 Modifiers.INTERNAL |
2862 public Struct (TypeContainer parent, MemberName name, Modifiers mod, Attributes attrs)
2863 : base (parent, name, attrs, MemberKind.Struct)
2865 var accmods = IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE;
2866 this.ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, accmods, Location, Report) | Modifiers.SEALED ;
2867 spec = new TypeSpec (Kind, null, this, null, ModFlags);
2870 public override AttributeTargets AttributeTargets {
2872 return AttributeTargets.Struct;
2876 public override void Accept (StructuralVisitor visitor)
2878 visitor.Visit (this);
2881 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
2883 base.ApplyAttributeBuilder (a, ctor, cdata, pa);
2886 // When struct constains fixed fixed and struct layout has explicitly
2887 // set CharSet, its value has to be propagated to compiler generated
2890 if (a.Type == pa.StructLayout) {
2891 var value = a.GetNamedValue ("CharSet");
2895 for (int i = 0; i < Members.Count; ++i) {
2896 FixedField ff = Members [i] as FixedField;
2900 ff.CharSet = (CharSet) System.Enum.Parse (typeof (CharSet), value.GetValue ().ToString ());
2905 bool CheckStructCycles ()
2911 foreach (var member in Members) {
2912 var field = member as Field;
2916 TypeSpec ftype = field.Spec.MemberType;
2917 if (!ftype.IsStruct)
2920 if (ftype is BuiltinTypeSpec)
2923 foreach (var targ in ftype.TypeArguments) {
2924 if (!CheckFieldTypeCycle (targ)) {
2925 Report.Error (523, field.Location,
2926 "Struct member `{0}' of type `{1}' causes a cycle in the struct layout",
2927 field.GetSignatureForError (), ftype.GetSignatureForError ());
2933 // Static fields of exactly same type are allowed
2935 if (field.IsStatic && ftype == CurrentType)
2938 if (!CheckFieldTypeCycle (ftype)) {
2939 Report.Error (523, field.Location,
2940 "Struct member `{0}' of type `{1}' causes a cycle in the struct layout",
2941 field.GetSignatureForError (), ftype.GetSignatureForError ());
2950 static bool CheckFieldTypeCycle (TypeSpec ts)
2952 var fts = ts.MemberDefinition as Struct;
2956 return fts.CheckStructCycles ();
2959 public override void Emit ()
2961 CheckStructCycles ();
2966 public override bool IsUnmanagedType ()
2968 if (has_unmanaged_check_done)
2969 return is_unmanaged;
2971 if (requires_delayed_unmanagedtype_check)
2974 var parent_def = Parent.PartialContainer;
2975 if (parent_def != null && parent_def.IsGenericOrParentIsGeneric) {
2976 has_unmanaged_check_done = true;
2980 if (first_nonstatic_field != null) {
2981 requires_delayed_unmanagedtype_check = true;
2983 foreach (var member in Members) {
2984 var f = member as Field;
2991 // It can happen when recursive unmanaged types are defined
2992 // struct S { S* s; }
2993 TypeSpec mt = f.MemberType;
3001 has_unmanaged_check_done = true;
3005 has_unmanaged_check_done = true;
3008 is_unmanaged = true;
3012 protected override TypeSpec[] ResolveBaseTypes (out FullNamedExpression base_class)
3014 var ifaces = base.ResolveBaseTypes (out base_class);
3015 base_type = Compiler.BuiltinTypes.ValueType;
3019 public override void RegisterFieldForInitialization (MemberCore field, FieldInitializer expression)
3021 if ((field.ModFlags & Modifiers.STATIC) == 0) {
3022 Report.Error (573, field.Location, "`{0}': Structs cannot have instance field initializers",
3023 field.GetSignatureForError ());
3026 base.RegisterFieldForInitialization (field, expression);
3034 public sealed class Interface : TypeDefinition {
3037 /// Modifiers allowed in a class declaration
3039 const Modifiers AllowedModifiers =
3042 Modifiers.PROTECTED |
3043 Modifiers.INTERNAL |
3047 public Interface (TypeContainer parent, MemberName name, Modifiers mod, Attributes attrs)
3048 : base (parent, name, attrs, MemberKind.Interface)
3050 var accmods = IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE;
3052 this.ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, accmods, name.Location, Report);
3053 spec = new TypeSpec (Kind, null, this, null, ModFlags);
3058 public override AttributeTargets AttributeTargets {
3060 return AttributeTargets.Interface;
3064 protected override TypeAttributes TypeAttr {
3066 const TypeAttributes DefaultTypeAttributes =
3067 TypeAttributes.AutoLayout |
3068 TypeAttributes.Abstract |
3069 TypeAttributes.Interface;
3071 return base.TypeAttr | DefaultTypeAttributes;
3077 public override void Accept (StructuralVisitor visitor)
3079 visitor.Visit (this);
3082 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
3084 if (a.Type == pa.ComImport && !attributes.Contains (pa.Guid)) {
3085 a.Error_MissingGuidAttribute ();
3089 base.ApplyAttributeBuilder (a, ctor, cdata, pa);
3092 protected override bool VerifyClsCompliance ()
3094 if (!base.VerifyClsCompliance ())
3097 if (iface_exprs != null) {
3098 foreach (var iface in iface_exprs) {
3099 if (iface.IsCLSCompliant ())
3102 Report.SymbolRelatedToPreviousError (iface);
3103 Report.Warning (3027, 1, Location, "`{0}' is not CLS-compliant because base interface `{1}' is not CLS-compliant",
3104 GetSignatureForError (), iface.GetSignatureForError ());
3112 public abstract class InterfaceMemberBase : MemberBase
3115 // Common modifiers allowed in a class declaration
3117 protected const Modifiers AllowedModifiersClass =
3120 Modifiers.PROTECTED |
3121 Modifiers.INTERNAL |
3126 Modifiers.OVERRIDE |
3127 Modifiers.ABSTRACT |
3132 // Common modifiers allowed in a struct declaration
3134 protected const Modifiers AllowedModifiersStruct =
3137 Modifiers.PROTECTED |
3138 Modifiers.INTERNAL |
3141 Modifiers.OVERRIDE |
3146 // Common modifiers allowed in a interface declaration
3148 protected const Modifiers AllowedModifiersInterface =
3153 // Whether this is an interface member.
3155 public bool IsInterface;
3158 // If true, this is an explicit interface implementation
3160 public readonly bool IsExplicitImpl;
3162 protected bool is_external_implementation;
3165 // The interface type we are explicitly implementing
3167 public TypeSpec InterfaceType;
3170 // The method we're overriding if this is an override method.
3172 protected MethodSpec base_method;
3174 readonly Modifiers explicit_mod_flags;
3175 public MethodAttributes flags;
3177 protected InterfaceMemberBase (TypeDefinition parent, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, MemberName name, Attributes attrs)
3178 : base (parent, type, mod, allowed_mod, Modifiers.PRIVATE, name, attrs)
3180 IsInterface = parent.Kind == MemberKind.Interface;
3181 IsExplicitImpl = (MemberName.ExplicitInterface != null);
3182 explicit_mod_flags = mod;
3185 public abstract Variance ExpectedMemberTypeVariance { get; }
3187 protected override bool CheckBase ()
3189 if (!base.CheckBase ())
3192 if ((caching_flags & Flags.MethodOverloadsExist) != 0)
3193 CheckForDuplications ();
3198 // For System.Object only
3199 if (Parent.BaseType == null)
3202 MemberSpec candidate;
3203 bool overrides = false;
3204 var base_member = FindBaseMember (out candidate, ref overrides);
3206 if ((ModFlags & Modifiers.OVERRIDE) != 0) {
3207 if (base_member == null) {
3208 if (candidate == null) {
3209 if (this is Method && ((Method)this).ParameterInfo.IsEmpty && MemberName.Name == Destructor.MetadataName && MemberName.Arity == 0) {
3210 Report.Error (249, Location, "Do not override `{0}'. Use destructor syntax instead",
3211 "object.Finalize()");
3213 Report.Error (115, Location, "`{0}' is marked as an override but no suitable {1} found to override",
3214 GetSignatureForError (), SimpleName.GetMemberType (this));
3217 Report.SymbolRelatedToPreviousError (candidate);
3219 Report.Error (72, Location, "`{0}': cannot override because `{1}' is not an event",
3220 GetSignatureForError (), TypeManager.GetFullNameSignature (candidate));
3221 else if (this is PropertyBase)
3222 Report.Error (544, Location, "`{0}': cannot override because `{1}' is not a property",
3223 GetSignatureForError (), TypeManager.GetFullNameSignature (candidate));
3225 Report.Error (505, Location, "`{0}': cannot override because `{1}' is not a method",
3226 GetSignatureForError (), TypeManager.GetFullNameSignature (candidate));
3233 // Handles ambiguous overrides
3235 if (candidate != null) {
3236 Report.SymbolRelatedToPreviousError (candidate);
3237 Report.SymbolRelatedToPreviousError (base_member);
3239 // Get member definition for error reporting
3240 var m1 = MemberCache.GetMember (base_member.DeclaringType.GetDefinition (), base_member);
3241 var m2 = MemberCache.GetMember (candidate.DeclaringType.GetDefinition (), candidate);
3243 Report.Error (462, Location,
3244 "`{0}' cannot override inherited members `{1}' and `{2}' because they have the same signature when used in type `{3}'",
3245 GetSignatureForError (), m1.GetSignatureForError (), m2.GetSignatureForError (), Parent.GetSignatureForError ());
3248 if (!CheckOverrideAgainstBase (base_member))
3251 ObsoleteAttribute oa = base_member.GetAttributeObsolete ();
3253 if (OptAttributes == null || !OptAttributes.Contains (Module.PredefinedAttributes.Obsolete)) {
3254 Report.SymbolRelatedToPreviousError (base_member);
3255 Report.Warning (672, 1, Location, "Member `{0}' overrides obsolete member `{1}'. Add the Obsolete attribute to `{0}'",
3256 GetSignatureForError (), base_member.GetSignatureForError ());
3259 if (OptAttributes != null && OptAttributes.Contains (Module.PredefinedAttributes.Obsolete)) {
3260 Report.SymbolRelatedToPreviousError (base_member);
3261 Report.Warning (809, 1, Location, "Obsolete member `{0}' overrides non-obsolete member `{1}'",
3262 GetSignatureForError (), base_member.GetSignatureForError ());
3266 base_method = base_member as MethodSpec;
3270 if (base_member == null && candidate != null && (!(candidate is IParametersMember) || !(this is IParametersMember)))
3271 base_member = candidate;
3273 if (base_member == null) {
3274 if ((ModFlags & Modifiers.NEW) != 0) {
3275 if (base_member == null) {
3276 Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required",
3277 GetSignatureForError ());
3281 if ((ModFlags & Modifiers.NEW) == 0) {
3282 ModFlags |= Modifiers.NEW;
3283 if (!IsCompilerGenerated) {
3284 Report.SymbolRelatedToPreviousError (base_member);
3285 if (!IsInterface && (base_member.Modifiers & (Modifiers.ABSTRACT | Modifiers.VIRTUAL | Modifiers.OVERRIDE)) != 0) {
3286 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",
3287 GetSignatureForError (), base_member.GetSignatureForError ());
3289 Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
3290 GetSignatureForError (), base_member.GetSignatureForError ());
3295 if (!IsInterface && base_member.IsAbstract && !overrides && !IsStatic) {
3296 Report.SymbolRelatedToPreviousError (base_member);
3297 Report.Error (533, Location, "`{0}' hides inherited abstract member `{1}'",
3298 GetSignatureForError (), base_member.GetSignatureForError ());
3305 protected virtual bool CheckForDuplications ()
3307 return Parent.MemberCache.CheckExistingMembersOverloads (this, ParametersCompiled.EmptyReadOnlyParameters);
3311 // Performs various checks on the MethodInfo `mb' regarding the modifier flags
3312 // that have been defined.
3314 protected virtual bool CheckOverrideAgainstBase (MemberSpec base_member)
3318 if ((base_member.Modifiers & (Modifiers.ABSTRACT | Modifiers.VIRTUAL | Modifiers.OVERRIDE)) == 0) {
3319 Report.SymbolRelatedToPreviousError (base_member);
3320 Report.Error (506, Location,
3321 "`{0}': cannot override inherited member `{1}' because it is not marked virtual, abstract or override",
3322 GetSignatureForError (), TypeManager.CSharpSignature (base_member));
3326 // Now we check that the overriden method is not final
3327 if ((base_member.Modifiers & Modifiers.SEALED) != 0) {
3328 Report.SymbolRelatedToPreviousError (base_member);
3329 Report.Error (239, Location, "`{0}': cannot override inherited member `{1}' because it is sealed",
3330 GetSignatureForError (), TypeManager.CSharpSignature (base_member));
3334 var base_member_type = ((IInterfaceMemberSpec) base_member).MemberType;
3335 if (!TypeSpecComparer.Override.IsEqual (MemberType, base_member_type)) {
3336 Report.SymbolRelatedToPreviousError (base_member);
3337 if (this is PropertyBasedMember) {
3338 Report.Error (1715, Location, "`{0}': type must be `{1}' to match overridden member `{2}'",
3339 GetSignatureForError (), base_member_type.GetSignatureForError (), base_member.GetSignatureForError ());
3341 Report.Error (508, Location, "`{0}': return type must be `{1}' to match overridden member `{2}'",
3342 GetSignatureForError (), base_member_type.GetSignatureForError (), base_member.GetSignatureForError ());
3350 protected static bool CheckAccessModifiers (MemberCore this_member, MemberSpec base_member)
3352 var thisp = this_member.ModFlags & Modifiers.AccessibilityMask;
3353 var base_classp = base_member.Modifiers & Modifiers.AccessibilityMask;
3355 if ((base_classp & (Modifiers.PROTECTED | Modifiers.INTERNAL)) == (Modifiers.PROTECTED | Modifiers.INTERNAL)) {
3357 // It must be at least "protected"
3359 if ((thisp & Modifiers.PROTECTED) == 0) {
3364 // when overriding protected internal, the method can be declared
3365 // protected internal only within the same assembly or assembly
3366 // which has InternalsVisibleTo
3368 if ((thisp & Modifiers.INTERNAL) != 0) {
3369 return base_member.DeclaringType.MemberDefinition.IsInternalAsPublic (this_member.Module.DeclaringAssembly);
3373 // protected overriding protected internal inside same assembly
3374 // requires internal modifier as well
3376 if (base_member.DeclaringType.MemberDefinition.IsInternalAsPublic (this_member.Module.DeclaringAssembly)) {
3383 return thisp == base_classp;
3386 public override bool Define ()
3389 ModFlags = Modifiers.PUBLIC | Modifiers.ABSTRACT |
3390 Modifiers.VIRTUAL | (ModFlags & (Modifiers.UNSAFE | Modifiers.NEW));
3392 flags = MethodAttributes.Public |
3393 MethodAttributes.Abstract |
3394 MethodAttributes.HideBySig |
3395 MethodAttributes.NewSlot |
3396 MethodAttributes.Virtual;
3398 Parent.PartialContainer.MethodModifiersValid (this);
3400 flags = ModifiersExtensions.MethodAttr (ModFlags);
3403 if (IsExplicitImpl) {
3404 InterfaceType = MemberName.ExplicitInterface.ResolveAsType (Parent);
3405 if (InterfaceType == null)
3408 if ((ModFlags & Modifiers.PARTIAL) != 0) {
3409 Report.Error (754, Location, "A partial method `{0}' cannot explicitly implement an interface",
3410 GetSignatureForError ());
3413 if (!InterfaceType.IsInterface) {
3414 Report.SymbolRelatedToPreviousError (InterfaceType);
3415 Report.Error (538, Location, "The type `{0}' in explicit interface declaration is not an interface",
3416 InterfaceType.GetSignatureForError ());
3418 Parent.PartialContainer.VerifyImplements (this);
3421 Modifiers allowed_explicit = Modifiers.AllowedExplicitImplFlags;
3423 allowed_explicit |= Modifiers.ASYNC;
3425 ModifiersExtensions.Check (allowed_explicit, explicit_mod_flags, 0, Location, Report);
3428 return base.Define ();
3431 protected bool DefineParameters (ParametersCompiled parameters)
3433 if (!parameters.Resolve (this))
3437 for (int i = 0; i < parameters.Count; ++i) {
3438 Parameter p = parameters [i];
3440 if (p.HasDefaultValue && (IsExplicitImpl || this is Operator || (this is Indexer && parameters.Count == 1)))
3441 p.Warning_UselessOptionalParameter (Report);
3443 if (p.CheckAccessibility (this))
3446 TypeSpec t = parameters.Types [i];
3447 Report.SymbolRelatedToPreviousError (t);
3448 if (this is Indexer)
3449 Report.Error (55, Location,
3450 "Inconsistent accessibility: parameter type `{0}' is less accessible than indexer `{1}'",
3451 t.GetSignatureForError (), GetSignatureForError ());
3452 else if (this is Operator)
3453 Report.Error (57, Location,
3454 "Inconsistent accessibility: parameter type `{0}' is less accessible than operator `{1}'",
3455 t.GetSignatureForError (), GetSignatureForError ());
3457 Report.Error (51, Location,
3458 "Inconsistent accessibility: parameter type `{0}' is less accessible than method `{1}'",
3459 t.GetSignatureForError (), GetSignatureForError ());
3465 protected override void DoMemberTypeDependentChecks ()
3467 base.DoMemberTypeDependentChecks ();
3469 VarianceDecl.CheckTypeVariance (MemberType, ExpectedMemberTypeVariance, this);
3472 public override void Emit()
3474 // for extern static method must be specified either DllImport attribute or MethodImplAttribute.
3475 // We are more strict than csc and report this as an error because SRE does not allow emit that
3476 if ((ModFlags & Modifiers.EXTERN) != 0 && !is_external_implementation && (OptAttributes == null || !OptAttributes.HasResolveError ())) {
3477 if (this is Constructor) {
3478 Report.Warning (824, 1, Location,
3479 "Constructor `{0}' is marked `external' but has no external implementation specified", GetSignatureForError ());
3481 Report.Warning (626, 1, Location,
3482 "`{0}' is marked as an external but has no DllImport attribute. Consider adding a DllImport attribute to specify the external implementation",
3483 GetSignatureForError ());
3490 public override bool EnableOverloadChecks (MemberCore overload)
3493 // Two members can differ in their explicit interface
3494 // type parameter only
3496 InterfaceMemberBase imb = overload as InterfaceMemberBase;
3497 if (imb != null && imb.IsExplicitImpl) {
3498 if (IsExplicitImpl) {
3499 caching_flags |= Flags.MethodOverloadsExist;
3504 return IsExplicitImpl;
3507 protected void Error_CannotChangeAccessModifiers (MemberCore member, MemberSpec base_member)
3509 var base_modifiers = base_member.Modifiers;
3511 // Remove internal modifier from types which are not internally accessible
3512 if ((base_modifiers & Modifiers.AccessibilityMask) == (Modifiers.PROTECTED | Modifiers.INTERNAL) &&
3513 !base_member.DeclaringType.MemberDefinition.IsInternalAsPublic (member.Module.DeclaringAssembly))
3514 base_modifiers = Modifiers.PROTECTED;
3516 Report.SymbolRelatedToPreviousError (base_member);
3517 Report.Error (507, member.Location,
3518 "`{0}': cannot change access modifiers when overriding `{1}' inherited member `{2}'",
3519 member.GetSignatureForError (),
3520 ModifiersExtensions.AccessibilityName (base_modifiers),
3521 base_member.GetSignatureForError ());
3524 protected void Error_StaticReturnType ()
3526 Report.Error (722, Location,
3527 "`{0}': static types cannot be used as return types",
3528 MemberType.GetSignatureForError ());
3532 /// Gets base method and its return type
3534 protected virtual MemberSpec FindBaseMember (out MemberSpec bestCandidate, ref bool overrides)
3536 return MemberCache.FindBaseMember (this, out bestCandidate, ref overrides);
3540 // The "short" name of this property / indexer / event. This is the
3541 // name without the explicit interface.
3543 public string ShortName {
3544 get { return MemberName.Name; }
3548 // Returns full metadata method name
3550 public string GetFullName (MemberName name)
3552 return GetFullName (name.Name);
3555 public string GetFullName (string name)
3557 if (!IsExplicitImpl)
3561 // When dealing with explicit members a full interface type
3562 // name is added to member name to avoid possible name conflicts
3564 // We use CSharpName which gets us full name with benefit of
3565 // replacing predefined names which saves some space and name
3568 return InterfaceType.GetSignatureForError () + "." + name;
3571 public override string GetSignatureForDocumentation ()
3574 return Parent.GetSignatureForDocumentation () + "." + InterfaceType.GetExplicitNameSignatureForDocumentation () + "#" + ShortName;
3576 return Parent.GetSignatureForDocumentation () + "." + ShortName;
3579 public override bool IsUsed
3581 get { return IsExplicitImpl || base.IsUsed; }
3584 public override void SetConstraints (List<Constraints> constraints_list)
3586 if (((ModFlags & Modifiers.OVERRIDE) != 0 || IsExplicitImpl)) {
3587 Report.Error (460, Location,
3588 "`{0}': Cannot specify constraints for overrides and explicit interface implementation methods",
3589 GetSignatureForError ());
3592 base.SetConstraints (constraints_list);
3596 public abstract class MemberBase : MemberCore
3598 protected FullNamedExpression type_expr;
3599 protected TypeSpec member_type;
3600 public new TypeDefinition Parent;
3602 protected MemberBase (TypeDefinition parent, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, Modifiers def_mod, MemberName name, Attributes attrs)
3603 : base (parent, name, attrs)
3605 this.Parent = parent;
3606 this.type_expr = type;
3608 if (name != MemberName.Null)
3609 ModFlags = ModifiersExtensions.Check (allowed_mod, mod, def_mod, Location, Report);
3614 public TypeSpec MemberType {
3620 public FullNamedExpression TypeExpression {
3629 // Main member define entry
3631 public override bool Define ()
3633 DoMemberTypeIndependentChecks ();
3636 // Returns false only when type resolution failed
3638 if (!ResolveMemberType ())
3641 DoMemberTypeDependentChecks ();
3646 // Any type_name independent checks
3648 protected virtual void DoMemberTypeIndependentChecks ()
3650 if ((Parent.ModFlags & Modifiers.SEALED) != 0 &&
3651 (ModFlags & (Modifiers.VIRTUAL | Modifiers.ABSTRACT)) != 0) {
3652 Report.Error (549, Location, "New virtual member `{0}' is declared in a sealed class `{1}'",
3653 GetSignatureForError (), Parent.GetSignatureForError ());
3658 // Any type_name dependent checks
3660 protected virtual void DoMemberTypeDependentChecks ()
3662 // verify accessibility
3663 if (!IsAccessibleAs (MemberType)) {
3664 Report.SymbolRelatedToPreviousError (MemberType);
3665 if (this is Property)
3666 Report.Error (53, Location,
3667 "Inconsistent accessibility: property type `" +
3668 MemberType.GetSignatureForError () + "' is less " +
3669 "accessible than property `" + GetSignatureForError () + "'");
3670 else if (this is Indexer)
3671 Report.Error (54, Location,
3672 "Inconsistent accessibility: indexer return type `" +
3673 MemberType.GetSignatureForError () + "' is less " +
3674 "accessible than indexer `" + GetSignatureForError () + "'");
3675 else if (this is MethodCore) {
3676 if (this is Operator)
3677 Report.Error (56, Location,
3678 "Inconsistent accessibility: return type `" +
3679 MemberType.GetSignatureForError () + "' is less " +
3680 "accessible than operator `" + GetSignatureForError () + "'");
3682 Report.Error (50, Location,
3683 "Inconsistent accessibility: return type `" +
3684 MemberType.GetSignatureForError () + "' is less " +
3685 "accessible than method `" + GetSignatureForError () + "'");
3687 Report.Error (52, Location,
3688 "Inconsistent accessibility: field type `" +
3689 MemberType.GetSignatureForError () + "' is less " +
3690 "accessible than field `" + GetSignatureForError () + "'");
3695 protected void IsTypePermitted ()
3697 if (MemberType.IsSpecialRuntimeType) {
3698 if (Parent is StateMachine) {
3699 Report.Error (4012, Location,
3700 "Parameters or local variables of type `{0}' cannot be declared in async methods or iterators",
3701 MemberType.GetSignatureForError ());
3702 } else if (Parent is HoistedStoreyClass) {
3703 Report.Error (4013, Location,
3704 "Local variables of type `{0}' cannot be used inside anonymous methods, lambda expressions or query expressions",
3705 MemberType.GetSignatureForError ());
3707 Report.Error (610, Location,
3708 "Field or property cannot be of type `{0}'", MemberType.GetSignatureForError ());
3713 protected virtual bool CheckBase ()
3715 CheckProtectedModifier ();
3720 public override string GetSignatureForDocumentation ()
3722 return Parent.GetSignatureForDocumentation () + "." + MemberName.Basename;
3725 protected virtual bool ResolveMemberType ()
3727 if (member_type != null)
3728 throw new InternalErrorException ("Multi-resolve");
3730 member_type = type_expr.ResolveAsType (this);
3731 return member_type != null;