X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fconstant.cs;h=397d72c9a4ae7653be65733999a337aaf1567695;hb=3f9310e59b924a8ef63dfef6c7f3c72935ac8f21;hp=638b3e55ba16ba0934906db7452306f4798141fc;hpb=aff7084f1d4997dd72f6abcbf3d14cebd3b3758e;p=mono.git diff --git a/mcs/mcs/constant.cs b/mcs/mcs/constant.cs index 638b3e55ba1..397d72c9a4a 100644 --- a/mcs/mcs/constant.cs +++ b/mcs/mcs/constant.cs @@ -3,10 +3,11 @@ // // Author: // Miguel de Icaza (miguel@ximian.com) -// Marek Safar (marek.safar@seznam.cz) +// Marek Safar (marek.safar@gmail.com) // // Copyright 2001-2003 Ximian, Inc. // Copyright 2003-2008 Novell, Inc. +// Copyright 2011-2013 Xamarin Inc // using System; @@ -57,15 +58,15 @@ namespace Mono.CSharp { } #endif - public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, TypeSpec target, bool expl) + public override void Error_ValueCannotBeConverted (ResolveContext ec, TypeSpec target, bool expl) { if (!expl && IsLiteral && BuiltinTypeSpec.IsPrimitiveTypeOrDecimal (target) && BuiltinTypeSpec.IsPrimitiveTypeOrDecimal (type)) { ec.Report.Error (31, loc, "Constant value `{0}' cannot be converted to a `{1}'", - GetValueAsLiteral (), TypeManager.CSharpName (target)); + GetValueAsLiteral (), target.GetSignatureForError ()); } else { - base.Error_ValueCannotBeConverted (ec, loc, target, expl); + base.Error_ValueCannotBeConverted (ec, target, expl); } } @@ -73,17 +74,22 @@ namespace Mono.CSharp { { Constant c = ConvertImplicitly (type); if (c == null) - Error_ValueCannotBeConverted (ec, loc, type, false); + Error_ValueCannotBeConverted (ec, type, false); return c; } + public override bool ContainsEmitWithAwait () + { + return false; + } + public virtual Constant ConvertImplicitly (TypeSpec type) { if (this.type == type) return this; - if (Convert.ImplicitNumericConversion (this, type) == null) + if (!Convert.ImplicitNumericConversionExists (this.type, type)) return null; bool fail; @@ -94,20 +100,15 @@ namespace Mono.CSharp { // reached, by calling Convert.ImplicitStandardConversionExists // throw new InternalErrorException ("Missing constant conversion between `{0}' and `{1}'", - TypeManager.CSharpName (Type), TypeManager.CSharpName (type)); + Type.GetSignatureForError (), type.GetSignatureForError ()); } - return CreateConstant (type, constant_value, loc); + return CreateConstantFromValue (type, constant_value, loc); } // // Returns a constant instance based on Type // - public static Constant CreateConstant (TypeSpec t, object v, Location loc) - { - return CreateConstantFromValue (t, v, loc); - } - public static Constant CreateConstantFromValue (TypeSpec t, object v, Location loc) { switch (t.BuiltinType) { @@ -154,8 +155,11 @@ namespace Mono.CSharp { return new NullConstant (t, loc); } - throw new InternalErrorException ("Constant value `{0}' has unexpected underlying type `{1}'", - v, TypeManager.CSharpName (t)); +#if STATIC + throw new InternalErrorException ("Constant value `{0}' has unexpected underlying type `{1}'", v, t.GetSignatureForError ()); +#else + return null; +#endif } public override Expression CreateExpressionTree (ResolveContext ec) @@ -242,35 +246,52 @@ namespace Mono.CSharp { return this; } - /// - /// Attempts to do a compile-time folding of a constant cast. - /// - public Constant TryReduce (ResolveContext ec, TypeSpec target_type, Location loc) + // + // Attempts to do a compile-time folding of a constant cast and handles + // error reporting for constant overlows only, on normal conversion + // errors returns null + // + public Constant Reduce (ResolveContext ec, TypeSpec target_type) { try { - return TryReduce (ec, target_type); - } - catch (OverflowException) { + return TryReduceConstant (ec, target_type); + } catch (OverflowException) { if (ec.ConstantCheckState && Type.BuiltinType != BuiltinTypeSpec.Type.Decimal) { ec.Report.Error (221, loc, "Constant value `{0}' cannot be converted to a `{1}' (use `unchecked' syntax to override)", GetValueAsLiteral (), target_type.GetSignatureForError ()); } else { - Error_ValueCannotBeConverted (ec, loc, target_type, false); + Error_ValueCannotBeConverted (ec, target_type, false); } return New.Constantify (target_type, loc); } } - Constant TryReduce (ResolveContext ec, TypeSpec target_type) + public Constant TryReduce (ResolveContext rc, TypeSpec targetType) + { + try { + return TryReduceConstant (rc, targetType); + } catch (OverflowException) { + return null; + } + } + + Constant TryReduceConstant (ResolveContext ec, TypeSpec target_type) { - if (Type == target_type) + if (Type == target_type) { + // + // Reducing literal value produces a new constant. Syntactically 10 is not same as (int)10 + // + if (IsLiteral) + return CreateConstantFromValue (target_type, GetValue (), loc); + return this; + } Constant c; - if (TypeManager.IsEnumType (target_type)) { - c = TryReduce (ec, EnumSpec.GetUnderlyingType (target_type)); + if (target_type.IsEnum) { + c = TryReduceConstant (ec, EnumSpec.GetUnderlyingType (target_type)); if (c == null) return null; @@ -366,16 +387,16 @@ namespace Mono.CSharp { eclass = ExprClass.Value; } - public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, TypeSpec target, bool expl) + public override void Error_ValueCannotBeConverted (ResolveContext ec, TypeSpec target, bool expl) { try { ConvertExplicitly (true, target); - base.Error_ValueCannotBeConverted (ec, loc, target, expl); + base.Error_ValueCannotBeConverted (ec, target, expl); } catch { ec.Report.Error (31, loc, "Constant value `{0}' cannot be converted to a `{1}'", - GetValue ().ToString (), TypeManager.CSharpName (target)); + GetValue ().ToString (), target.GetSignatureForError ()); } }