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 protected TypeContainer (TypeContainer parent, MemberName name, Attributes attrs, MemberKind kind)
57 : base (parent, name, attrs)
61 this.Basename = name.Basename;
63 defined_names = new Dictionary<string, MemberCore> ();
66 public override TypeSpec CurrentType {
72 public Dictionary<string, MemberCore> DefinedNames {
78 public TypeDefinition PartialContainer {
80 return main_container;
83 main_container = value;
87 public IList<TypeContainer> Containers {
94 // Any unattached attributes during parsing get added here. User
97 public Attributes UnattachedAttributes {
101 public void AddCompilerGeneratedClass (CompilerGeneratedContainer c)
103 AddTypeContainerMember (c);
106 public virtual void AddPartial (TypeDefinition next_part)
109 (PartialContainer ?? this).defined_names.TryGetValue (next_part.Basename, out mc);
111 AddPartial (next_part, mc as TypeDefinition);
114 protected void AddPartial (TypeDefinition next_part, TypeDefinition existing)
116 next_part.ModFlags |= Modifiers.PARTIAL;
118 if (existing == null) {
119 AddTypeContainer (next_part);
123 if ((existing.ModFlags & Modifiers.PARTIAL) == 0) {
124 if (existing.Kind != next_part.Kind) {
125 AddTypeContainer (next_part);
127 Report.SymbolRelatedToPreviousError (next_part);
128 Error_MissingPartialModifier (existing);
134 if (existing.Kind != next_part.Kind) {
135 Report.SymbolRelatedToPreviousError (existing);
136 Report.Error (261, next_part.Location,
137 "Partial declarations of `{0}' must be all classes, all structs or all interfaces",
138 next_part.GetSignatureForError ());
141 if ((existing.ModFlags & Modifiers.AccessibilityMask) != (next_part.ModFlags & Modifiers.AccessibilityMask) &&
142 ((existing.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) == 0 &&
143 (next_part.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) == 0)) {
144 Report.SymbolRelatedToPreviousError (existing);
145 Report.Error (262, next_part.Location,
146 "Partial declarations of `{0}' have conflicting accessibility modifiers",
147 next_part.GetSignatureForError ());
150 var tc_names = existing.CurrentTypeParameters;
151 if (tc_names != null) {
152 for (int i = 0; i < tc_names.Count; ++i) {
153 var tp = next_part.MemberName.TypeParameters[i];
154 if (tc_names[i].MemberName.Name != tp.MemberName.Name) {
155 Report.SymbolRelatedToPreviousError (existing.Location, "");
156 Report.Error (264, next_part.Location, "Partial declarations of `{0}' must have the same type parameter names in the same order",
157 next_part.GetSignatureForError ());
161 if (tc_names[i].Variance != tp.Variance) {
162 Report.SymbolRelatedToPreviousError (existing.Location, "");
163 Report.Error (1067, next_part.Location, "Partial declarations of `{0}' must have the same type parameter variance modifiers",
164 next_part.GetSignatureForError ());
170 if ((next_part.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) != 0) {
171 existing.ModFlags |= next_part.ModFlags & ~(Modifiers.DEFAULT_ACCESS_MODIFER | Modifiers.AccessibilityMask);
172 } else if ((existing.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) != 0) {
173 existing.ModFlags &= ~(Modifiers.DEFAULT_ACCESS_MODIFER | Modifiers.AccessibilityMask);
174 existing.ModFlags |= next_part.ModFlags;
176 existing.ModFlags |= next_part.ModFlags;
179 existing.Definition.Modifiers = existing.ModFlags;
181 if (next_part.attributes != null) {
182 if (existing.attributes == null)
183 existing.attributes = next_part.attributes;
185 existing.attributes.AddAttributes (next_part.attributes.Attrs);
188 next_part.PartialContainer = existing;
190 existing.AddPartialPart (next_part);
192 AddTypeContainerMember (next_part);
195 public virtual void AddTypeContainer (TypeContainer tc)
197 AddTypeContainerMember (tc);
199 var tparams = tc.MemberName.TypeParameters;
200 if (tparams != null && tc.PartialContainer != null) {
201 var td = (TypeDefinition) tc;
202 for (int i = 0; i < tparams.Count; ++i) {
204 if (tp.MemberName == null)
207 td.AddNameToContainer (tp, tp.Name);
212 protected virtual void AddTypeContainerMember (TypeContainer tc)
217 public virtual void CloseContainer ()
219 if (containers != null) {
220 foreach (TypeContainer tc in containers) {
221 tc.CloseContainer ();
226 public virtual void CreateMetadataName (StringBuilder sb)
228 if (Parent != null && Parent.MemberName != null)
229 Parent.CreateMetadataName (sb);
231 MemberName.CreateMetadataName (sb);
234 public virtual bool CreateContainer ()
236 if (containers != null) {
237 foreach (TypeContainer tc in containers) {
238 tc.CreateContainer ();
245 public override bool Define ()
247 if (containers != null) {
248 foreach (TypeContainer tc in containers) {
253 // Release cache used by parser only
254 if (Module.Evaluator == null) {
255 defined_names = null;
257 defined_names.Clear ();
263 public virtual void PrepareEmit ()
265 if (containers != null) {
266 foreach (var t in containers) {
269 } catch (Exception e) {
270 if (MemberName == MemberName.Null)
273 throw new InternalErrorException (t, e);
279 public virtual bool DefineContainer ()
286 DoDefineContainer ();
288 if (containers != null) {
289 foreach (TypeContainer tc in containers) {
291 tc.DefineContainer ();
292 } catch (Exception e) {
293 if (MemberName == MemberName.Null)
296 throw new InternalErrorException (tc, e);
304 public virtual void ExpandBaseInterfaces ()
306 if (containers != null) {
307 foreach (TypeContainer tc in containers) {
308 tc.ExpandBaseInterfaces ();
313 protected virtual void DefineNamespace ()
315 if (containers != null) {
316 foreach (var tc in containers) {
318 tc.DefineNamespace ();
319 } catch (Exception e) {
320 throw new InternalErrorException (tc, e);
326 protected virtual void DoDefineContainer ()
330 public virtual void EmitContainer ()
332 if (containers != null) {
333 for (int i = 0; i < containers.Count; ++i)
334 containers[i].EmitContainer ();
338 protected void Error_MissingPartialModifier (MemberCore type)
340 Report.Error (260, type.Location,
341 "Missing partial modifier on declaration of type `{0}'. Another partial declaration of this type exists",
342 type.GetSignatureForError ());
345 public override string GetSignatureForDocumentation ()
347 if (Parent != null && Parent.MemberName != null)
348 return Parent.GetSignatureForDocumentation () + "." + MemberName.GetSignatureForDocumentation ();
350 return MemberName.GetSignatureForDocumentation ();
353 public override string GetSignatureForError ()
355 if (Parent != null && Parent.MemberName != null)
356 return Parent.GetSignatureForError () + "." + MemberName.GetSignatureForError ();
358 return MemberName.GetSignatureForError ();
361 public string GetSignatureForMetadata ()
363 if (Parent is TypeDefinition) {
364 return Parent.GetSignatureForMetadata () + "+" + TypeNameParser.Escape (MemberName.Basename);
367 var sb = new StringBuilder ();
368 CreateMetadataName (sb);
369 return sb.ToString ();
372 public virtual void RemoveContainer (TypeContainer cont)
374 if (containers != null)
375 containers.Remove (cont);
377 var tc = Parent == Module ? Module : this;
378 tc.defined_names.Remove (cont.Basename);
381 public virtual void VerifyMembers ()
383 if (containers != null) {
384 foreach (TypeContainer tc in containers)
389 public override void WriteDebugSymbol (MonoSymbolFile file)
391 if (containers != null) {
392 foreach (TypeContainer tc in containers) {
393 tc.WriteDebugSymbol (file);
399 public abstract class TypeDefinition : TypeContainer, ITypeDefinition
402 // Different context is needed when resolving type container base
403 // types. Type names come from the parent scope but type parameter
404 // names from the container scope.
406 public struct BaseContext : IMemberContext
410 public BaseContext (TypeContainer tc)
415 #region IMemberContext Members
417 public CompilerContext Compiler {
418 get { return tc.Compiler; }
421 public TypeSpec CurrentType {
422 get { return tc.Parent.CurrentType; }
425 public TypeParameters CurrentTypeParameters {
426 get { return tc.PartialContainer.CurrentTypeParameters; }
429 public MemberCore CurrentMemberDefinition {
433 public bool IsObsolete {
434 get { return tc.IsObsolete; }
437 public bool IsUnsafe {
438 get { return tc.IsUnsafe; }
441 public bool IsStatic {
442 get { return tc.IsStatic; }
445 public ModuleContainer Module {
446 get { return tc.Module; }
449 public string GetSignatureForError ()
451 return tc.GetSignatureForError ();
454 public ExtensionMethodCandidates LookupExtensionMethod (TypeSpec extensionType, string name, int arity)
459 public FullNamedExpression LookupNamespaceAlias (string name)
461 return tc.Parent.LookupNamespaceAlias (name);
464 public FullNamedExpression LookupNamespaceOrType (string name, int arity, LookupMode mode, Location loc)
467 var tp = CurrentTypeParameters;
469 TypeParameter t = tp.Find (name);
471 return new TypeParameterExpr (t, loc);
475 return tc.Parent.LookupNamespaceOrType (name, arity, mode, loc);
485 GetHashCode = 1 << 1,
486 HasStaticFieldInitializer = 1 << 2
489 readonly List<MemberCore> members;
491 // Holds a list of fields that have initializers
492 protected List<FieldInitializer> initialized_fields;
494 // Holds a list of static fields that have initializers
495 protected List<FieldInitializer> initialized_static_fields;
497 Dictionary<MethodSpec, Method> hoisted_base_call_proxies;
499 Dictionary<string, FullNamedExpression> Cache = new Dictionary<string, FullNamedExpression> ();
502 // Points to the first non-static field added to the container.
504 // This is an arbitrary choice. We are interested in looking at _some_ non-static field,
505 // and the first one's as good as any.
507 protected FieldBase first_nonstatic_field;
510 // This one is computed after we can distinguish interfaces
511 // from classes from the arraylist `type_bases'
513 protected TypeSpec base_type;
514 FullNamedExpression base_type_expr; // TODO: It's temporary variable
515 protected TypeSpec[] iface_exprs;
517 protected List<FullNamedExpression> type_bases;
519 // Partial parts for classes only
520 List<TypeDefinition> class_partial_parts;
522 TypeDefinition InTransit;
524 public TypeBuilder TypeBuilder;
525 GenericTypeParameterBuilder[] all_tp_builders;
527 // All recursive type parameters put together sharing same
528 // TypeParameter instances
530 TypeParameters all_type_parameters;
532 public const string DefaultIndexerName = "Item";
534 bool has_normal_indexers;
536 protected bool requires_delayed_unmanagedtype_check;
538 bool members_defined;
539 bool members_defined_ok;
540 protected bool has_static_constructor;
542 private CachedMethods cached_method;
544 protected TypeSpec spec;
545 TypeSpec current_type;
547 public int DynamicSitesCounter;
548 public int AnonymousMethodsCounter;
549 public int MethodGroupsCounter;
551 static readonly string[] attribute_targets = new string[] { "type" };
554 /// The pending methods that need to be implemented
555 // (interfaces or abstract methods)
557 PendingImplementation pending;
559 protected TypeDefinition (TypeContainer parent, MemberName name, Attributes attrs, MemberKind kind)
560 : base (parent, name, attrs, kind)
562 PartialContainer = this;
563 members = new List<MemberCore> ();
568 public List<FullNamedExpression> BaseTypeExpressions {
574 public override TypeSpec CurrentType {
576 if (current_type == null) {
577 if (IsGenericOrParentIsGeneric) {
579 // Switch to inflated version as it's used by all expressions
581 var targs = CurrentTypeParameters == null ? TypeSpec.EmptyTypes : CurrentTypeParameters.Types;
582 current_type = spec.MakeGenericType (this, targs);
592 public override TypeParameters CurrentTypeParameters {
594 return PartialContainer.MemberName.TypeParameters;
598 int CurrentTypeParametersStartIndex {
600 int total = all_tp_builders.Length;
601 if (CurrentTypeParameters != null) {
602 return total - CurrentTypeParameters.Count;
608 public virtual AssemblyDefinition DeclaringAssembly {
610 return Module.DeclaringAssembly;
614 IAssemblyDefinition ITypeDefinition.DeclaringAssembly {
616 return Module.DeclaringAssembly;
620 public TypeSpec Definition {
626 public bool HasMembersDefined {
628 return members_defined;
632 public bool HasInstanceConstructor {
634 return (caching_flags & Flags.HasInstanceConstructor) != 0;
637 caching_flags |= Flags.HasInstanceConstructor;
641 // Indicated whether container has StructLayout attribute set Explicit
642 public bool HasExplicitLayout {
643 get { return (caching_flags & Flags.HasExplicitLayout) != 0; }
644 set { caching_flags |= Flags.HasExplicitLayout; }
647 public bool HasOperators {
649 return (caching_flags & Flags.HasUserOperators) != 0;
652 caching_flags |= Flags.HasUserOperators;
656 public bool HasStructLayout {
657 get { return (caching_flags & Flags.HasStructLayout) != 0; }
658 set { caching_flags |= Flags.HasStructLayout; }
661 public TypeSpec[] Interfaces {
667 public bool IsGenericOrParentIsGeneric {
669 return all_type_parameters != null;
673 public bool IsTopLevel {
675 return !(Parent is TypeDefinition);
679 public bool IsPartial {
681 return (ModFlags & Modifiers.PARTIAL) != 0;
685 bool ITypeDefinition.IsTypeForwarder {
692 // Returns true for secondary partial containers
696 return PartialContainer != this;
700 public MemberCache MemberCache {
702 return spec.MemberCache;
706 public List<MemberCore> Members {
712 string ITypeDefinition.Namespace {
715 while (p.Kind != MemberKind.Namespace)
718 return p.MemberName == null ? null : p.GetSignatureForError ();
722 public TypeParameters TypeParametersAll {
724 return all_type_parameters;
728 public override string[] ValidAttributeTargets {
730 return attribute_targets;
736 public override void Accept (StructuralVisitor visitor)
738 visitor.Visit (this);
741 public void AddMember (MemberCore symbol)
743 if (symbol.MemberName.ExplicitInterface != null) {
744 if (!(Kind == MemberKind.Class || Kind == MemberKind.Struct)) {
745 Report.Error (541, symbol.Location,
746 "`{0}': explicit interface declaration can only be declared in a class or struct",
747 symbol.GetSignatureForError ());
751 AddNameToContainer (symbol, symbol.MemberName.Name);
752 members.Add (symbol);
755 public override void AddTypeContainer (TypeContainer tc)
757 AddNameToContainer (tc, tc.Basename);
759 base.AddTypeContainer (tc);
762 protected override void AddTypeContainerMember (TypeContainer tc)
766 if (containers == null)
767 containers = new List<TypeContainer> ();
769 base.AddTypeContainerMember (tc);
773 // Adds the member to defined_names table. It tests for duplications and enclosing name conflicts
775 public virtual void AddNameToContainer (MemberCore symbol, string name)
777 if (((ModFlags | symbol.ModFlags) & Modifiers.COMPILER_GENERATED) != 0)
781 if (!PartialContainer.defined_names.TryGetValue (name, out mc)) {
782 PartialContainer.defined_names.Add (name, symbol);
786 if (symbol.EnableOverloadChecks (mc))
789 InterfaceMemberBase im = mc as InterfaceMemberBase;
790 if (im != null && im.IsExplicitImpl)
793 Report.SymbolRelatedToPreviousError (mc);
794 if ((mc.ModFlags & Modifiers.PARTIAL) != 0 && (symbol is ClassOrStruct || symbol is Interface)) {
795 Error_MissingPartialModifier (symbol);
799 if (symbol is TypeParameter) {
800 Report.Error (692, symbol.Location,
801 "Duplicate type parameter `{0}'", symbol.GetSignatureForError ());
803 Report.Error (102, symbol.Location,
804 "The type `{0}' already contains a definition for `{1}'",
805 GetSignatureForError (), name);
811 public void AddConstructor (Constructor c)
813 AddConstructor (c, false);
816 public void AddConstructor (Constructor c, bool isDefault)
818 bool is_static = (c.ModFlags & Modifiers.STATIC) != 0;
820 AddNameToContainer (c, is_static ? Constructor.TypeConstructorName : Constructor.ConstructorName);
822 if (is_static && c.ParameterInfo.IsEmpty) {
823 PartialContainer.has_static_constructor = true;
825 PartialContainer.HasInstanceConstructor = true;
831 public bool AddField (FieldBase field)
835 if ((field.ModFlags & Modifiers.STATIC) != 0)
838 var first_field = PartialContainer.first_nonstatic_field;
839 if (first_field == null) {
840 PartialContainer.first_nonstatic_field = field;
844 if (Kind == MemberKind.Struct && first_field.Parent != field.Parent) {
845 Report.SymbolRelatedToPreviousError (first_field.Parent);
846 Report.Warning (282, 3, field.Location,
847 "struct instance field `{0}' found in different declaration from instance field `{1}'",
848 field.GetSignatureForError (), first_field.GetSignatureForError ());
854 /// Indexer has special handling in constrast to other AddXXX because the name can be driven by IndexerNameAttribute
856 public void AddIndexer (Indexer i)
861 public void AddOperator (Operator op)
863 PartialContainer.HasOperators = true;
867 public void AddPartialPart (TypeDefinition part)
869 if (Kind != MemberKind.Class)
872 if (class_partial_parts == null)
873 class_partial_parts = new List<TypeDefinition> ();
875 class_partial_parts.Add (part);
878 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
880 if (has_normal_indexers && a.Type == pa.DefaultMember) {
881 Report.Error (646, a.Location, "Cannot specify the `DefaultMember' attribute on type containing an indexer");
885 if (a.Type == pa.Required) {
886 Report.Error (1608, a.Location, "The RequiredAttribute attribute is not permitted on C# types");
890 TypeBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
893 public override AttributeTargets AttributeTargets {
895 throw new NotSupportedException ();
899 public TypeSpec BaseType {
901 return spec.BaseType;
905 protected virtual TypeAttributes TypeAttr {
907 return ModifiersExtensions.TypeAttr (ModFlags, IsTopLevel);
911 public int TypeParametersCount {
913 return MemberName.Arity;
917 TypeParameterSpec[] ITypeDefinition.TypeParameters {
919 return PartialContainer.CurrentTypeParameters.Types;
923 public string GetAttributeDefaultMember ()
925 return indexer_name ?? DefaultIndexerName;
928 public bool IsComImport {
930 if (OptAttributes == null)
933 return OptAttributes.Contains (Module.PredefinedAttributes.ComImport);
937 public virtual void RegisterFieldForInitialization (MemberCore field, FieldInitializer expression)
940 PartialContainer.RegisterFieldForInitialization (field, expression);
942 if ((field.ModFlags & Modifiers.STATIC) != 0){
943 if (initialized_static_fields == null) {
944 HasStaticFieldInitializer = true;
945 initialized_static_fields = new List<FieldInitializer> (4);
948 initialized_static_fields.Add (expression);
950 if (initialized_fields == null)
951 initialized_fields = new List<FieldInitializer> (4);
953 initialized_fields.Add (expression);
957 public void ResolveFieldInitializers (BlockContext ec)
959 Debug.Assert (!IsPartialPart);
962 if (initialized_static_fields == null)
965 bool has_complex_initializer = !ec.Module.Compiler.Settings.Optimize;
967 ExpressionStatement [] init = new ExpressionStatement [initialized_static_fields.Count];
968 for (i = 0; i < initialized_static_fields.Count; ++i) {
969 FieldInitializer fi = initialized_static_fields [i];
970 ExpressionStatement s = fi.ResolveStatement (ec);
972 s = EmptyExpressionStatement.Instance;
973 } else if (!fi.IsSideEffectFree) {
974 has_complex_initializer = true;
980 for (i = 0; i < initialized_static_fields.Count; ++i) {
981 FieldInitializer fi = initialized_static_fields [i];
983 // Need special check to not optimize code like this
984 // static int a = b = 5;
987 if (!has_complex_initializer && fi.IsDefaultInitializer)
990 ec.CurrentBlock.AddScopeStatement (new StatementExpression (init [i]));
996 if (initialized_fields == null)
999 for (int i = 0; i < initialized_fields.Count; ++i) {
1000 FieldInitializer fi = initialized_fields [i];
1001 ExpressionStatement s = fi.ResolveStatement (ec);
1006 // Field is re-initialized to its default value => removed
1008 if (fi.IsDefaultInitializer && ec.Module.Compiler.Settings.Optimize)
1011 ec.CurrentBlock.AddScopeStatement (new StatementExpression (s));
1015 public override string DocComment {
1027 public PendingImplementation PendingImplementations {
1028 get { return pending; }
1031 internal override void GenerateDocComment (DocumentationBuilder builder)
1036 base.GenerateDocComment (builder);
1038 foreach (var member in members)
1039 member.GenerateDocComment (builder);
1042 public TypeSpec GetAttributeCoClass ()
1044 if (OptAttributes == null)
1047 Attribute a = OptAttributes.Search (Module.PredefinedAttributes.CoClass);
1051 return a.GetCoClassAttributeValue ();
1054 public AttributeUsageAttribute GetAttributeUsage (PredefinedAttribute pa)
1057 if (OptAttributes != null) {
1058 a = OptAttributes.Search (pa);
1064 return a.GetAttributeUsageAttribute ();
1067 public virtual CompilationSourceFile GetCompilationSourceFile ()
1069 TypeContainer ns = Parent;
1071 var sf = ns as CompilationSourceFile;
1079 public virtual void SetBaseTypes (List<FullNamedExpression> baseTypes)
1081 type_bases = baseTypes;
1085 /// This function computes the Base class and also the
1086 /// list of interfaces that the class or struct @c implements.
1088 /// The return value is an array (might be null) of
1089 /// interfaces implemented (as Types).
1091 /// The @base_class argument is set to the base object or null
1092 /// if this is `System.Object'.
1094 protected virtual TypeSpec[] ResolveBaseTypes (out FullNamedExpression base_class)
1097 if (type_bases == null)
1100 int count = type_bases.Count;
1101 TypeSpec[] ifaces = null;
1102 var base_context = new BaseContext (this);
1103 for (int i = 0, j = 0; i < count; i++){
1104 FullNamedExpression fne = type_bases [i];
1106 var fne_resolved = fne.ResolveAsType (base_context);
1107 if (fne_resolved == null)
1110 if (i == 0 && Kind == MemberKind.Class && !fne_resolved.IsInterface) {
1111 if (fne_resolved.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
1112 Report.Error (1965, Location, "Class `{0}' cannot derive from the dynamic type",
1113 GetSignatureForError ());
1118 base_type = fne_resolved;
1124 ifaces = new TypeSpec [count - i];
1126 if (fne_resolved.IsInterface) {
1127 for (int ii = 0; ii < j; ++ii) {
1128 if (fne_resolved == ifaces [ii]) {
1129 Report.Error (528, Location, "`{0}' is already listed in interface list",
1130 fne_resolved.GetSignatureForError ());
1135 if (Kind == MemberKind.Interface && !IsAccessibleAs (fne_resolved)) {
1136 Report.Error (61, fne.Location,
1137 "Inconsistent accessibility: base interface `{0}' is less accessible than interface `{1}'",
1138 fne_resolved.GetSignatureForError (), GetSignatureForError ());
1141 Report.SymbolRelatedToPreviousError (fne_resolved);
1142 if (Kind != MemberKind.Class) {
1143 Report.Error (527, fne.Location, "Type `{0}' in interface list is not an interface", fne_resolved.GetSignatureForError ());
1144 } else if (base_class != null)
1145 Report.Error (1721, fne.Location, "`{0}': Classes cannot have multiple base classes (`{1}' and `{2}')",
1146 GetSignatureForError (), base_class.GetSignatureForError (), fne_resolved.GetSignatureForError ());
1148 Report.Error (1722, fne.Location, "`{0}': Base class `{1}' must be specified as first",
1149 GetSignatureForError (), fne_resolved.GetSignatureForError ());
1153 ifaces [j++] = fne_resolved;
1160 // Checks that some operators come in pairs:
1166 // They are matched based on the return type and the argument types
1168 void CheckPairedOperators ()
1170 bool has_equality_or_inequality = false;
1171 List<Operator.OpType> found_matched = new List<Operator.OpType> ();
1173 for (int i = 0; i < members.Count; ++i) {
1174 var o_a = members[i] as Operator;
1178 var o_type = o_a.OperatorType;
1179 if (o_type == Operator.OpType.Equality || o_type == Operator.OpType.Inequality)
1180 has_equality_or_inequality = true;
1182 if (found_matched.Contains (o_type))
1185 var matching_type = o_a.GetMatchingOperator ();
1186 if (matching_type == Operator.OpType.TOP) {
1190 bool pair_found = false;
1191 for (int ii = 0; ii < members.Count; ++ii) {
1192 var o_b = members[ii] as Operator;
1193 if (o_b == null || o_b.OperatorType != matching_type)
1196 if (!TypeSpecComparer.IsEqual (o_a.ReturnType, o_b.ReturnType))
1199 if (!TypeSpecComparer.Equals (o_a.ParameterTypes, o_b.ParameterTypes))
1202 found_matched.Add (matching_type);
1208 Report.Error (216, o_a.Location,
1209 "The operator `{0}' requires a matching operator `{1}' to also be defined",
1210 o_a.GetSignatureForError (), Operator.GetName (matching_type));
1214 if (has_equality_or_inequality) {
1216 Report.Warning (660, 2, Location, "`{0}' defines operator == or operator != but does not override Object.Equals(object o)",
1217 GetSignatureForError ());
1219 if (!HasGetHashCode)
1220 Report.Warning (661, 2, Location, "`{0}' defines operator == or operator != but does not override Object.GetHashCode()",
1221 GetSignatureForError ());
1225 public override void CreateMetadataName (StringBuilder sb)
1227 if (Parent.MemberName != null) {
1228 Parent.CreateMetadataName (sb);
1230 if (sb.Length != 0) {
1235 sb.Append (MemberName.Basename);
1238 bool CreateTypeBuilder ()
1241 // Sets .size to 1 for structs with no instance fields
1243 int type_size = Kind == MemberKind.Struct && first_nonstatic_field == null && !(this is StateMachine) ? 1 : 0;
1245 var parent_def = Parent as TypeDefinition;
1246 if (parent_def == null) {
1247 var sb = new StringBuilder ();
1248 CreateMetadataName (sb);
1249 TypeBuilder = Module.CreateBuilder (sb.ToString (), TypeAttr, type_size);
1251 TypeBuilder = parent_def.TypeBuilder.DefineNestedType (Basename, TypeAttr, null, type_size);
1254 if (DeclaringAssembly.Importer != null)
1255 DeclaringAssembly.Importer.AddCompiledType (TypeBuilder, spec);
1257 spec.SetMetaInfo (TypeBuilder);
1258 spec.MemberCache = new MemberCache (this);
1260 TypeParameters parentAllTypeParameters = null;
1261 if (parent_def != null) {
1262 spec.DeclaringType = Parent.CurrentType;
1263 parent_def.MemberCache.AddMember (spec);
1264 parentAllTypeParameters = parent_def.all_type_parameters;
1267 if (MemberName.TypeParameters != null || parentAllTypeParameters != null) {
1268 var tparam_names = CreateTypeParameters (parentAllTypeParameters);
1270 all_tp_builders = TypeBuilder.DefineGenericParameters (tparam_names);
1272 if (CurrentTypeParameters != null) {
1273 CurrentTypeParameters.Create (spec, CurrentTypeParametersStartIndex, this);
1274 CurrentTypeParameters.Define (all_tp_builders);
1281 string[] CreateTypeParameters (TypeParameters parentAllTypeParameters)
1284 int parent_offset = 0;
1285 if (parentAllTypeParameters != null) {
1286 if (CurrentTypeParameters == null) {
1287 all_type_parameters = parentAllTypeParameters;
1288 return parentAllTypeParameters.GetAllNames ();
1291 names = new string[parentAllTypeParameters.Count + CurrentTypeParameters.Count];
1292 all_type_parameters = new TypeParameters (names.Length);
1293 all_type_parameters.Add (parentAllTypeParameters);
1295 parent_offset = all_type_parameters.Count;
1296 for (int i = 0; i < parent_offset; ++i)
1297 names[i] = all_type_parameters[i].MemberName.Name;
1300 names = new string[CurrentTypeParameters.Count];
1303 for (int i = 0; i < CurrentTypeParameters.Count; ++i) {
1304 if (all_type_parameters != null)
1305 all_type_parameters.Add (MemberName.TypeParameters[i]);
1307 var name = CurrentTypeParameters[i].MemberName.Name;
1308 names[parent_offset + i] = name;
1309 for (int ii = 0; ii < parent_offset + i; ++ii) {
1310 if (names[ii] != name)
1313 var tp = CurrentTypeParameters[i];
1314 var conflict = all_type_parameters[ii];
1316 tp.WarningParentNameConflict (conflict);
1320 if (all_type_parameters == null)
1321 all_type_parameters = CurrentTypeParameters;
1327 public SourceMethodBuilder CreateMethodSymbolEntry ()
1329 if (Module.DeclaringAssembly.SymbolWriter == null)
1332 var source_file = GetCompilationSourceFile ();
1333 if (source_file == null)
1336 return new SourceMethodBuilder (source_file.SymbolUnitEntry);
1340 // Creates a proxy base method call inside this container for hoisted base member calls
1342 public MethodSpec CreateHoistedBaseCallProxy (ResolveContext rc, MethodSpec method)
1344 Method proxy_method;
1347 // One proxy per base method is enough
1349 if (hoisted_base_call_proxies == null) {
1350 hoisted_base_call_proxies = new Dictionary<MethodSpec, Method> ();
1351 proxy_method = null;
1353 hoisted_base_call_proxies.TryGetValue (method, out proxy_method);
1356 if (proxy_method == null) {
1357 string name = CompilerGeneratedContainer.MakeName (method.Name, null, "BaseCallProxy", hoisted_base_call_proxies.Count);
1359 MemberName member_name;
1360 TypeArguments targs = null;
1361 TypeSpec return_type = method.ReturnType;
1362 var local_param_types = method.Parameters.Types;
1364 if (method.IsGeneric) {
1366 // Copy all base generic method type parameters info
1368 var hoisted_tparams = method.GenericDefinition.TypeParameters;
1369 var tparams = new TypeParameters ();
1371 targs = new TypeArguments ();
1372 targs.Arguments = new TypeSpec[hoisted_tparams.Length];
1373 for (int i = 0; i < hoisted_tparams.Length; ++i) {
1374 var tp = hoisted_tparams[i];
1375 var local_tp = new TypeParameter (tp, null, new MemberName (tp.Name, Location), null);
1376 tparams.Add (local_tp);
1378 targs.Add (new SimpleName (tp.Name, Location));
1379 targs.Arguments[i] = local_tp.Type;
1382 member_name = new MemberName (name, tparams, Location);
1385 // Mutate any method type parameters from original
1386 // to newly created hoisted version
1388 var mutator = new TypeParameterMutator (hoisted_tparams, tparams);
1389 return_type = mutator.Mutate (return_type);
1390 local_param_types = mutator.Mutate (local_param_types);
1392 member_name = new MemberName (name);
1395 var base_parameters = new Parameter[method.Parameters.Count];
1396 for (int i = 0; i < base_parameters.Length; ++i) {
1397 var base_param = method.Parameters.FixedParameters[i];
1398 base_parameters[i] = new Parameter (new TypeExpression (local_param_types [i], Location),
1399 base_param.Name, base_param.ModFlags, null, Location);
1400 base_parameters[i].Resolve (this, i);
1403 var cloned_params = ParametersCompiled.CreateFullyResolved (base_parameters, method.Parameters.Types);
1404 if (method.Parameters.HasArglist) {
1405 cloned_params.FixedParameters[0] = new Parameter (null, "__arglist", Parameter.Modifier.NONE, null, Location);
1406 cloned_params.Types[0] = Module.PredefinedTypes.RuntimeArgumentHandle.Resolve ();
1409 // Compiler generated proxy
1410 proxy_method = new Method (this, new TypeExpression (return_type, Location),
1411 Modifiers.PRIVATE | Modifiers.COMPILER_GENERATED | Modifiers.DEBUGGER_HIDDEN,
1412 member_name, cloned_params, null);
1414 var block = new ToplevelBlock (Compiler, proxy_method.ParameterInfo, Location) {
1415 IsCompilerGenerated = true
1418 var mg = MethodGroupExpr.CreatePredefined (method, method.DeclaringType, Location);
1419 mg.InstanceExpression = new BaseThis (method.DeclaringType, Location);
1421 mg.SetTypeArguments (rc, targs);
1423 // Get all the method parameters and pass them as arguments
1424 var real_base_call = new Invocation (mg, block.GetAllParametersArguments ());
1425 Statement statement;
1426 if (method.ReturnType.Kind == MemberKind.Void)
1427 statement = new StatementExpression (real_base_call);
1429 statement = new Return (real_base_call, Location);
1431 block.AddStatement (statement);
1432 proxy_method.Block = block;
1434 members.Add (proxy_method);
1435 proxy_method.Define ();
1436 proxy_method.PrepareEmit ();
1438 hoisted_base_call_proxies.Add (method, proxy_method);
1441 return proxy_method.Spec;
1444 protected bool DefineBaseTypes ()
1446 if (IsPartialPart && Kind == MemberKind.Class)
1449 return DoDefineBaseType ();
1452 bool DoDefineBaseType ()
1454 iface_exprs = ResolveBaseTypes (out base_type_expr);
1457 if (IsPartialPart) {
1458 set_base_type = false;
1460 if (base_type_expr != null) {
1461 if (PartialContainer.base_type_expr != null && PartialContainer.base_type != base_type) {
1462 Report.SymbolRelatedToPreviousError (base_type_expr.Location, "");
1463 Report.Error (263, Location,
1464 "Partial declarations of `{0}' must not specify different base classes",
1465 GetSignatureForError ());
1467 PartialContainer.base_type_expr = base_type_expr;
1468 PartialContainer.base_type = base_type;
1469 set_base_type = true;
1473 if (iface_exprs != null) {
1474 if (PartialContainer.iface_exprs == null)
1475 PartialContainer.iface_exprs = iface_exprs;
1477 var ifaces = new List<TypeSpec> (PartialContainer.iface_exprs);
1478 foreach (var iface_partial in iface_exprs) {
1479 if (ifaces.Contains (iface_partial))
1482 ifaces.Add (iface_partial);
1485 PartialContainer.iface_exprs = ifaces.ToArray ();
1489 PartialContainer.members.AddRange (members);
1490 if (containers != null) {
1491 if (PartialContainer.containers == null)
1492 PartialContainer.containers = new List<TypeContainer> ();
1494 PartialContainer.containers.AddRange (containers);
1497 members_defined = members_defined_ok = true;
1498 caching_flags |= Flags.CloseTypeCreated;
1500 set_base_type = true;
1503 var cycle = CheckRecursiveDefinition (this);
1504 if (cycle != null) {
1505 Report.SymbolRelatedToPreviousError (cycle);
1506 if (this is Interface) {
1507 Report.Error (529, Location,
1508 "Inherited interface `{0}' causes a cycle in the interface hierarchy of `{1}'",
1509 GetSignatureForError (), cycle.GetSignatureForError ());
1512 PartialContainer.iface_exprs = null;
1514 Report.Error (146, Location,
1515 "Circular base class dependency involving `{0}' and `{1}'",
1516 GetSignatureForError (), cycle.GetSignatureForError ());
1519 PartialContainer.base_type = null;
1523 if (iface_exprs != null) {
1524 foreach (var iface_type in iface_exprs) {
1525 // Prevents a crash, the interface might not have been resolved: 442144
1526 if (iface_type == null)
1529 if (!spec.AddInterfaceDefined (iface_type))
1532 TypeBuilder.AddInterfaceImplementation (iface_type.GetMetaInfo ());
1536 if (Kind == MemberKind.Interface) {
1537 spec.BaseType = Compiler.BuiltinTypes.Object;
1541 if (set_base_type) {
1546 // Base type of partial container has to be resolved before we
1547 // resolve any nested types of the container. We need to know
1548 // partial parts because the base type can be specified in file
1549 // defined after current container
1551 if (class_partial_parts != null) {
1552 foreach (var pp in class_partial_parts)
1553 pp.DoDefineBaseType ();
1562 if (base_type == null) {
1563 TypeBuilder.SetParent (null);
1567 if (spec.BaseType == base_type)
1570 spec.BaseType = base_type;
1573 spec.UpdateInflatedInstancesBaseType ();
1575 // Set base type after type creation
1576 TypeBuilder.SetParent (base_type.GetMetaInfo ());
1579 public override void ExpandBaseInterfaces ()
1582 DoExpandBaseInterfaces ();
1584 base.ExpandBaseInterfaces ();
1587 public void DoExpandBaseInterfaces ()
1589 if ((caching_flags & Flags.InterfacesExpanded) != 0)
1592 caching_flags |= Flags.InterfacesExpanded;
1595 // Expand base interfaces. It cannot be done earlier because all partial
1596 // interface parts need to be defined before the type they are used from
1598 if (iface_exprs != null) {
1599 foreach (var iface in iface_exprs) {
1603 var td = iface.MemberDefinition as TypeDefinition;
1605 td.DoExpandBaseInterfaces ();
1607 if (iface.Interfaces == null)
1610 foreach (var biface in iface.Interfaces) {
1611 if (spec.AddInterfaceDefined (biface)) {
1612 TypeBuilder.AddInterfaceImplementation (biface.GetMetaInfo ());
1619 // Include all base type interfaces too, see ImportTypeBase for details
1621 if (base_type != null) {
1622 var td = base_type.MemberDefinition as TypeDefinition;
1624 td.DoExpandBaseInterfaces ();
1627 // Simply use base interfaces only, they are all expanded which makes
1628 // it easy to handle generic type argument propagation with single
1631 // interface IA<T> : IB<T>
1632 // interface IB<U> : IC<U>
1635 if (base_type.Interfaces != null) {
1636 foreach (var iface in base_type.Interfaces) {
1637 spec.AddInterfaceDefined (iface);
1643 public override void PrepareEmit ()
1645 if ((caching_flags & Flags.CloseTypeCreated) != 0)
1648 foreach (var member in members) {
1649 var pm = member as IParametersMember;
1651 var mc = member as MethodOrOperator;
1656 var p = pm.Parameters;
1660 ((ParametersCompiled) p).ResolveDefaultValues (member);
1663 var c = member as Const;
1668 base.PrepareEmit ();
1672 // Defines the type in the appropriate ModuleBuilder or TypeBuilder.
1674 public override bool CreateContainer ()
1676 if (TypeBuilder != null)
1682 if (IsPartialPart) {
1683 spec = PartialContainer.spec;
1684 TypeBuilder = PartialContainer.TypeBuilder;
1685 all_tp_builders = PartialContainer.all_tp_builders;
1686 all_type_parameters = PartialContainer.all_type_parameters;
1688 if (!CreateTypeBuilder ()) {
1694 return base.CreateContainer ();
1697 protected override void DoDefineContainer ()
1701 DoResolveTypeParameters ();
1705 // Replaces normal spec with predefined one when compiling corlib
1706 // and this type container defines predefined type
1708 public void SetPredefinedSpec (BuiltinTypeSpec spec)
1710 // When compiling build-in types we start with two
1711 // version of same type. One is of BuiltinTypeSpec and
1712 // second one is ordinary TypeSpec. The unification
1713 // happens at later stage when we know which type
1714 // really matches the builtin type signature. However
1715 // that means TypeSpec create during CreateType of this
1716 // type has to be replaced with builtin one
1718 spec.SetMetaInfo (TypeBuilder);
1719 spec.MemberCache = this.spec.MemberCache;
1720 spec.DeclaringType = this.spec.DeclaringType;
1723 current_type = null;
1726 public override void RemoveContainer (TypeContainer cont)
1728 base.RemoveContainer (cont);
1729 Members.Remove (cont);
1730 Cache.Remove (cont.Basename);
1733 protected virtual bool DoResolveTypeParameters ()
1735 var tparams = CurrentTypeParameters;
1736 if (tparams == null)
1739 var base_context = new BaseContext (this);
1740 for (int i = 0; i < tparams.Count; ++i) {
1741 var tp = tparams[i];
1743 if (!tp.ResolveConstraints (base_context)) {
1749 if (IsPartialPart) {
1750 PartialContainer.CurrentTypeParameters.UpdateConstraints (this);
1756 TypeSpec CheckRecursiveDefinition (TypeDefinition tc)
1758 if (InTransit != null)
1763 if (base_type != null) {
1764 var ptc = base_type.MemberDefinition as TypeDefinition;
1765 if (ptc != null && ptc.CheckRecursiveDefinition (this) != null)
1769 if (iface_exprs != null) {
1770 foreach (var iface in iface_exprs) {
1771 // the interface might not have been resolved, prevents a crash, see #442144
1774 var ptc = iface.MemberDefinition as Interface;
1775 if (ptc != null && ptc.CheckRecursiveDefinition (this) != null)
1780 if (!IsTopLevel && Parent.PartialContainer.CheckRecursiveDefinition (this) != null)
1788 /// Populates our TypeBuilder with fields and methods
1790 public sealed override bool Define ()
1792 if (members_defined)
1793 return members_defined_ok;
1795 members_defined_ok = DoDefineMembers ();
1796 members_defined = true;
1800 return members_defined_ok;
1803 protected virtual bool DoDefineMembers ()
1805 Debug.Assert (!IsPartialPart);
1807 if (iface_exprs != null) {
1808 foreach (var iface_type in iface_exprs) {
1809 if (iface_type == null)
1812 // Ensure the base is always setup
1813 var compiled_iface = iface_type.MemberDefinition as Interface;
1814 if (compiled_iface != null)
1815 compiled_iface.Define ();
1817 ObsoleteAttribute oa = iface_type.GetAttributeObsolete ();
1818 if (oa != null && !IsObsolete)
1819 AttributeTester.Report_ObsoleteMessage (oa, iface_type.GetSignatureForError (), Location, Report);
1821 if (iface_type.Arity > 0) {
1822 // TODO: passing `this' is wrong, should be base type iface instead
1823 VarianceDecl.CheckTypeVariance (iface_type, Variance.Covariant, this);
1825 if (((InflatedTypeSpec) iface_type).HasDynamicArgument () && !IsCompilerGenerated) {
1826 Report.Error (1966, Location,
1827 "`{0}': cannot implement a dynamic interface `{1}'",
1828 GetSignatureForError (), iface_type.GetSignatureForError ());
1833 if (iface_type.IsGenericOrParentIsGeneric) {
1834 foreach (var prev_iface in iface_exprs) {
1835 if (prev_iface == iface_type || prev_iface == null)
1838 if (!TypeSpecComparer.Unify.IsEqual (iface_type, prev_iface))
1841 Report.Error (695, Location,
1842 "`{0}' cannot implement both `{1}' and `{2}' because they may unify for some type parameter substitutions",
1843 GetSignatureForError (), prev_iface.GetSignatureForError (), iface_type.GetSignatureForError ());
1848 if (Kind == MemberKind.Interface) {
1849 foreach (var iface in spec.Interfaces) {
1850 MemberCache.AddInterface (iface);
1855 if (base_type != null) {
1857 // Run checks skipped during DefineType (e.g FullNamedExpression::ResolveAsType)
1859 if (base_type_expr != null) {
1860 ObsoleteAttribute obsolete_attr = base_type.GetAttributeObsolete ();
1861 if (obsolete_attr != null && !IsObsolete)
1862 AttributeTester.Report_ObsoleteMessage (obsolete_attr, base_type.GetSignatureForError (), base_type_expr.Location, Report);
1864 if (IsGenericOrParentIsGeneric && base_type.IsAttribute) {
1865 Report.Error (698, base_type_expr.Location,
1866 "A generic type cannot derive from `{0}' because it is an attribute class",
1867 base_type.GetSignatureForError ());
1871 var baseContainer = base_type.MemberDefinition as ClassOrStruct;
1872 if (baseContainer != null) {
1873 baseContainer.Define ();
1876 // It can trigger define of this type (for generic types only)
1878 if (HasMembersDefined)
1883 if (Kind == MemberKind.Struct || Kind == MemberKind.Class) {
1884 pending = PendingImplementation.GetPendingImplementations (this);
1887 var count = members.Count;
1888 for (int i = 0; i < count; ++i) {
1889 var mc = members[i] as InterfaceMemberBase;
1890 if (mc == null || !mc.IsExplicitImpl)
1895 } catch (Exception e) {
1896 throw new InternalErrorException (mc, e);
1900 for (int i = 0; i < count; ++i) {
1901 var mc = members[i] as InterfaceMemberBase;
1902 if (mc != null && mc.IsExplicitImpl)
1905 if (members[i] is TypeContainer)
1909 members[i].Define ();
1910 } catch (Exception e) {
1911 throw new InternalErrorException (members[i], e);
1916 CheckPairedOperators ();
1919 if (requires_delayed_unmanagedtype_check) {
1920 requires_delayed_unmanagedtype_check = false;
1921 foreach (var member in members) {
1922 var f = member as Field;
1923 if (f != null && f.MemberType != null && f.MemberType.IsPointer)
1924 TypeManager.VerifyUnmanaged (Module, f.MemberType, f.Location);
1928 ComputeIndexerName();
1930 if (HasEquals && !HasGetHashCode) {
1931 Report.Warning (659, 3, Location,
1932 "`{0}' overrides Object.Equals(object) but does not override Object.GetHashCode()", GetSignatureForError ());
1935 if (Kind == MemberKind.Interface && iface_exprs != null) {
1936 MemberCache.RemoveHiddenMembers (spec);
1942 void ComputeIndexerName ()
1944 var indexers = MemberCache.FindMembers (spec, MemberCache.IndexerNameAlias, true);
1945 if (indexers == null)
1948 string class_indexer_name = null;
1951 // Check normal indexers for consistent name, explicit interface implementation
1952 // indexers are ignored
1954 foreach (var indexer in indexers) {
1956 // FindMembers can return unfiltered full hierarchy names
1958 if (indexer.DeclaringType != spec)
1961 has_normal_indexers = true;
1963 if (class_indexer_name == null) {
1964 indexer_name = class_indexer_name = indexer.Name;
1968 if (indexer.Name != class_indexer_name)
1969 Report.Error (668, ((Indexer)indexer.MemberDefinition).Location,
1970 "Two indexers have different names; the IndexerName attribute must be used with the same name on every indexer within a type");
1974 void EmitIndexerName ()
1976 if (!has_normal_indexers)
1979 var ctor = Module.PredefinedMembers.DefaultMemberAttributeCtor.Get ();
1983 var encoder = new AttributeEncoder ();
1984 encoder.Encode (GetAttributeDefaultMember ());
1985 encoder.EncodeEmptyNamedArguments ();
1987 TypeBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray ());
1990 public override void VerifyMembers ()
1993 // Check for internal or private fields that were never assigned
1995 if (!IsCompilerGenerated && Compiler.Settings.WarningLevel >= 3 && this == PartialContainer) {
1996 bool is_type_exposed = Kind == MemberKind.Struct || IsExposedFromAssembly ();
1997 foreach (var member in members) {
1998 if (member is Event) {
2000 // An event can be assigned from same class only, so we can report
2001 // this warning for all accessibility modes
2004 Report.Warning (67, 3, member.Location, "The event `{0}' is never used", member.GetSignatureForError ());
2009 if ((member.ModFlags & Modifiers.AccessibilityMask) != Modifiers.PRIVATE) {
2010 if (is_type_exposed)
2013 member.SetIsUsed ();
2016 var f = member as Field;
2020 if (!member.IsUsed) {
2021 if ((member.caching_flags & Flags.IsAssigned) == 0) {
2022 Report.Warning (169, 3, member.Location, "The private field `{0}' is never used", member.GetSignatureForError ());
2024 Report.Warning (414, 3, member.Location, "The private field `{0}' is assigned but its value is never used",
2025 member.GetSignatureForError ());
2030 if ((f.caching_flags & Flags.IsAssigned) != 0)
2034 // Only report 649 on level 4
2036 if (Compiler.Settings.WarningLevel < 4)
2040 // Don't be pedantic when type requires specific layout
2042 if (f.OptAttributes != null || PartialContainer.HasStructLayout)
2045 Constant c = New.Constantify (f.MemberType, f.Location);
2048 value = c.GetValueAsLiteral ();
2049 } else if (TypeSpec.IsReferenceType (f.MemberType)) {
2056 value = " `" + value + "'";
2058 Report.Warning (649, 4, f.Location, "Field `{0}' is never assigned to, and will always have its default value{1}",
2059 f.GetSignatureForError (), value);
2063 base.VerifyMembers ();
2066 public override void Emit ()
2068 if (OptAttributes != null)
2069 OptAttributes.Emit ();
2071 if (!IsCompilerGenerated) {
2073 MemberSpec candidate;
2074 bool overrides = false;
2075 var conflict_symbol = MemberCache.FindBaseMember (this, out candidate, ref overrides);
2076 if (conflict_symbol == null && candidate == null) {
2077 if ((ModFlags & Modifiers.NEW) != 0)
2078 Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required",
2079 GetSignatureForError ());
2081 if ((ModFlags & Modifiers.NEW) == 0) {
2082 if (candidate == null)
2083 candidate = conflict_symbol;
2085 Report.SymbolRelatedToPreviousError (candidate);
2086 Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
2087 GetSignatureForError (), candidate.GetSignatureForError ());
2092 // Run constraints check on all possible generic types
2093 if (base_type != null && base_type_expr != null) {
2094 ConstraintChecker.Check (this, base_type, base_type_expr.Location);
2097 if (iface_exprs != null) {
2098 foreach (var iface_type in iface_exprs) {
2099 if (iface_type == null)
2102 ConstraintChecker.Check (this, iface_type, Location); // TODO: Location is wrong
2107 if (all_tp_builders != null) {
2108 int current_starts_index = CurrentTypeParametersStartIndex;
2109 for (int i = 0; i < all_tp_builders.Length; i++) {
2110 if (i < current_starts_index) {
2111 all_type_parameters[i].EmitConstraints (all_tp_builders [i]);
2113 var tp = CurrentTypeParameters [i - current_starts_index];
2114 tp.CheckGenericConstraints (!IsObsolete);
2120 if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0 && !Parent.IsCompilerGenerated)
2121 Module.PredefinedAttributes.CompilerGenerated.EmitAttribute (TypeBuilder);
2124 if ((TypeBuilder.Attributes & TypeAttributes.StringFormatMask) == 0 && Module.HasDefaultCharSet)
2125 TypeBuilder.__SetAttributes (TypeBuilder.Attributes | Module.DefaultCharSetType);
2130 for (int i = 0; i < members.Count; i++) {
2132 if ((m.caching_flags & Flags.CloseTypeCreated) != 0)
2139 CheckAttributeClsCompliance ();
2141 if (pending != null)
2142 pending.VerifyPendingMethods ();
2146 void CheckAttributeClsCompliance ()
2148 if (!spec.IsAttribute || !IsExposedFromAssembly () || !Compiler.Settings.VerifyClsCompliance || !IsClsComplianceRequired ())
2151 foreach (var m in members) {
2152 var c = m as Constructor;
2156 if (c.HasCompliantArgs)
2160 Report.Warning (3015, 1, Location, "`{0}' has no accessible constructors which use only CLS-compliant types", GetSignatureForError ());
2163 public sealed override void EmitContainer ()
2165 if ((caching_flags & Flags.CloseTypeCreated) != 0)
2171 public override void CloseContainer ()
2173 if ((caching_flags & Flags.CloseTypeCreated) != 0)
2176 // Close base type container first to avoid TypeLoadException
2177 if (spec.BaseType != null) {
2178 var btype = spec.BaseType.MemberDefinition as TypeContainer;
2179 if (btype != null) {
2180 btype.CloseContainer ();
2182 if ((caching_flags & Flags.CloseTypeCreated) != 0)
2188 caching_flags |= Flags.CloseTypeCreated;
2189 TypeBuilder.CreateType ();
2190 } catch (TypeLoadException) {
2192 // This is fine, the code still created the type
2194 } catch (Exception e) {
2195 throw new InternalErrorException (this, e);
2198 base.CloseContainer ();
2201 initialized_fields = null;
2202 initialized_static_fields = null;
2204 OptAttributes = null;
2208 // Performs the validation on a Method's modifiers (properties have
2209 // the same properties).
2211 // TODO: Why is it not done at parse stage, move to Modifiers::Check
2213 public bool MethodModifiersValid (MemberCore mc)
2215 const Modifiers vao = (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE);
2216 const Modifiers nv = (Modifiers.NEW | Modifiers.VIRTUAL);
2218 var flags = mc.ModFlags;
2221 // At most one of static, virtual or override
2223 if ((flags & Modifiers.STATIC) != 0){
2224 if ((flags & vao) != 0){
2225 Report.Error (112, mc.Location, "A static member `{0}' cannot be marked as override, virtual or abstract",
2226 mc.GetSignatureForError ());
2231 if ((flags & Modifiers.OVERRIDE) != 0 && (flags & nv) != 0){
2232 Report.Error (113, mc.Location, "A member `{0}' marked as override cannot be marked as new or virtual",
2233 mc.GetSignatureForError ());
2238 // If the declaration includes the abstract modifier, then the
2239 // declaration does not include static, virtual or extern
2241 if ((flags & Modifiers.ABSTRACT) != 0){
2242 if ((flags & Modifiers.EXTERN) != 0){
2244 180, mc.Location, "`{0}' cannot be both extern and abstract", mc.GetSignatureForError ());
2248 if ((flags & Modifiers.SEALED) != 0) {
2249 Report.Error (502, mc.Location, "`{0}' cannot be both abstract and sealed", mc.GetSignatureForError ());
2253 if ((flags & Modifiers.VIRTUAL) != 0){
2254 Report.Error (503, mc.Location, "The abstract method `{0}' cannot be marked virtual", mc.GetSignatureForError ());
2258 if ((ModFlags & Modifiers.ABSTRACT) == 0){
2259 Report.SymbolRelatedToPreviousError (this);
2260 Report.Error (513, mc.Location, "`{0}' is abstract but it is declared in the non-abstract class `{1}'",
2261 mc.GetSignatureForError (), GetSignatureForError ());
2266 if ((flags & Modifiers.PRIVATE) != 0){
2267 if ((flags & vao) != 0){
2268 Report.Error (621, mc.Location, "`{0}': virtual or abstract members cannot be private", mc.GetSignatureForError ());
2273 if ((flags & Modifiers.SEALED) != 0){
2274 if ((flags & Modifiers.OVERRIDE) == 0){
2275 Report.Error (238, mc.Location, "`{0}' cannot be sealed because it is not an override", mc.GetSignatureForError ());
2283 protected override bool VerifyClsCompliance ()
2285 if (!base.VerifyClsCompliance ())
2288 // Check all container names for user classes
2289 if (Kind != MemberKind.Delegate)
2290 MemberCache.VerifyClsCompliance (Definition, Report);
2292 if (BaseType != null && !BaseType.IsCLSCompliant ()) {
2293 Report.Warning (3009, 1, Location, "`{0}': base type `{1}' is not CLS-compliant",
2294 GetSignatureForError (), BaseType.GetSignatureForError ());
2300 /// Performs checks for an explicit interface implementation. First it
2301 /// checks whether the `interface_type' is a base inteface implementation.
2302 /// Then it checks whether `name' exists in the interface type.
2304 public bool VerifyImplements (InterfaceMemberBase mb)
2306 var ifaces = spec.Interfaces;
2307 if (ifaces != null) {
2308 foreach (TypeSpec t in ifaces){
2309 if (t == mb.InterfaceType)
2314 Report.SymbolRelatedToPreviousError (mb.InterfaceType);
2315 Report.Error (540, mb.Location, "`{0}': containing type does not implement interface `{1}'",
2316 mb.GetSignatureForError (), mb.InterfaceType.GetSignatureForError ());
2321 // Used for visiblity checks to tests whether this definition shares
2322 // base type baseType, it does member-definition search
2324 public bool IsBaseTypeDefinition (TypeSpec baseType)
2326 // RootContext check
2327 if (TypeBuilder == null)
2332 if (type.MemberDefinition == baseType.MemberDefinition)
2335 type = type.BaseType;
2336 } while (type != null);
2341 public override bool IsClsComplianceRequired ()
2344 return PartialContainer.IsClsComplianceRequired ();
2346 return base.IsClsComplianceRequired ();
2349 bool ITypeDefinition.IsInternalAsPublic (IAssemblyDefinition assembly)
2351 return Module.DeclaringAssembly == assembly;
2354 public virtual bool IsUnmanagedType ()
2359 public void LoadMembers (TypeSpec declaringType, bool onlyTypes, ref MemberCache cache)
2361 throw new NotSupportedException ("Not supported for compiled definition " + GetSignatureForError ());
2365 // Public function used to locate types.
2367 // Set 'ignore_cs0104' to true if you want to ignore cs0104 errors.
2369 // Returns: Type or null if they type can not be found.
2371 public override FullNamedExpression LookupNamespaceOrType (string name, int arity, LookupMode mode, Location loc)
2373 FullNamedExpression e;
2374 if (arity == 0 && Cache.TryGetValue (name, out e) && mode != LookupMode.IgnoreAccessibility)
2380 var tp = CurrentTypeParameters;
2382 TypeParameter tparam = tp.Find (name);
2384 e = new TypeParameterExpr (tparam, Location.Null);
2389 TypeSpec t = LookupNestedTypeInHierarchy (name, arity);
2391 if (t != null && (t.IsAccessible (this) || mode == LookupMode.IgnoreAccessibility))
2392 e = new TypeExpression (t, Location.Null);
2394 e = Parent.LookupNamespaceOrType (name, arity, mode, loc);
2398 // TODO MemberCache: How to cache arity stuff ?
2399 if (arity == 0 && mode == LookupMode.Normal)
2405 TypeSpec LookupNestedTypeInHierarchy (string name, int arity)
2407 // Has any nested type
2408 // Does not work, because base type can have
2409 //if (PartialContainer.Types == null)
2412 var container = PartialContainer.CurrentType;
2413 return MemberCache.FindNestedType (container, name, arity);
2416 public void Mark_HasEquals ()
2418 cached_method |= CachedMethods.Equals;
2421 public void Mark_HasGetHashCode ()
2423 cached_method |= CachedMethods.GetHashCode;
2426 public override void WriteDebugSymbol (MonoSymbolFile file)
2431 foreach (var m in members) {
2432 m.WriteDebugSymbol (file);
2437 /// Method container contains Equals method
2439 public bool HasEquals {
2441 return (cached_method & CachedMethods.Equals) != 0;
2446 /// Method container contains GetHashCode method
2448 public bool HasGetHashCode {
2450 return (cached_method & CachedMethods.GetHashCode) != 0;
2454 public bool HasStaticFieldInitializer {
2456 return (cached_method & CachedMethods.HasStaticFieldInitializer) != 0;
2460 cached_method |= CachedMethods.HasStaticFieldInitializer;
2462 cached_method &= ~CachedMethods.HasStaticFieldInitializer;
2466 public override string DocCommentHeader {
2467 get { return "T:"; }
2471 public abstract class ClassOrStruct : TypeDefinition
2473 public const TypeAttributes StaticClassAttribute = TypeAttributes.Abstract | TypeAttributes.Sealed;
2475 SecurityType declarative_security;
2477 protected ClassOrStruct (TypeContainer parent, MemberName name, Attributes attrs, MemberKind kind)
2478 : base (parent, name, attrs, kind)
2482 protected override TypeAttributes TypeAttr {
2484 TypeAttributes ta = base.TypeAttr;
2485 if (!has_static_constructor)
2486 ta |= TypeAttributes.BeforeFieldInit;
2488 if (Kind == MemberKind.Class) {
2489 ta |= TypeAttributes.AutoLayout | TypeAttributes.Class;
2491 ta |= StaticClassAttribute;
2493 ta |= TypeAttributes.SequentialLayout;
2500 public override void AddNameToContainer (MemberCore symbol, string name)
2502 if (!(symbol is Constructor) && symbol.MemberName.Name == MemberName.Name) {
2503 if (symbol is TypeParameter) {
2504 Report.Error (694, symbol.Location,
2505 "Type parameter `{0}' has same name as containing type, or method",
2506 symbol.GetSignatureForError ());
2510 InterfaceMemberBase imb = symbol as InterfaceMemberBase;
2511 if (imb == null || !imb.IsExplicitImpl) {
2512 Report.SymbolRelatedToPreviousError (this);
2513 Report.Error (542, symbol.Location, "`{0}': member names cannot be the same as their enclosing type",
2514 symbol.GetSignatureForError ());
2519 base.AddNameToContainer (symbol, name);
2522 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
2524 if (a.IsValidSecurityAttribute ()) {
2525 a.ExtractSecurityPermissionSet (ctor, ref declarative_security);
2529 if (a.Type == pa.StructLayout) {
2530 PartialContainer.HasStructLayout = true;
2531 if (a.IsExplicitLayoutKind ())
2532 PartialContainer.HasExplicitLayout = true;
2535 if (a.Type == pa.Dynamic) {
2536 a.Error_MisusedDynamicAttribute ();
2540 base.ApplyAttributeBuilder (a, ctor, cdata, pa);
2544 /// Defines the default constructors
2546 protected virtual Constructor DefineDefaultConstructor (bool is_static)
2548 // The default instance constructor is public
2549 // If the class is abstract, the default constructor is protected
2550 // The default static constructor is private
2554 mods = Modifiers.STATIC | Modifiers.PRIVATE;
2556 mods = ((ModFlags & Modifiers.ABSTRACT) != 0) ? Modifiers.PROTECTED : Modifiers.PUBLIC;
2559 var c = new Constructor (this, MemberName.Name, mods, null, ParametersCompiled.EmptyReadOnlyParameters, Location);
2560 c.Initializer = new GeneratedBaseInitializer (Location);
2562 AddConstructor (c, true);
2563 c.Block = new ToplevelBlock (Compiler, ParametersCompiled.EmptyReadOnlyParameters, Location) {
2564 IsCompilerGenerated = true
2570 protected override bool DoDefineMembers ()
2572 CheckProtectedModifier ();
2574 base.DoDefineMembers ();
2579 public override void Emit ()
2581 if (!has_static_constructor && HasStaticFieldInitializer) {
2582 var c = DefineDefaultConstructor (true);
2588 if (declarative_security != null) {
2589 foreach (var de in declarative_security) {
2591 TypeBuilder.__AddDeclarativeSecurity (de);
2593 TypeBuilder.AddDeclarativeSecurity (de.Key, de.Value);
2601 public sealed class Class : ClassOrStruct
2603 const Modifiers AllowedModifiers =
2606 Modifiers.PROTECTED |
2607 Modifiers.INTERNAL |
2609 Modifiers.ABSTRACT |
2614 public Class (TypeContainer parent, MemberName name, Modifiers mod, Attributes attrs)
2615 : base (parent, name, attrs, MemberKind.Class)
2617 var accmods = IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE;
2618 this.ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, accmods, Location, Report);
2619 spec = new TypeSpec (Kind, null, this, null, ModFlags);
2622 public override void Accept (StructuralVisitor visitor)
2624 visitor.Visit (this);
2627 public override void SetBaseTypes (List<FullNamedExpression> baseTypes)
2629 var pmn = MemberName;
2630 if (pmn.Name == "Object" && !pmn.IsGeneric && Parent.MemberName.Name == "System" && Parent.MemberName.Left == null)
2631 Report.Error (537, Location,
2632 "The class System.Object cannot have a base class or implement an interface.");
2634 base.SetBaseTypes (baseTypes);
2637 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
2639 if (a.Type == pa.AttributeUsage) {
2640 if (!BaseType.IsAttribute && spec.BuiltinType != BuiltinTypeSpec.Type.Attribute) {
2641 Report.Error (641, a.Location, "Attribute `{0}' is only valid on classes derived from System.Attribute", a.GetSignatureForError ());
2645 if (a.Type == pa.Conditional && !BaseType.IsAttribute) {
2646 Report.Error (1689, a.Location, "Attribute `System.Diagnostics.ConditionalAttribute' is only valid on methods or attribute classes");
2650 if (a.Type == pa.ComImport && !attributes.Contains (pa.Guid)) {
2651 a.Error_MissingGuidAttribute ();
2655 if (a.Type == pa.Extension) {
2656 a.Error_MisusedExtensionAttribute ();
2660 if (a.Type.IsConditionallyExcluded (this))
2663 base.ApplyAttributeBuilder (a, ctor, cdata, pa);
2666 public override AttributeTargets AttributeTargets {
2668 return AttributeTargets.Class;
2672 protected override bool DoDefineMembers ()
2674 if ((ModFlags & Modifiers.ABSTRACT) == Modifiers.ABSTRACT && (ModFlags & (Modifiers.SEALED | Modifiers.STATIC)) != 0) {
2675 Report.Error (418, Location, "`{0}': an abstract class cannot be sealed or static", GetSignatureForError ());
2678 if ((ModFlags & (Modifiers.SEALED | Modifiers.STATIC)) == (Modifiers.SEALED | Modifiers.STATIC)) {
2679 Report.Error (441, Location, "`{0}': a class cannot be both static and sealed", GetSignatureForError ());
2683 foreach (var m in Members) {
2684 if (m is Operator) {
2685 Report.Error (715, m.Location, "`{0}': Static classes cannot contain user-defined operators", m.GetSignatureForError ());
2689 if (m is Destructor) {
2690 Report.Error (711, m.Location, "`{0}': Static classes cannot contain destructor", GetSignatureForError ());
2695 Report.Error (720, m.Location, "`{0}': cannot declare indexers in a static class", m.GetSignatureForError ());
2699 if ((m.ModFlags & Modifiers.STATIC) != 0 || m is TypeContainer)
2702 if (m is Constructor) {
2703 Report.Error (710, m.Location, "`{0}': Static classes cannot have instance constructors", GetSignatureForError ());
2707 Report.Error (708, m.Location, "`{0}': cannot declare instance members in a static class", m.GetSignatureForError ());
2710 if (!PartialContainer.HasInstanceConstructor)
2711 DefineDefaultConstructor (false);
2714 return base.DoDefineMembers ();
2717 public override void Emit ()
2721 if ((ModFlags & Modifiers.METHOD_EXTENSION) != 0)
2722 Module.PredefinedAttributes.Extension.EmitAttribute (TypeBuilder);
2724 if (base_type != null && base_type.HasDynamicElement) {
2725 Module.PredefinedAttributes.Dynamic.EmitAttribute (TypeBuilder, base_type, Location);
2729 protected override TypeSpec[] ResolveBaseTypes (out FullNamedExpression base_class)
2731 var ifaces = base.ResolveBaseTypes (out base_class);
2733 if (base_class == null) {
2734 if (spec.BuiltinType != BuiltinTypeSpec.Type.Object)
2735 base_type = Compiler.BuiltinTypes.Object;
2737 if (base_type.IsGenericParameter){
2738 Report.Error (689, base_class.Location, "`{0}': Cannot derive from type parameter `{1}'",
2739 GetSignatureForError (), base_type.GetSignatureForError ());
2740 } else if (base_type.IsStatic) {
2741 Report.SymbolRelatedToPreviousError (base_type);
2742 Report.Error (709, Location, "`{0}': Cannot derive from static class `{1}'",
2743 GetSignatureForError (), base_type.GetSignatureForError ());
2744 } else if (base_type.IsSealed) {
2745 Report.SymbolRelatedToPreviousError (base_type);
2746 Report.Error (509, Location, "`{0}': cannot derive from sealed type `{1}'",
2747 GetSignatureForError (), base_type.GetSignatureForError ());
2748 } else if (PartialContainer.IsStatic && base_type.BuiltinType != BuiltinTypeSpec.Type.Object) {
2749 Report.Error (713, Location, "Static class `{0}' cannot derive from type `{1}'. Static classes must derive from object",
2750 GetSignatureForError (), base_type.GetSignatureForError ());
2753 switch (base_type.BuiltinType) {
2754 case BuiltinTypeSpec.Type.Enum:
2755 case BuiltinTypeSpec.Type.ValueType:
2756 case BuiltinTypeSpec.Type.MulticastDelegate:
2757 case BuiltinTypeSpec.Type.Delegate:
2758 case BuiltinTypeSpec.Type.Array:
2759 if (!(spec is BuiltinTypeSpec)) {
2760 Report.Error (644, Location, "`{0}' cannot derive from special class `{1}'",
2761 GetSignatureForError (), base_type.GetSignatureForError ());
2763 base_type = Compiler.BuiltinTypes.Object;
2768 if (!IsAccessibleAs (base_type)) {
2769 Report.SymbolRelatedToPreviousError (base_type);
2770 Report.Error (60, Location, "Inconsistent accessibility: base class `{0}' is less accessible than class `{1}'",
2771 base_type.GetSignatureForError (), GetSignatureForError ());
2775 if (PartialContainer.IsStatic && ifaces != null) {
2776 foreach (var t in ifaces)
2777 Report.SymbolRelatedToPreviousError (t);
2778 Report.Error (714, Location, "Static class `{0}' cannot implement interfaces", GetSignatureForError ());
2784 /// Search for at least one defined condition in ConditionalAttribute of attribute class
2785 /// Valid only for attribute classes.
2786 public override string[] ConditionalConditions ()
2788 if ((caching_flags & (Flags.Excluded_Undetected | Flags.Excluded)) == 0)
2791 caching_flags &= ~Flags.Excluded_Undetected;
2793 if (OptAttributes == null)
2796 Attribute[] attrs = OptAttributes.SearchMulti (Module.PredefinedAttributes.Conditional);
2800 string[] conditions = new string[attrs.Length];
2801 for (int i = 0; i < conditions.Length; ++i)
2802 conditions[i] = attrs[i].GetConditionalAttributeValue ();
2804 caching_flags |= Flags.Excluded;
2809 public sealed class Struct : ClassOrStruct
2811 bool is_unmanaged, has_unmanaged_check_done;
2815 // Modifiers allowed in a struct declaration
2817 const Modifiers AllowedModifiers =
2820 Modifiers.PROTECTED |
2821 Modifiers.INTERNAL |
2825 public Struct (TypeContainer parent, MemberName name, Modifiers mod, Attributes attrs)
2826 : base (parent, name, attrs, MemberKind.Struct)
2828 var accmods = IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE;
2829 this.ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, accmods, Location, Report) | Modifiers.SEALED ;
2830 spec = new TypeSpec (Kind, null, this, null, ModFlags);
2833 public override AttributeTargets AttributeTargets {
2835 return AttributeTargets.Struct;
2839 public override void Accept (StructuralVisitor visitor)
2841 visitor.Visit (this);
2844 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
2846 base.ApplyAttributeBuilder (a, ctor, cdata, pa);
2849 // When struct constains fixed fixed and struct layout has explicitly
2850 // set CharSet, its value has to be propagated to compiler generated
2853 if (a.Type == pa.StructLayout) {
2854 var value = a.GetNamedValue ("CharSet");
2858 for (int i = 0; i < Members.Count; ++i) {
2859 FixedField ff = Members [i] as FixedField;
2863 ff.CharSet = (CharSet) System.Enum.Parse (typeof (CharSet), value.GetValue ().ToString ());
2868 bool CheckStructCycles ()
2874 foreach (var member in Members) {
2875 var field = member as Field;
2879 TypeSpec ftype = field.Spec.MemberType;
2880 if (!ftype.IsStruct)
2883 if (ftype is BuiltinTypeSpec)
2886 foreach (var targ in ftype.TypeArguments) {
2887 if (!CheckFieldTypeCycle (targ)) {
2888 Report.Error (523, field.Location,
2889 "Struct member `{0}' of type `{1}' causes a cycle in the struct layout",
2890 field.GetSignatureForError (), ftype.GetSignatureForError ());
2896 // Static fields of exactly same type are allowed
2898 if (field.IsStatic && ftype == CurrentType)
2901 if (!CheckFieldTypeCycle (ftype)) {
2902 Report.Error (523, field.Location,
2903 "Struct member `{0}' of type `{1}' causes a cycle in the struct layout",
2904 field.GetSignatureForError (), ftype.GetSignatureForError ());
2913 static bool CheckFieldTypeCycle (TypeSpec ts)
2915 var fts = ts.MemberDefinition as Struct;
2919 return fts.CheckStructCycles ();
2922 public override void Emit ()
2924 CheckStructCycles ();
2929 public override bool IsUnmanagedType ()
2931 if (has_unmanaged_check_done)
2932 return is_unmanaged;
2934 if (requires_delayed_unmanagedtype_check)
2937 var parent_def = Parent.PartialContainer;
2938 if (parent_def != null && parent_def.IsGenericOrParentIsGeneric) {
2939 has_unmanaged_check_done = true;
2943 if (first_nonstatic_field != null) {
2944 requires_delayed_unmanagedtype_check = true;
2946 foreach (var member in Members) {
2947 var f = member as Field;
2954 // It can happen when recursive unmanaged types are defined
2955 // struct S { S* s; }
2956 TypeSpec mt = f.MemberType;
2964 has_unmanaged_check_done = true;
2968 has_unmanaged_check_done = true;
2971 is_unmanaged = true;
2975 protected override TypeSpec[] ResolveBaseTypes (out FullNamedExpression base_class)
2977 var ifaces = base.ResolveBaseTypes (out base_class);
2978 base_type = Compiler.BuiltinTypes.ValueType;
2982 public override void RegisterFieldForInitialization (MemberCore field, FieldInitializer expression)
2984 if ((field.ModFlags & Modifiers.STATIC) == 0) {
2985 Report.Error (573, field.Location, "`{0}': Structs cannot have instance field initializers",
2986 field.GetSignatureForError ());
2989 base.RegisterFieldForInitialization (field, expression);
2997 public sealed class Interface : TypeDefinition {
3000 /// Modifiers allowed in a class declaration
3002 const Modifiers AllowedModifiers =
3005 Modifiers.PROTECTED |
3006 Modifiers.INTERNAL |
3010 public Interface (TypeContainer parent, MemberName name, Modifiers mod, Attributes attrs)
3011 : base (parent, name, attrs, MemberKind.Interface)
3013 var accmods = IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE;
3015 this.ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, accmods, name.Location, Report);
3016 spec = new TypeSpec (Kind, null, this, null, ModFlags);
3021 public override AttributeTargets AttributeTargets {
3023 return AttributeTargets.Interface;
3027 protected override TypeAttributes TypeAttr {
3029 const TypeAttributes DefaultTypeAttributes =
3030 TypeAttributes.AutoLayout |
3031 TypeAttributes.Abstract |
3032 TypeAttributes.Interface;
3034 return base.TypeAttr | DefaultTypeAttributes;
3040 public override void Accept (StructuralVisitor visitor)
3042 visitor.Visit (this);
3045 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
3047 if (a.Type == pa.ComImport && !attributes.Contains (pa.Guid)) {
3048 a.Error_MissingGuidAttribute ();
3052 base.ApplyAttributeBuilder (a, ctor, cdata, pa);
3055 protected override bool VerifyClsCompliance ()
3057 if (!base.VerifyClsCompliance ())
3060 if (iface_exprs != null) {
3061 foreach (var iface in iface_exprs) {
3062 if (iface.IsCLSCompliant ())
3065 Report.SymbolRelatedToPreviousError (iface);
3066 Report.Warning (3027, 1, Location, "`{0}' is not CLS-compliant because base interface `{1}' is not CLS-compliant",
3067 GetSignatureForError (), iface.GetSignatureForError ());
3075 public abstract class InterfaceMemberBase : MemberBase
3078 // Common modifiers allowed in a class declaration
3080 protected const Modifiers AllowedModifiersClass =
3083 Modifiers.PROTECTED |
3084 Modifiers.INTERNAL |
3089 Modifiers.OVERRIDE |
3090 Modifiers.ABSTRACT |
3095 // Common modifiers allowed in a struct declaration
3097 protected const Modifiers AllowedModifiersStruct =
3100 Modifiers.PROTECTED |
3101 Modifiers.INTERNAL |
3104 Modifiers.OVERRIDE |
3109 // Common modifiers allowed in a interface declaration
3111 protected const Modifiers AllowedModifiersInterface =
3116 // Whether this is an interface member.
3118 public bool IsInterface;
3121 // If true, this is an explicit interface implementation
3123 public readonly bool IsExplicitImpl;
3125 protected bool is_external_implementation;
3128 // The interface type we are explicitly implementing
3130 public TypeSpec InterfaceType;
3133 // The method we're overriding if this is an override method.
3135 protected MethodSpec base_method;
3137 readonly Modifiers explicit_mod_flags;
3138 public MethodAttributes flags;
3140 protected InterfaceMemberBase (TypeDefinition parent, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, MemberName name, Attributes attrs)
3141 : base (parent, type, mod, allowed_mod, Modifiers.PRIVATE, name, attrs)
3143 IsInterface = parent.Kind == MemberKind.Interface;
3144 IsExplicitImpl = (MemberName.ExplicitInterface != null);
3145 explicit_mod_flags = mod;
3148 public abstract Variance ExpectedMemberTypeVariance { get; }
3150 protected override bool CheckBase ()
3152 if (!base.CheckBase ())
3155 if ((caching_flags & Flags.MethodOverloadsExist) != 0)
3156 CheckForDuplications ();
3161 // For System.Object only
3162 if (Parent.BaseType == null)
3165 MemberSpec candidate;
3166 bool overrides = false;
3167 var base_member = FindBaseMember (out candidate, ref overrides);
3169 if ((ModFlags & Modifiers.OVERRIDE) != 0) {
3170 if (base_member == null) {
3171 if (candidate == null) {
3172 if (this is Method && ((Method)this).ParameterInfo.IsEmpty && MemberName.Name == Destructor.MetadataName && MemberName.Arity == 0) {
3173 Report.Error (249, Location, "Do not override `{0}'. Use destructor syntax instead",
3174 "object.Finalize()");
3176 Report.Error (115, Location, "`{0}' is marked as an override but no suitable {1} found to override",
3177 GetSignatureForError (), SimpleName.GetMemberType (this));
3180 Report.SymbolRelatedToPreviousError (candidate);
3182 Report.Error (72, Location, "`{0}': cannot override because `{1}' is not an event",
3183 GetSignatureForError (), TypeManager.GetFullNameSignature (candidate));
3184 else if (this is PropertyBase)
3185 Report.Error (544, Location, "`{0}': cannot override because `{1}' is not a property",
3186 GetSignatureForError (), TypeManager.GetFullNameSignature (candidate));
3188 Report.Error (505, Location, "`{0}': cannot override because `{1}' is not a method",
3189 GetSignatureForError (), TypeManager.GetFullNameSignature (candidate));
3196 // Handles ambiguous overrides
3198 if (candidate != null) {
3199 Report.SymbolRelatedToPreviousError (candidate);
3200 Report.SymbolRelatedToPreviousError (base_member);
3202 // Get member definition for error reporting
3203 var m1 = MemberCache.GetMember (base_member.DeclaringType.GetDefinition (), base_member);
3204 var m2 = MemberCache.GetMember (candidate.DeclaringType.GetDefinition (), candidate);
3206 Report.Error (462, Location,
3207 "`{0}' cannot override inherited members `{1}' and `{2}' because they have the same signature when used in type `{3}'",
3208 GetSignatureForError (), m1.GetSignatureForError (), m2.GetSignatureForError (), Parent.GetSignatureForError ());
3211 if (!CheckOverrideAgainstBase (base_member))
3214 ObsoleteAttribute oa = base_member.GetAttributeObsolete ();
3216 if (OptAttributes == null || !OptAttributes.Contains (Module.PredefinedAttributes.Obsolete)) {
3217 Report.SymbolRelatedToPreviousError (base_member);
3218 Report.Warning (672, 1, Location, "Member `{0}' overrides obsolete member `{1}'. Add the Obsolete attribute to `{0}'",
3219 GetSignatureForError (), base_member.GetSignatureForError ());
3222 if (OptAttributes != null && OptAttributes.Contains (Module.PredefinedAttributes.Obsolete)) {
3223 Report.SymbolRelatedToPreviousError (base_member);
3224 Report.Warning (809, 1, Location, "Obsolete member `{0}' overrides non-obsolete member `{1}'",
3225 GetSignatureForError (), base_member.GetSignatureForError ());
3229 base_method = base_member as MethodSpec;
3233 if (base_member == null && candidate != null && (!(candidate is IParametersMember) || !(this is IParametersMember)))
3234 base_member = candidate;
3236 if (base_member == null) {
3237 if ((ModFlags & Modifiers.NEW) != 0) {
3238 if (base_member == null) {
3239 Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required",
3240 GetSignatureForError ());
3244 if ((ModFlags & Modifiers.NEW) == 0) {
3245 ModFlags |= Modifiers.NEW;
3246 if (!IsCompilerGenerated) {
3247 Report.SymbolRelatedToPreviousError (base_member);
3248 if (!IsInterface && (base_member.Modifiers & (Modifiers.ABSTRACT | Modifiers.VIRTUAL | Modifiers.OVERRIDE)) != 0) {
3249 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",
3250 GetSignatureForError (), base_member.GetSignatureForError ());
3252 Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
3253 GetSignatureForError (), base_member.GetSignatureForError ());
3258 if (!IsInterface && base_member.IsAbstract && !overrides) {
3259 Report.SymbolRelatedToPreviousError (base_member);
3260 Report.Error (533, Location, "`{0}' hides inherited abstract member `{1}'",
3261 GetSignatureForError (), base_member.GetSignatureForError ());
3268 protected virtual bool CheckForDuplications ()
3270 return Parent.MemberCache.CheckExistingMembersOverloads (this, ParametersCompiled.EmptyReadOnlyParameters);
3274 // Performs various checks on the MethodInfo `mb' regarding the modifier flags
3275 // that have been defined.
3277 protected virtual bool CheckOverrideAgainstBase (MemberSpec base_member)
3281 if ((base_member.Modifiers & (Modifiers.ABSTRACT | Modifiers.VIRTUAL | Modifiers.OVERRIDE)) == 0) {
3282 Report.SymbolRelatedToPreviousError (base_member);
3283 Report.Error (506, Location,
3284 "`{0}': cannot override inherited member `{1}' because it is not marked virtual, abstract or override",
3285 GetSignatureForError (), TypeManager.CSharpSignature (base_member));
3289 // Now we check that the overriden method is not final
3290 if ((base_member.Modifiers & Modifiers.SEALED) != 0) {
3291 Report.SymbolRelatedToPreviousError (base_member);
3292 Report.Error (239, Location, "`{0}': cannot override inherited member `{1}' because it is sealed",
3293 GetSignatureForError (), TypeManager.CSharpSignature (base_member));
3297 var base_member_type = ((IInterfaceMemberSpec) base_member).MemberType;
3298 if (!TypeSpecComparer.Override.IsEqual (MemberType, base_member_type)) {
3299 Report.SymbolRelatedToPreviousError (base_member);
3300 if (this is PropertyBasedMember) {
3301 Report.Error (1715, Location, "`{0}': type must be `{1}' to match overridden member `{2}'",
3302 GetSignatureForError (), base_member_type.GetSignatureForError (), base_member.GetSignatureForError ());
3304 Report.Error (508, Location, "`{0}': return type must be `{1}' to match overridden member `{2}'",
3305 GetSignatureForError (), base_member_type.GetSignatureForError (), base_member.GetSignatureForError ());
3313 protected static bool CheckAccessModifiers (MemberCore this_member, MemberSpec base_member)
3315 var thisp = this_member.ModFlags & Modifiers.AccessibilityMask;
3316 var base_classp = base_member.Modifiers & Modifiers.AccessibilityMask;
3318 if ((base_classp & (Modifiers.PROTECTED | Modifiers.INTERNAL)) == (Modifiers.PROTECTED | Modifiers.INTERNAL)) {
3320 // It must be at least "protected"
3322 if ((thisp & Modifiers.PROTECTED) == 0) {
3327 // when overriding protected internal, the method can be declared
3328 // protected internal only within the same assembly or assembly
3329 // which has InternalsVisibleTo
3331 if ((thisp & Modifiers.INTERNAL) != 0) {
3332 return base_member.DeclaringType.MemberDefinition.IsInternalAsPublic (this_member.Module.DeclaringAssembly);
3336 // protected overriding protected internal inside same assembly
3337 // requires internal modifier as well
3339 if (base_member.DeclaringType.MemberDefinition.IsInternalAsPublic (this_member.Module.DeclaringAssembly)) {
3346 return thisp == base_classp;
3349 public override bool Define ()
3352 ModFlags = Modifiers.PUBLIC | Modifiers.ABSTRACT |
3353 Modifiers.VIRTUAL | (ModFlags & (Modifiers.UNSAFE | Modifiers.NEW));
3355 flags = MethodAttributes.Public |
3356 MethodAttributes.Abstract |
3357 MethodAttributes.HideBySig |
3358 MethodAttributes.NewSlot |
3359 MethodAttributes.Virtual;
3361 Parent.PartialContainer.MethodModifiersValid (this);
3363 flags = ModifiersExtensions.MethodAttr (ModFlags);
3366 if (IsExplicitImpl) {
3367 InterfaceType = MemberName.ExplicitInterface.ResolveAsType (Parent);
3368 if (InterfaceType == null)
3371 if ((ModFlags & Modifiers.PARTIAL) != 0) {
3372 Report.Error (754, Location, "A partial method `{0}' cannot explicitly implement an interface",
3373 GetSignatureForError ());
3376 if (!InterfaceType.IsInterface) {
3377 Report.SymbolRelatedToPreviousError (InterfaceType);
3378 Report.Error (538, Location, "The type `{0}' in explicit interface declaration is not an interface",
3379 InterfaceType.GetSignatureForError ());
3381 Parent.PartialContainer.VerifyImplements (this);
3384 Modifiers allowed_explicit = Modifiers.AllowedExplicitImplFlags;
3386 allowed_explicit |= Modifiers.ASYNC;
3388 ModifiersExtensions.Check (allowed_explicit, explicit_mod_flags, 0, Location, Report);
3391 return base.Define ();
3394 protected bool DefineParameters (ParametersCompiled parameters)
3396 if (!parameters.Resolve (this))
3400 for (int i = 0; i < parameters.Count; ++i) {
3401 Parameter p = parameters [i];
3403 if (p.HasDefaultValue && (IsExplicitImpl || this is Operator || (this is Indexer && parameters.Count == 1)))
3404 p.Warning_UselessOptionalParameter (Report);
3406 if (p.CheckAccessibility (this))
3409 TypeSpec t = parameters.Types [i];
3410 Report.SymbolRelatedToPreviousError (t);
3411 if (this is Indexer)
3412 Report.Error (55, Location,
3413 "Inconsistent accessibility: parameter type `{0}' is less accessible than indexer `{1}'",
3414 t.GetSignatureForError (), GetSignatureForError ());
3415 else if (this is Operator)
3416 Report.Error (57, Location,
3417 "Inconsistent accessibility: parameter type `{0}' is less accessible than operator `{1}'",
3418 t.GetSignatureForError (), GetSignatureForError ());
3420 Report.Error (51, Location,
3421 "Inconsistent accessibility: parameter type `{0}' is less accessible than method `{1}'",
3422 t.GetSignatureForError (), GetSignatureForError ());
3428 protected override void DoMemberTypeDependentChecks ()
3430 base.DoMemberTypeDependentChecks ();
3432 VarianceDecl.CheckTypeVariance (MemberType, ExpectedMemberTypeVariance, this);
3435 public override void Emit()
3437 // for extern static method must be specified either DllImport attribute or MethodImplAttribute.
3438 // We are more strict than csc and report this as an error because SRE does not allow emit that
3439 if ((ModFlags & Modifiers.EXTERN) != 0 && !is_external_implementation && (OptAttributes == null || !OptAttributes.HasResolveError ())) {
3440 if (this is Constructor) {
3441 Report.Warning (824, 1, Location,
3442 "Constructor `{0}' is marked `external' but has no external implementation specified", GetSignatureForError ());
3444 Report.Warning (626, 1, Location,
3445 "`{0}' is marked as an external but has no DllImport attribute. Consider adding a DllImport attribute to specify the external implementation",
3446 GetSignatureForError ());
3453 public override bool EnableOverloadChecks (MemberCore overload)
3456 // Two members can differ in their explicit interface
3457 // type parameter only
3459 InterfaceMemberBase imb = overload as InterfaceMemberBase;
3460 if (imb != null && imb.IsExplicitImpl) {
3461 if (IsExplicitImpl) {
3462 caching_flags |= Flags.MethodOverloadsExist;
3467 return IsExplicitImpl;
3470 protected void Error_CannotChangeAccessModifiers (MemberCore member, MemberSpec base_member)
3472 var base_modifiers = base_member.Modifiers;
3474 // Remove internal modifier from types which are not internally accessible
3475 if ((base_modifiers & Modifiers.AccessibilityMask) == (Modifiers.PROTECTED | Modifiers.INTERNAL) &&
3476 !base_member.DeclaringType.MemberDefinition.IsInternalAsPublic (member.Module.DeclaringAssembly))
3477 base_modifiers = Modifiers.PROTECTED;
3479 Report.SymbolRelatedToPreviousError (base_member);
3480 Report.Error (507, member.Location,
3481 "`{0}': cannot change access modifiers when overriding `{1}' inherited member `{2}'",
3482 member.GetSignatureForError (),
3483 ModifiersExtensions.AccessibilityName (base_modifiers),
3484 base_member.GetSignatureForError ());
3487 protected void Error_StaticReturnType ()
3489 Report.Error (722, Location,
3490 "`{0}': static types cannot be used as return types",
3491 MemberType.GetSignatureForError ());
3495 /// Gets base method and its return type
3497 protected virtual MemberSpec FindBaseMember (out MemberSpec bestCandidate, ref bool overrides)
3499 return MemberCache.FindBaseMember (this, out bestCandidate, ref overrides);
3503 // The "short" name of this property / indexer / event. This is the
3504 // name without the explicit interface.
3506 public string ShortName {
3507 get { return MemberName.Name; }
3511 // Returns full metadata method name
3513 public string GetFullName (MemberName name)
3515 return GetFullName (name.Name);
3518 public string GetFullName (string name)
3520 if (!IsExplicitImpl)
3524 // When dealing with explicit members a full interface type
3525 // name is added to member name to avoid possible name conflicts
3527 // We use CSharpName which gets us full name with benefit of
3528 // replacing predefined names which saves some space and name
3531 return InterfaceType.GetSignatureForError () + "." + name;
3534 public override string GetSignatureForDocumentation ()
3537 return Parent.GetSignatureForDocumentation () + "." + InterfaceType.GetExplicitNameSignatureForDocumentation () + "#" + ShortName;
3539 return Parent.GetSignatureForDocumentation () + "." + ShortName;
3542 public override bool IsUsed
3544 get { return IsExplicitImpl || base.IsUsed; }
3547 public override void SetConstraints (List<Constraints> constraints_list)
3549 if (((ModFlags & Modifiers.OVERRIDE) != 0 || IsExplicitImpl)) {
3550 Report.Error (460, Location,
3551 "`{0}': Cannot specify constraints for overrides and explicit interface implementation methods",
3552 GetSignatureForError ());
3555 base.SetConstraints (constraints_list);
3559 public abstract class MemberBase : MemberCore
3561 protected FullNamedExpression type_expr;
3562 protected TypeSpec member_type;
3563 public new TypeDefinition Parent;
3565 protected MemberBase (TypeDefinition parent, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, Modifiers def_mod, MemberName name, Attributes attrs)
3566 : base (parent, name, attrs)
3568 this.Parent = parent;
3569 this.type_expr = type;
3571 if (name != MemberName.Null)
3572 ModFlags = ModifiersExtensions.Check (allowed_mod, mod, def_mod, Location, Report);
3577 public TypeSpec MemberType {
3583 public FullNamedExpression TypeExpression {
3592 // Main member define entry
3594 public override bool Define ()
3596 DoMemberTypeIndependentChecks ();
3599 // Returns false only when type resolution failed
3601 if (!ResolveMemberType ())
3604 DoMemberTypeDependentChecks ();
3609 // Any type_name independent checks
3611 protected virtual void DoMemberTypeIndependentChecks ()
3613 if ((Parent.ModFlags & Modifiers.SEALED) != 0 &&
3614 (ModFlags & (Modifiers.VIRTUAL | Modifiers.ABSTRACT)) != 0) {
3615 Report.Error (549, Location, "New virtual member `{0}' is declared in a sealed class `{1}'",
3616 GetSignatureForError (), Parent.GetSignatureForError ());
3621 // Any type_name dependent checks
3623 protected virtual void DoMemberTypeDependentChecks ()
3625 // verify accessibility
3626 if (!IsAccessibleAs (MemberType)) {
3627 Report.SymbolRelatedToPreviousError (MemberType);
3628 if (this is Property)
3629 Report.Error (53, Location,
3630 "Inconsistent accessibility: property type `" +
3631 MemberType.GetSignatureForError () + "' is less " +
3632 "accessible than property `" + GetSignatureForError () + "'");
3633 else if (this is Indexer)
3634 Report.Error (54, Location,
3635 "Inconsistent accessibility: indexer return type `" +
3636 MemberType.GetSignatureForError () + "' is less " +
3637 "accessible than indexer `" + GetSignatureForError () + "'");
3638 else if (this is MethodCore) {
3639 if (this is Operator)
3640 Report.Error (56, Location,
3641 "Inconsistent accessibility: return type `" +
3642 MemberType.GetSignatureForError () + "' is less " +
3643 "accessible than operator `" + GetSignatureForError () + "'");
3645 Report.Error (50, Location,
3646 "Inconsistent accessibility: return type `" +
3647 MemberType.GetSignatureForError () + "' is less " +
3648 "accessible than method `" + GetSignatureForError () + "'");
3650 Report.Error (52, Location,
3651 "Inconsistent accessibility: field type `" +
3652 MemberType.GetSignatureForError () + "' is less " +
3653 "accessible than field `" + GetSignatureForError () + "'");
3658 protected void IsTypePermitted ()
3660 if (MemberType.IsSpecialRuntimeType) {
3661 if (Parent is StateMachine) {
3662 Report.Error (4012, Location,
3663 "Parameters or local variables of type `{0}' cannot be declared in async methods or iterators",
3664 MemberType.GetSignatureForError ());
3665 } else if (Parent is HoistedStoreyClass) {
3666 Report.Error (4013, Location,
3667 "Local variables of type `{0}' cannot be used inside anonymous methods, lambda expressions or query expressions",
3668 MemberType.GetSignatureForError ());
3670 Report.Error (610, Location,
3671 "Field or property cannot be of type `{0}'", MemberType.GetSignatureForError ());
3676 protected virtual bool CheckBase ()
3678 CheckProtectedModifier ();
3683 public override string GetSignatureForDocumentation ()
3685 return Parent.GetSignatureForDocumentation () + "." + MemberName.Basename;
3688 protected virtual bool ResolveMemberType ()
3690 if (member_type != null)
3691 throw new InternalErrorException ("Multi-resolve");
3693 member_type = type_expr.ResolveAsType (this);
3694 return member_type != null;