X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Ffield.cs;h=f5603b4fae4ebecd7daa335c60ed08f4bf131d4f;hb=a4a84a1325565b912b1fe4d19d40cfd0affa1a3a;hp=641fe206327642d537f3cdff2d51d631c1e04b7c;hpb=fbbbdf8ef1638db72e8956ca5039e28b2d337d9c;p=mono.git diff --git a/mcs/mcs/field.cs b/mcs/mcs/field.cs index 641fe206327..f5603b4fae4 100644 --- a/mcs/mcs/field.cs +++ b/mcs/mcs/field.cs @@ -9,6 +9,7 @@ // // Copyright 2001, 2002, 2003 Ximian, Inc (http://www.ximian.com) // Copyright 2004-2008 Novell, Inc +// Copyright 2011 Xamarin Inc // using System; @@ -41,6 +42,11 @@ namespace Mono.CSharp public Expression Initializer { get; private set; } #endregion + + public virtual FullNamedExpression GetFieldTypeExpression (FieldBase field) + { + return new TypeExpression (field.MemberType, Name.Location); + } } // @@ -61,10 +67,8 @@ namespace Mono.CSharp static readonly string[] attribute_targets = new string [] { "field" }; - protected FieldBase (DeclSpace parent, FullNamedExpression type, Modifiers mod, - Modifiers allowed_mod, MemberName name, Attributes attrs) - : base (parent, null, type, mod, allowed_mod | Modifiers.ABSTRACT, Modifiers.PRIVATE, - name, attrs) + protected FieldBase (TypeDefinition parent, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, MemberName name, Attributes attrs) + : base (parent, type, mod, allowed_mod | Modifiers.ABSTRACT, Modifiers.PRIVATE, name, attrs) { if ((mod & Modifiers.ABSTRACT) != 0) Report.Error (681, Location, "The modifier 'abstract' is not valid on fields. Try using a property instead"); @@ -78,6 +82,12 @@ namespace Mono.CSharp } } + public List Declarators { + get { + return this.declarators; + } + } + public Expression Initializer { get { return initializer; @@ -87,6 +97,12 @@ namespace Mono.CSharp } } + public string Name { + get { + return MemberName.Name; + } + } + public FieldSpec Spec { get { return spec; @@ -108,8 +124,7 @@ namespace Mono.CSharp declarators.Add (declarator); - // TODO: This will probably break - Parent.AddMember (this, declarator.Name.Value); + Parent.AddNameToContainer (this, declarator.Name.Value); } public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa) @@ -166,7 +181,8 @@ namespace Mono.CSharp return false; MemberSpec candidate; - var conflict_symbol = MemberCache.FindBaseMember (this, out candidate); + bool overrides = false; + var conflict_symbol = MemberCache.FindBaseMember (this, out candidate, ref overrides); if (conflict_symbol == null) conflict_symbol = candidate; @@ -194,7 +210,7 @@ namespace Mono.CSharp public virtual Constant ConvertInitializer (ResolveContext rc, Constant expr) { - return expr.ConvertImplicitly (rc, MemberType); + return expr.ConvertImplicitly (MemberType); } protected override void DoMemberTypeDependentChecks () @@ -220,14 +236,16 @@ namespace Mono.CSharp public override void Emit () { - if (member_type == InternalType.Dynamic) { + if (member_type.BuiltinType == BuiltinTypeSpec.Type.Dynamic) { Module.PredefinedAttributes.Dynamic.EmitAttribute (FieldBuilder); - } else if (!(Parent is CompilerGeneratedClass) && member_type.HasDynamicElement) { + } else if (!Parent.IsCompilerGenerated && member_type.HasDynamicElement) { Module.PredefinedAttributes.Dynamic.EmitAttribute (FieldBuilder, member_type, Location); } if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0 && !Parent.IsCompilerGenerated) Module.PredefinedAttributes.CompilerGenerated.EmitAttribute (FieldBuilder); + if ((ModFlags & Modifiers.DEBUGGER_HIDDEN) != 0) + Module.PredefinedAttributes.DebuggerBrowsable.EmitAttribute (FieldBuilder, System.Diagnostics.DebuggerBrowsableState.Never); if (OptAttributes != null) { OptAttributes.Emit (); @@ -237,6 +255,8 @@ namespace Mono.CSharp Report.Error (625, Location, "`{0}': Instance field types marked with StructLayout(LayoutKind.Explicit) must have a FieldOffset attribute", GetSignatureForError ()); } + ConstraintChecker.Check (this, member_type, type_expr.Location); + base.Emit (); } @@ -338,9 +358,9 @@ namespace Mono.CSharp return fs; } - public override List ResolveMissingDependencies () + public override List ResolveMissingDependencies (MemberSpec caller) { - return memberType.ResolveMissingDependencies (); + return memberType.ResolveMissingDependencies (this); } } @@ -362,7 +382,7 @@ namespace Mono.CSharp Modifiers.PRIVATE | Modifiers.UNSAFE; - public FixedField (DeclSpace parent, FullNamedExpression type, Modifiers mod, MemberName name, Attributes attrs) + public FixedField (TypeDefinition parent, FullNamedExpression type, Modifiers mod, MemberName name, Attributes attrs) : base (parent, type, mod, AllowedModifiers, name, attrs) { } @@ -380,7 +400,7 @@ namespace Mono.CSharp public override Constant ConvertInitializer (ResolveContext rc, Constant expr) { - return expr.ImplicitConversionRequired (rc, TypeManager.int32_type, Location); + return expr.ImplicitConversionRequired (rc, rc.BuiltinTypes.Int, Location); } public override bool Define () @@ -388,31 +408,32 @@ namespace Mono.CSharp if (!base.Define ()) return false; - if (!TypeManager.IsPrimitiveType (MemberType)) { + if (!BuiltinTypeSpec.IsPrimitiveType (MemberType)) { 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); + var f = new FixedField (Parent, d.GetFieldTypeExpression (this), 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); + f.Define (); + Parent.PartialContainer.Members.Add (f); } } // Create nested fixed buffer container string name = String.Format ("<{0}>__FixedBuffer{1}", Name, GlobalCounter++); fixed_buffer_type = Parent.TypeBuilder.DefineNestedType (name, - TypeAttributes.NestedPublic | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit, TypeManager.value_type.GetMetaInfo ()); + TypeAttributes.NestedPublic | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit, + Compiler.BuiltinTypes.ValueType.GetMetaInfo ()); - fixed_buffer_type.DefineField (FixedElementName, MemberType.GetMetaInfo (), FieldAttributes.Public); + var ffield = fixed_buffer_type.DefineField (FixedElementName, MemberType.GetMetaInfo (), FieldAttributes.Public); FieldBuilder = Parent.TypeBuilder.DefineField (Name, fixed_buffer_type, ModifiersExtensions.FieldAttr (ModFlags)); - var element_spec = new FieldSpec (null, this, MemberType, FieldBuilder, ModFlags); - spec = new FixedFieldSpec (Parent.Definition, this, FieldBuilder, element_spec, ModFlags); + + var element_spec = new FieldSpec (null, this, MemberType, ffield, ModFlags); + spec = new FixedFieldSpec (Module, Parent.Definition, this, FieldBuilder, element_spec, ModFlags); Parent.MemberCache.AddMember (spec); return true; @@ -445,14 +466,6 @@ namespace Mono.CSharp return; } - int type_size = Expression.GetTypeSize (MemberType); - - if (buffer_size > int.MaxValue / type_size) { - Report.Error (1664, Location, "Fixed size buffer `{0}' of length `{1}' and type `{2}' exceeded 2^31 limit", - GetSignatureForError (), buffer_size.ToString (), TypeManager.CSharpName (MemberType)); - return; - } - EmitFieldSize (buffer_size); #if STATIC @@ -469,32 +482,38 @@ namespace Mono.CSharp void EmitFieldSize (int buffer_size) { - PredefinedAttribute pa; - AttributeEncoder encoder; + int type_size = BuiltinTypeSpec.GetSize (MemberType); - pa = Module.PredefinedAttributes.StructLayout; - if (pa.Constructor == null && !pa.ResolveConstructor (Location, TypeManager.short_type)) + if (buffer_size > int.MaxValue / type_size) { + Report.Error (1664, Location, "Fixed size buffer `{0}' of length `{1}' and type `{2}' exceeded 2^31 limit", + GetSignatureForError (), buffer_size.ToString (), MemberType.GetSignatureForError ()); return; + } + + AttributeEncoder encoder; - var char_set_type = Module.PredefinedTypes.CharSet.Resolve (Location); - if (char_set_type == null) + var ctor = Module.PredefinedMembers.StructLayoutAttributeCtor.Resolve (Location); + if (ctor == null) return; - var field_size = pa.GetField ("Size", TypeManager.int32_type, Location); - var field_charset = pa.GetField ("CharSet", char_set_type, Location); + var field_size = Module.PredefinedMembers.StructLayoutSize.Resolve (Location); + var field_charset = Module.PredefinedMembers.StructLayoutCharSet.Resolve (Location); if (field_size == null || field_charset == null) return; var char_set = CharSet ?? Module.DefaultCharSet ?? 0; - encoder = new AttributeEncoder (false); + encoder = new AttributeEncoder (); encoder.Encode ((short)LayoutKind.Sequential); encoder.EncodeNamedArguments ( new [] { field_size, field_charset }, - new Constant [] { new IntConstant (buffer_size, Location), new IntConstant ((int) char_set, Location) } + new Constant [] { + new IntConstant (Compiler.BuiltinTypes, buffer_size * type_size, Location), + new IntConstant (Compiler.BuiltinTypes, (int) char_set, Location) + } ); - pa.EmitAttribute (fixed_buffer_type, encoder); + fixed_buffer_type.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray ()); // // Don't emit FixedBufferAttribute attribute for private types @@ -502,16 +521,16 @@ namespace Mono.CSharp if ((ModFlags & Modifiers.PRIVATE) != 0) return; - pa = Module.PredefinedAttributes.FixedBuffer; - if (pa.Constructor == null && !pa.ResolveConstructor (Location, TypeManager.type_type, TypeManager.int32_type)) + ctor = Module.PredefinedMembers.FixedBufferAttributeCtor.Resolve (Location); + if (ctor == null) return; - encoder = new AttributeEncoder (false); + encoder = new AttributeEncoder (); encoder.EncodeTypeName (MemberType); encoder.Encode (buffer_size); encoder.EncodeEmptyNamedArguments (); - pa.EmitAttribute (FieldBuilder, encoder); + FieldBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray ()); } } @@ -519,8 +538,8 @@ namespace Mono.CSharp { readonly FieldSpec element; - public FixedFieldSpec (TypeSpec declaringType, IMemberDefinition definition, FieldInfo info, FieldSpec element, Modifiers modifiers) - : base (declaringType, definition, element.MemberType, info, modifiers) + public FixedFieldSpec (ModuleContainer module, TypeSpec declaringType, IMemberDefinition definition, FieldInfo info, FieldSpec element, Modifiers modifiers) + : base (declaringType, definition, PointerContainer.MakeType (module, element.MemberType), info, modifiers) { this.element = element; @@ -533,10 +552,10 @@ namespace Mono.CSharp return element; } } - + public TypeSpec ElementType { get { - return MemberType; + return element.MemberType; } } } @@ -559,23 +578,29 @@ namespace Mono.CSharp Modifiers.UNSAFE | Modifiers.READONLY; - public Field (DeclSpace parent, FullNamedExpression type, Modifiers mod, MemberName name, - Attributes attrs) + public Field (TypeDefinition parent, FullNamedExpression type, Modifiers mod, MemberName name, Attributes attrs) : base (parent, type, mod, AllowedModifiers, name, attrs) { } bool CanBeVolatile () { - if (TypeManager.IsReferenceType (MemberType)) + switch (MemberType.BuiltinType) { + case BuiltinTypeSpec.Type.Bool: + case BuiltinTypeSpec.Type.Char: + case BuiltinTypeSpec.Type.SByte: + case BuiltinTypeSpec.Type.Byte: + case BuiltinTypeSpec.Type.Short: + case BuiltinTypeSpec.Type.UShort: + case BuiltinTypeSpec.Type.Int: + case BuiltinTypeSpec.Type.UInt: + case BuiltinTypeSpec.Type.Float: + case BuiltinTypeSpec.Type.UIntPtr: + case BuiltinTypeSpec.Type.IntPtr: return true; + } - if (MemberType == TypeManager.bool_type || MemberType == TypeManager.char_type || - MemberType == TypeManager.sbyte_type || MemberType == TypeManager.byte_type || - MemberType == TypeManager.short_type || MemberType == TypeManager.ushort_type || - MemberType == TypeManager.int32_type || MemberType == TypeManager.uint32_type || - MemberType == TypeManager.float_type || - MemberType == TypeManager.intptr_type || MemberType == TypeManager.uintptr_type) + if (TypeSpec.IsReferenceType (MemberType)) return true; if (MemberType.IsEnum) @@ -584,6 +609,11 @@ namespace Mono.CSharp return false; } + public override void Accept (StructuralVisitor visitor) + { + visitor.Visit (this); + } + public override bool Define () { if (!base.Define ()) @@ -591,7 +621,7 @@ namespace Mono.CSharp MetaType[] required_modifier = null; if ((ModFlags & Modifiers.VOLATILE) != 0) { - var mod = Module.PredefinedTypes.IsVolatile.Resolve (Location); + var mod = Module.PredefinedTypes.IsVolatile.Resolve (); if (mod != null) required_modifier = new MetaType[] { mod.GetMetaInfo () }; } @@ -601,25 +631,26 @@ namespace Mono.CSharp spec = new FieldSpec (Parent.Definition, this, MemberType, FieldBuilder, ModFlags); - // Don't cache inaccessible fields - if ((ModFlags & Modifiers.BACKING_FIELD) == 0) { + // + // Don't cache inaccessible fields except for struct where we + // need them for definitive assignment checks + // + if ((ModFlags & Modifiers.BACKING_FIELD) == 0 || Parent.Kind == MemberKind.Struct) { Parent.MemberCache.AddMember (spec); } if (initializer != null) { - ((TypeContainer) Parent).RegisterFieldForInitialization (this, - new FieldInitializer (spec, initializer, this)); + Parent.RegisterFieldForInitialization (this, new FieldInitializer (this, initializer, TypeExpression.Location)); } 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); + var f = new Field (Parent, d.GetFieldTypeExpression (this), ModFlags, new MemberName (d.Name.Value, d.Name.Location), OptAttributes); if (d.Initializer != null) f.initializer = d.Initializer; - Parent.PartialContainer.Fields.Insert (++index, f); + f.Define (); + Parent.PartialContainer.Members.Add (f); } } @@ -636,7 +667,7 @@ namespace Mono.CSharp if ((ModFlags & Modifiers.VOLATILE) != 0) { if (!CanBeVolatile ()) { Report.Error (677, Location, "`{0}': A volatile field cannot be of the type `{1}'", - GetSignatureForError (), TypeManager.CSharpName (MemberType)); + GetSignatureForError (), MemberType.GetSignatureForError ()); } if ((ModFlags & Modifiers.READONLY) != 0) {