X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fconst.cs;h=2588ab92aac252b9fc079d82917a265f45d29729;hb=9852c2cbe6f73daa670b333daf70c01d96c2261a;hp=7422b492b3f23be40c2771edca882855dc315718;hpb=a097b5471761180c4aae2dab224ed9caeeae3e86;p=mono.git diff --git a/mcs/mcs/const.cs b/mcs/mcs/const.cs index 7422b492b3f..2588ab92aac 100644 --- a/mcs/mcs/const.cs +++ b/mcs/mcs/const.cs @@ -20,12 +20,13 @@ namespace Mono.CSharp { { void CheckObsoleteness (Location loc); bool ResolveValue (); - Constant Value { get; } + Constant CreateConstantReference (Location loc); } - public class Const : FieldMember, IConstant { - Constant value; + public class Const : FieldBase, IConstant { + protected Constant value; bool in_transit; + bool resolved; bool define_called; public const int AllowedModifiers = @@ -76,22 +77,29 @@ namespace Mono.CSharp { return false; } + // If the constant is private then we don't need any field the + // value is already inlined and cannot be referenced + //if ((ModFlags & Modifiers.PRIVATE) != 0 && RootContext.Optimize) + // return true; + while (ttype.IsArray) - ttype = TypeManager.GetElementType (ttype); + ttype = TypeManager.GetElementType (ttype); FieldAttributes field_attr = FieldAttributes.Static | Modifiers.FieldAttr (ModFlags); // Decimals cannot be emitted into the constant blob. So, convert to 'readonly'. if (ttype == TypeManager.decimal_type) { field_attr |= FieldAttributes.InitOnly; - Parent.PartialContainer.RegisterFieldForInitialization (this); } else { field_attr |= FieldAttributes.Literal; } FieldBuilder = Parent.TypeBuilder.DefineField (Name, MemberType, field_attr); - TypeManager.RegisterConstant (FieldBuilder, this); + if (ttype == TypeManager.decimal_type) + Parent.PartialContainer.RegisterFieldForInitialization (this, + new FieldInitializer (FieldBuilder, initializer, Parent)); + return true; } @@ -117,6 +125,9 @@ namespace Mono.CSharp { if (!ResolveValue ()) return; + if (FieldBuilder == null) + return; + if (value.Type == TypeManager.decimal_type) { Decimal d = ((DecimalConstant)value).Value; int[] bits = Decimal.GetBits (d); @@ -157,42 +168,52 @@ namespace Mono.CSharp { public bool ResolveValue () { - if (value != null) - return true; + if (resolved) + return value != null; SetMemberIsUsed (); if (in_transit) { Error_CyclicDeclaration (this); // Suppress cyclic errors value = New.Constantify (MemberType); + resolved = true; return false; } in_transit = true; // TODO: IResolveContext here - EmitContext ec = new EmitContext (this, Parent, Location, null, MemberType, ModFlags); - value = initializer.ResolveAsConstant (ec, this); + EmitContext ec = new EmitContext ( + this, Parent, Location, null, MemberType, ModFlags); + ec.InEnumContext = this is EnumMember; + value = DoResolveValue (ec); in_transit = false; + resolved = true; + return value != null; + } + protected virtual Constant DoResolveValue (EmitContext ec) + { + Constant value = initializer.ResolveAsConstant (ec, this); if (value == null) - return false; - - value = value.ImplicitConversionRequired (MemberType, Location); - if (value == null) - return false; + return null; - if (!MemberType.IsValueType && MemberType != TypeManager.string_type && !value.IsDefaultValue) { - Error_ConstantCanBeInitializedWithNullOnly (Location, GetSignatureForError ()); - return false; + Constant c = value.ConvertImplicitly (MemberType); + if (c == null) { + if (!MemberType.IsValueType && MemberType != TypeManager.string_type && !value.IsDefaultValue) + Error_ConstantCanBeInitializedWithNullOnly (Location, GetSignatureForError ()); + else + value.Error_ValueCannotBeConverted (null, Location, MemberType, false); } - return true; + return c; } - public Constant Value { - get { - return value; - } + public virtual Constant CreateConstantReference (Location loc) + { + if (value == null) + return null; + + return Constant.CreateConstant (value.Type, value.GetValue(), loc); } #endregion @@ -201,14 +222,14 @@ namespace Mono.CSharp { public class ExternalConstant : IConstant { FieldInfo fi; - Constant value; + object value; public ExternalConstant (FieldInfo fi) { this.fi = fi; } - private ExternalConstant (FieldInfo fi, Constant value): + private ExternalConstant (FieldInfo fi, object value): this (fi) { this.value = value; @@ -229,7 +250,7 @@ namespace Mono.CSharp { return null; IConstant ic = new ExternalConstant (fi, - new DecimalConstant (((System.Runtime.CompilerServices.DecimalConstantAttribute) attrs [0]).Value, Location.Null)); + ((System.Runtime.CompilerServices.DecimalConstantAttribute) attrs [0]).Value); return ic; } @@ -251,20 +272,13 @@ namespace Mono.CSharp { if (value != null) return true; - if (fi.DeclaringType.IsEnum) { - value = Expression.Constantify (fi.GetValue (fi), TypeManager.EnumToUnderlying (fi.FieldType)); - value = new EnumConstant (value, fi.DeclaringType); - return true; - } - - value = Expression.Constantify (fi.GetValue (fi), fi.FieldType); + value = fi.GetValue (fi); return true; } - public Constant Value { - get { - return value; - } + public Constant CreateConstantReference (Location loc) + { + return Constant.CreateConstant (fi.FieldType, value, loc); } #endregion