X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Ffield.cs;h=49dbb3d400d0bd43e587908e41c6ff097a4431bd;hb=656b38c2e15860ed8d9e16809579989ebd69b9fa;hp=b20153fcafea522b1cd7cf860efa6ea806206518;hpb=26c760304aae98bfe829d3188e7cefc9047f47f7;p=mono.git diff --git a/mcs/mcs/field.cs b/mcs/mcs/field.cs index b20153fcafe..49dbb3d400d 100644 --- a/mcs/mcs/field.cs +++ b/mcs/mcs/field.cs @@ -19,15 +19,32 @@ using System.Runtime.InteropServices; namespace Mono.CSharp { + public class FieldDeclarator + { + public FieldDeclarator (SimpleMemberName name, Expression initializer) + { + this.Name = name; + this.Initializer = initializer; + } + + #region Properties + + public SimpleMemberName Name { get; private set; } + public Expression Initializer { get; private set; } + + #endregion + } + // // Abstract class for all fields // abstract public class FieldBase : MemberBase { - public FieldBuilder FieldBuilder; + protected FieldBuilder FieldBuilder; protected FieldSpec spec; public Status status; protected Expression initializer; + protected List declarators; [Flags] public enum Status : byte { @@ -45,13 +62,49 @@ namespace Mono.CSharp Report.Error (681, Location, "The modifier 'abstract' is not valid on fields. Try using a property instead"); } + #region Properties + public override AttributeTargets AttributeTargets { get { return AttributeTargets.Field; } } - public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa) + public Expression Initializer { + get { + return initializer; + } + set { + this.initializer = value; + } + } + + public FieldSpec Spec { + get { + return spec; + } + } + + public override string[] ValidAttributeTargets { + get { + return attribute_targets; + } + } + + #endregion + + public void AddDeclarator (FieldDeclarator declarator) + { + if (declarators == null) + declarators = new List (2); + + declarators.Add (declarator); + + // TODO: This will probably break + Parent.AddMember (this, declarator.Name.Value); + } + + public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa) { if (a.Type == pa.FieldOffset) { status |= Status.HAS_OFFSET; @@ -91,26 +144,36 @@ namespace Mono.CSharp return; } - FieldBuilder.SetCustomAttribute (cb); + FieldBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata); } protected override bool CheckBase () { if (!base.CheckBase ()) return false; - - MemberInfo conflict_symbol = Parent.PartialContainer.FindBaseMemberWithSameName (Name, false); + + MemberSpec candidate; + var conflict_symbol = MemberCache.FindBaseMember (this, out candidate); + if (conflict_symbol == null) + conflict_symbol = candidate; + if (conflict_symbol == null) { if ((ModFlags & Modifiers.NEW) != 0) { - Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ()); + Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", + GetSignatureForError ()); } - return true; - } - - if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE | Modifiers.BACKING_FIELD)) == 0) { - Report.SymbolRelatedToPreviousError (conflict_symbol); - Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended", - GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol)); + } else { + if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE | Modifiers.BACKING_FIELD)) == 0) { + Report.SymbolRelatedToPreviousError (conflict_symbol); + Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended", + GetSignatureForError (), conflict_symbol.GetSignatureForError ()); + } + + if (conflict_symbol.IsAbstract) { + Report.SymbolRelatedToPreviousError (conflict_symbol); + Report.Error (533, Location, "`{0}' hides inherited abstract member `{1}'", + GetSignatureForError (), conflict_symbol.GetSignatureForError ()); + } } return true; @@ -125,12 +188,11 @@ namespace Mono.CSharp { base.DoMemberTypeDependentChecks (); - if (TypeManager.IsGenericParameter (MemberType)) + if (MemberType.IsGenericParameter) return; - if (MemberType.IsSealed && MemberType.IsAbstract) { + if (MemberType.IsStatic) Error_VariableOfStaticClass (Location, GetSignatureForError (), MemberType, Report); - } CheckBase (); IsTypePermitted (); @@ -145,20 +207,14 @@ namespace Mono.CSharp public override void Emit () { - if (TypeManager.IsDynamicType (member_type)) { - PredefinedAttributes.Get.Dynamic.EmitAttribute (FieldBuilder); - } else { - var trans_flags = TypeManager.HasDynamicTypeUsed (member_type); - if (trans_flags != null) { - var pa = PredefinedAttributes.Get.DynamicTransform; - if (pa.Constructor != null || pa.ResolveConstructor (Location, TypeManager.bool_type.MakeArrayType ())) { - FieldBuilder.SetCustomAttribute (new CustomAttributeBuilder (pa.Constructor, new object[] { trans_flags })); - } - } + if (member_type == InternalType.Dynamic) { + Compiler.PredefinedAttributes.Dynamic.EmitAttribute (FieldBuilder); + } else if (member_type.HasDynamicElement) { + Compiler.PredefinedAttributes.Dynamic.EmitAttribute (FieldBuilder, member_type); } if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0 && !Parent.IsCompilerGenerated) - PredefinedAttributes.Get.CompilerGenerated.EmitAttribute (FieldBuilder); + Compiler.PredefinedAttributes.CompilerGenerated.EmitAttribute (FieldBuilder); if (OptAttributes != null) { OptAttributes.Emit (); @@ -171,100 +227,102 @@ namespace Mono.CSharp base.Emit (); } - public static void Error_VariableOfStaticClass (Location loc, string variable_name, Type static_class, Report Report) + public static void Error_VariableOfStaticClass (Location loc, string variable_name, TypeSpec static_class, Report Report) { Report.SymbolRelatedToPreviousError (static_class); Report.Error (723, loc, "`{0}': cannot declare variables of static types", variable_name); } - public Expression Initializer { - get { - return initializer; - } - set { - if (value != null) { - this.initializer = value; - } - } - } - - protected virtual bool IsFieldClsCompliant { - get { - if (FieldBuilder == null) - return true; - - return AttributeTester.IsClsCompliant (FieldBuilder.FieldType); - } - } - - public FieldSpec Spec { - get { return spec; } - } - - public override string[] ValidAttributeTargets - { - get { - return attribute_targets; - } - } - protected override bool VerifyClsCompliance () { if (!base.VerifyClsCompliance ()) return false; - if (!IsFieldClsCompliant) { + if (!MemberType.IsCLSCompliant () || this is FixedField) { Report.Warning (3003, 1, Location, "Type of `{0}' is not CLS-compliant", GetSignatureForError ()); } return true; } - - public void SetAssigned () - { - caching_flags |= Flags.IsAssigned; - } } // // Field specification // - public class FieldSpec : MemberSpec + public class FieldSpec : MemberSpec, IInterfaceMemberSpec { - FieldInfo info; + FieldInfo metaInfo; + TypeSpec memberType; - public FieldSpec (IMemberDetails details, FieldInfo info, Modifiers modifiers) - : base (details, info.Name, modifiers) + public FieldSpec (TypeSpec declaringType, IMemberDefinition definition, TypeSpec memberType, FieldInfo info, Modifiers modifiers) + : base (MemberKind.Field, declaringType, definition, modifiers) { - this.info = info; + this.metaInfo = info; + this.memberType = memberType; } - public bool IsReadOnly { - get { return (modifiers & Modifiers.READONLY) != 0; } - } +#region Properties - public FieldInfo MetaInfo { + public bool IsReadOnly { get { - return info; - } - set { - info = value; + return (Modifiers & Modifiers.READONLY) != 0; } } - // Obsolete - public Type DeclaringType { + public TypeSpec MemberType { get { - return MetaInfo.DeclaringType; + return memberType; } } - // Obsolete - public Type FieldType { - get { - return MetaInfo.FieldType; +#endregion + + public FieldInfo GetMetaInfo () + { + if ((state & StateFlags.PendingMetaInflate) != 0) { + var decl_meta = DeclaringType.GetMetaInfo (); + if (DeclaringType.IsTypeBuilder) { + metaInfo = TypeBuilder.GetField (decl_meta, metaInfo); + } else { + var orig_token = metaInfo.MetadataToken; + metaInfo = decl_meta.GetField (Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static); + if (metaInfo.MetadataToken != orig_token) + throw new NotImplementedException ("Resolved to wrong meta token"); + + // What a stupid API, does not work because field handle is imported + // metaInfo = FieldInfo.GetFieldFromHandle (metaInfo.FieldHandle, DeclaringType.MetaInfo.TypeHandle); + } + + state &= ~StateFlags.PendingMetaInflate; } + + return metaInfo; + } + + public override MemberSpec InflateMember (TypeParameterInflator inflator) + { + var fs = (FieldSpec) base.InflateMember (inflator); + fs.memberType = inflator.Inflate (memberType); + return fs; + } + + public FieldSpec Mutate (TypeParameterMutator mutator) + { + var decl = DeclaringType; + if (DeclaringType.IsGenericOrParentIsGeneric) + decl = mutator.Mutate (decl); + + if (decl == DeclaringType) + return this; + + var fs = (FieldSpec) MemberwiseClone (); + fs.declaringType = decl; + fs.state |= StateFlags.PendingMetaInflate; + + // Gets back FieldInfo in case of metaInfo was inflated + fs.metaInfo = MemberCache.GetMember (TypeParameterMutator.GetMemberDeclaringType (DeclaringType), this).metaInfo; + return fs; } } @@ -288,14 +346,9 @@ namespace Mono.CSharp Modifiers.PRIVATE | Modifiers.UNSAFE; - public FixedField (DeclSpace parent, FullNamedExpression type, Modifiers mod, string name, - Expression size_expr, Attributes attrs, Location loc): - base (parent, type, mod, AllowedModifiers, new MemberName (name, loc), attrs) + public FixedField (DeclSpace parent, FullNamedExpression type, Modifiers mod, MemberName name, Attributes attrs) + : base (parent, type, mod, AllowedModifiers, name, attrs) { - if (RootContext.Version < LanguageVersion.ISO_2) - Report.FeatureIsNotAvailable (loc, "fixed size buffers"); - - initializer = new ConstInitializer (this, size_expr); } public override Constant ConvertInitializer (ResolveContext rc, Constant expr) @@ -312,22 +365,30 @@ namespace Mono.CSharp Report.Error (1663, Location, "`{0}': Fixed size buffers type must be one of the following: bool, byte, short, int, long, char, sbyte, ushort, uint, ulong, float or double", GetSignatureForError ()); - } + } else if (declarators != null) { + var t = new TypeExpression (MemberType, TypeExpression.Location); + int index = Parent.PartialContainer.Fields.IndexOf (this); + foreach (var d in declarators) { + var f = new FixedField (Parent, t, ModFlags, new MemberName (d.Name.Value, d.Name.Location), OptAttributes); + f.initializer = d.Initializer; + ((ConstInitializer) f.initializer).Name = d.Name.Value; + Parent.PartialContainer.Fields.Insert (++index, f); + } + } // Create nested fixed buffer container string name = String.Format ("<{0}>__FixedBuffer{1}", Name, GlobalCounter++); fixed_buffer_type = Parent.TypeBuilder.DefineNestedType (name, Parent.Module.DefaultCharSetType | - TypeAttributes.NestedPublic | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit, TypeManager.value_type); - - var element = fixed_buffer_type.DefineField (FixedElementName, MemberType, FieldAttributes.Public); + TypeAttributes.NestedPublic | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit, TypeManager.value_type.GetMetaInfo ()); + + fixed_buffer_type.DefineField (FixedElementName, MemberType.GetMetaInfo (), FieldAttributes.Public); RootContext.RegisterCompilerGeneratedType (fixed_buffer_type); FieldBuilder = Parent.TypeBuilder.DefineField (Name, fixed_buffer_type, ModifiersExtensions.FieldAttr (ModFlags)); - spec = new FixedFieldSpec (this, FieldBuilder, element, ModFlags); - - Parent.MemberCache.AddMember (FieldBuilder, this); - TypeManager.RegisterFieldBase (FieldBuilder, this); + var element_spec = new FieldSpec (null, this, MemberType, FieldBuilder, ModFlags); + spec = new FixedFieldSpec (Parent.Definition, this, FieldBuilder, element_spec, ModFlags); + Parent.MemberCache.AddMember (spec); return true; } @@ -338,7 +399,7 @@ namespace Mono.CSharp if (!IsUnsafe) Expression.UnsafeError (Report, Location); - if (Parent.PartialContainer.Kind != Kind.Struct) { + if (Parent.PartialContainer.Kind != MemberKind.Struct) { Report.Error (1642, Location, "`{0}': Fixed size buffer fields may only be members of structs", GetSignatureForError ()); } @@ -369,7 +430,7 @@ namespace Mono.CSharp buffer_size *= type_size; EmitFieldSize (buffer_size); - PredefinedAttributes.Get.UnsafeValueType.EmitAttribute (fixed_buffer_type); + Compiler.PredefinedAttributes.UnsafeValueType.EmitAttribute (fixed_buffer_type); base.Emit (); } @@ -379,14 +440,16 @@ namespace Mono.CSharp CustomAttributeBuilder cab; PredefinedAttribute pa; - pa = PredefinedAttributes.Get.StructLayout; + pa = Compiler.PredefinedAttributes.StructLayout; if (pa.Constructor == null && !pa.ResolveConstructor (Location, TypeManager.short_type)) return; // TODO: It's not cleared - if (fi == null) - fi = new FieldInfo[] { pa.Type.GetField ("Size") }; + if (fi == null) { + var field = (FieldSpec) MemberCache.FindMember (pa.Type, MemberFilter.Field ("Size", null), BindingRestriction.DeclaredOnly); + fi = new FieldInfo[] { field.GetMetaInfo () }; + } object[] fi_val = new object[] { buffer_size }; cab = new CustomAttributeBuilder (pa.Constructor, @@ -399,21 +462,15 @@ namespace Mono.CSharp if ((ModFlags & Modifiers.PRIVATE) != 0) return; - pa = PredefinedAttributes.Get.FixedBuffer; + pa = Compiler.PredefinedAttributes.FixedBuffer; if (pa.Constructor == null && !pa.ResolveConstructor (Location, TypeManager.type_type, TypeManager.int32_type)) return; - cab = new CustomAttributeBuilder (pa.Constructor, new object[] { MemberType, buffer_size }); + cab = new CustomAttributeBuilder (pa.Constructor, new object[] { MemberType.GetMetaInfo (), buffer_size }); FieldBuilder.SetCustomAttribute (cab); } - protected override bool IsFieldClsCompliant { - get { - return false; - } - } - public void SetCharSet (TypeAttributes ta) { TypeAttributes cta = fixed_buffer_type.Attributes; @@ -438,23 +495,26 @@ namespace Mono.CSharp class FixedFieldSpec : FieldSpec { - readonly FieldInfo element; + readonly FieldSpec element; - public FixedFieldSpec (IMemberDetails details, FieldInfo info, FieldInfo element, Modifiers modifiers) - : base (details, info, modifiers) + public FixedFieldSpec (TypeSpec declaringType, IMemberDefinition definition, FieldInfo info, FieldSpec element, Modifiers modifiers) + : base (declaringType, definition, element.MemberType, info, modifiers) { this.element = element; + + // It's never CLS-Compliant + state &= ~StateFlags.CLSCompliant_Undetected; } - public FieldInfo Element { + public FieldSpec Element { get { return element; } } - public Type ElementType { + public TypeSpec ElementType { get { - return element.FieldType; + return MemberType; } } } @@ -496,36 +556,9 @@ namespace Mono.CSharp MemberType == TypeManager.intptr_type || MemberType == TypeManager.uintptr_type) return true; - if (TypeManager.IsEnumType (MemberType)) - return true; - - return false; - } - - bool CheckStructLayout (Type type, bool isStatic) - { - if (TypeManager.IsBuiltinType (type)) + if (MemberType.IsEnum) return true; - if (isStatic) { - if (!TypeManager.IsValueType (type) || TypeManager.IsEqual (type, Parent.TypeBuilder)) - return true; - } - - if (!TypeManager.IsEqual (TypeManager.DropGenericTypeArguments (type), Parent.TypeBuilder)) { - if (!TypeManager.IsGenericType (type)) - return true; - - foreach (Type t in TypeManager.GetTypeArguments (type)) { - if (!CheckStructLayout (t, false)) - return false; - } - return true; - } - - Report.Error (523, Location, - "Struct member `{0}' of type `{1}' causes a cycle in the struct layout", - GetSignatureForError (), TypeManager.CSharpName (MemberType)); return false; } @@ -534,40 +567,41 @@ namespace Mono.CSharp if (!base.Define ()) return false; - try { - Type[] required_modifier = null; - if ((ModFlags & Modifiers.VOLATILE) != 0) { - if (TypeManager.isvolatile_type == null) - TypeManager.isvolatile_type = TypeManager.CoreLookupType (Compiler, - "System.Runtime.CompilerServices", "IsVolatile", Kind.Class, true); - - if (TypeManager.isvolatile_type != null) - required_modifier = new Type [] { TypeManager.isvolatile_type }; - } + Type[] required_modifier = null; + if ((ModFlags & Modifiers.VOLATILE) != 0) { + if (TypeManager.isvolatile_type == null) + TypeManager.isvolatile_type = TypeManager.CoreLookupType (Compiler, + "System.Runtime.CompilerServices", "IsVolatile", MemberKind.Class, true); - FieldBuilder = Parent.TypeBuilder.DefineField ( - Name, MemberType, required_modifier, null, ModifiersExtensions.FieldAttr (ModFlags)); + if (TypeManager.isvolatile_type != null) + required_modifier = new Type[] { TypeManager.isvolatile_type.GetMetaInfo () }; + } - spec = new FieldSpec (this, FieldBuilder, ModFlags); + FieldBuilder = Parent.TypeBuilder.DefineField ( + Name, member_type.GetMetaInfo (), required_modifier, null, ModifiersExtensions.FieldAttr (ModFlags)); - // Don't cache inaccessible fields - if ((ModFlags & Modifiers.BACKING_FIELD) == 0) { - Parent.MemberCache.AddMember (FieldBuilder, this); - } + spec = new FieldSpec (Parent.Definition, this, MemberType, FieldBuilder, ModFlags); - TypeManager.RegisterFieldBase (FieldBuilder, this); - } - catch (ArgumentException) { - Report.RuntimeMissingSupport (Location, "`void' or `void*' field type"); - return false; + // Don't cache inaccessible fields + if ((ModFlags & Modifiers.BACKING_FIELD) == 0) { + Parent.MemberCache.AddMember (spec); } if (initializer != null) { ((TypeContainer) Parent).RegisterFieldForInitialization (this, - new FieldInitializer (this, initializer, this)); - } else { - if (Parent.PartialContainer.Kind == Kind.Struct) - CheckStructLayout (member_type, (ModFlags & Modifiers.STATIC) != 0); + new FieldInitializer (spec, initializer, this)); + } + + if (declarators != null) { + var t = new TypeExpression (MemberType, TypeExpression.Location); + int index = Parent.PartialContainer.Fields.IndexOf (this); + foreach (var d in declarators) { + var f = new Field (Parent, t, ModFlags, new MemberName (d.Name.Value, d.Name.Location), OptAttributes); + if (d.Initializer != null) + f.initializer = d.Initializer; + + Parent.PartialContainer.Fields.Insert (++index, f); + } } return true; @@ -575,6 +609,9 @@ namespace Mono.CSharp protected override void DoMemberTypeDependentChecks () { + if ((ModFlags & Modifiers.BACKING_FIELD) != 0) + return; + base.DoMemberTypeDependentChecks (); if ((ModFlags & Modifiers.VOLATILE) != 0) {