X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fconstant.cs;h=8ea18f3c74d842f9d4d26334ac75c89826222d9d;hb=bc5aebde4188af99f1b3d5415be88910e436f209;hp=18ca2dd7bdd3d8f57defbfb04817b737b351abec;hpb=25a65a17552f510c26f16a21dfd086f112b61133;p=mono.git diff --git a/mcs/mcs/constant.cs b/mcs/mcs/constant.cs index 18ca2dd7bdd..8ea18f3c74d 100644 --- a/mcs/mcs/constant.cs +++ b/mcs/mcs/constant.cs @@ -39,6 +39,18 @@ namespace Mono.CSharp { return this.GetType ().Name + " (" + AsString () + ")"; } + public override bool GetAttributableValue (Type valueType, out object value) + { + Constant c = ImplicitConversionRequired (valueType, loc); + if (c == null) { + value = null; + return false; + } + + value = c.GetTypedValue (); + return true; + } + /// /// This is used to obtain the actual value of the literal /// cast into an object. @@ -58,6 +70,14 @@ namespace Mono.CSharp { return this; } + public Constant ImplicitConversionRequired (Type type, Location loc) + { + Constant c = ToType (type); + if (c == null) + Error_ValueCannotBeConverted (loc, type, false); + return c; + } + // // The various ToXXXX conversion functions are used by the constant // folding evaluator. A null value is returned if the conversion is @@ -139,7 +159,7 @@ namespace Mono.CSharp { return c; } - public virtual Constant ToType (Type type, Location loc) + public virtual Constant ToType (Type type) { if (Type == type) return this; @@ -147,8 +167,7 @@ namespace Mono.CSharp { if (type == TypeManager.object_type) return this; - if (!Convert.ImplicitStandardConversionExists (Convert.ConstantEC, this, type)){ - Error_ValueCannotBeConverted (loc, type, false); + if (!Convert.ImplicitStandardConversionExists (this, type)){ return null; } @@ -161,8 +180,6 @@ namespace Mono.CSharp { bool fail; object constant_value = TypeManager.ChangeType (GetValue (), type, out fail); if (fail){ - Error_ValueCannotBeConverted (loc, type, false); - // // We should always catch the error before this is ever // reached, by calling Convert.ImplicitStandardConversionExists @@ -171,69 +188,101 @@ namespace Mono.CSharp { String.Format ("LookupConstantValue: This should never be reached {0} {1}", Type, type)); } - Constant retval; - if (type == TypeManager.int32_type) - retval = new IntConstant ((int) constant_value, loc); - else if (type == TypeManager.uint32_type) - retval = new UIntConstant ((uint) constant_value, loc); - else if (type == TypeManager.int64_type) - retval = new LongConstant ((long) constant_value, loc); - else if (type == TypeManager.uint64_type) - retval = new ULongConstant ((ulong) constant_value, loc); - else if (type == TypeManager.float_type) - retval = new FloatConstant ((float) constant_value, loc); - else if (type == TypeManager.double_type) - retval = new DoubleConstant ((double) constant_value, loc); - else if (type == TypeManager.string_type) - retval = new StringConstant ((string) constant_value, loc); - else if (type == TypeManager.short_type) - retval = new ShortConstant ((short) constant_value, loc); - else if (type == TypeManager.ushort_type) - retval = new UShortConstant ((ushort) constant_value, loc); - else if (type == TypeManager.sbyte_type) - retval = new SByteConstant ((sbyte) constant_value, loc); - else if (type == TypeManager.byte_type) - retval = new ByteConstant ((byte) constant_value, loc); - else if (type == TypeManager.char_type) - retval = new CharConstant ((char) constant_value, loc); - else if (type == TypeManager.bool_type) - retval = new BoolConstant ((bool) constant_value, loc); - else if (type == TypeManager.decimal_type) - retval = new DecimalConstant ((decimal) constant_value, loc); - else - throw new Exception ("LookupConstantValue: Unhandled constant type: " + type); - - return retval; + return CreateConstant (type, constant_value, loc); + } + + /// Returns a constant instance based on Type + /// The returned value is already resolved. + public static Constant CreateConstant (Type t, object v, Location loc) + { + if (t == TypeManager.int32_type) + return new IntConstant ((int) v, loc); + if (t == TypeManager.string_type) + return new StringConstant ((string) v, loc); + if (t == TypeManager.uint32_type) + return new UIntConstant ((uint) v, loc); + if (t == TypeManager.int64_type) + return new LongConstant ((long) v, loc); + if (t == TypeManager.uint64_type) + return new ULongConstant ((ulong) v, loc); + if (t == TypeManager.float_type) + return new FloatConstant ((float) v, loc); + if (t == TypeManager.double_type) + return new DoubleConstant ((double) v, loc); + if (t == TypeManager.short_type) + return new ShortConstant ((short)v, loc); + if (t == TypeManager.ushort_type) + return new UShortConstant ((ushort)v, loc); + if (t == TypeManager.sbyte_type) + return new SByteConstant ((sbyte)v, loc); + if (t == TypeManager.byte_type) + return new ByteConstant ((byte)v, loc); + if (t == TypeManager.char_type) + return new CharConstant ((char)v, loc); + if (t == TypeManager.bool_type) + return new BoolConstant ((bool) v, loc); + if (t == TypeManager.decimal_type) + return new DecimalConstant ((decimal) v, loc); + if (TypeManager.IsEnumType (t)) { + Type real_type = TypeManager.TypeToCoreType (v.GetType ()); + if (real_type == t) + real_type = System.Enum.GetUnderlyingType (real_type); + return new EnumConstant (CreateConstant (real_type, v, loc), t); + } + if (v == null && !TypeManager.IsValueType (t)) + return new EmptyConstantCast (new NullConstant (loc), t); + + throw new Exception ("Unknown type for constant (" + t + + "), details: " + v); + } + + protected static void CheckRange (bool inCheckedContext, ulong value, ulong max) + { + if (!inCheckedContext) + return; + + if (value > max) + throw new OverflowException (); } - protected void CheckRange (EmitContext ec, ulong value, Type type, ulong max) + protected static void CheckRange (bool inCheckedContext, double value, long min, long max) { - if (!ec.ConstantCheckState) + if (!inCheckedContext) return; - if (value > max) + if (((value < min) || (value > max))) + throw new OverflowException (); + + if (double.IsNaN (value)) throw new OverflowException (); } - protected void CheckRange (EmitContext ec, double value, Type type, long min, long max) + protected static void CheckRange (bool inCheckedContext, double value, ulong min, ulong max) { - if (!ec.ConstantCheckState) + if (!inCheckedContext) return; if (((value < min) || (value > max))) throw new OverflowException (); + + if (double.IsNaN (value)) + throw new OverflowException (); } - protected void CheckUnsigned (EmitContext ec, long value, Type type) + protected static void CheckUnsigned (bool inCheckedContext, long value) { - if (!ec.ConstantCheckState) + if (!inCheckedContext) return; if (value < 0) throw new OverflowException (); } - public abstract Constant Reduce (EmitContext ec, Type target_type); + /// + /// Maybe ConvertTo name is better. It tries to convert `this' constant to target_type. + /// It throws OverflowException + /// + public abstract Constant Reduce (bool inCheckedContext, Type target_type); /// /// Attempts to do a compile-time folding of a constant cast. @@ -244,11 +293,9 @@ namespace Mono.CSharp { return TryReduce (ec, target_type); } catch (OverflowException) { - if (ec.ConstantCheckState) { - Report.Error (221, loc, "Constant value `{0}' cannot be converted to a `{1}' (use `unchecked' syntax to override)", - this.GetValue (), TypeManager.CSharpName (target_type)); - } - return null; + Report.Error (221, loc, "Constant value `{0}' cannot be converted to a `{1}' (use `unchecked' syntax to override)", + GetValue ().ToString (), TypeManager.CSharpName (target_type)); + throw; } } @@ -265,7 +312,7 @@ namespace Mono.CSharp { return new EnumConstant (c, target_type); } - return Reduce (ec, target_type); + return Reduce (ec.ConstantCheckState, target_type); } @@ -306,6 +353,18 @@ namespace Mono.CSharp { public abstract Constant Increment (); + /// + /// Need to pass type as the constant can require a boxing + /// and in such case no optimization is possible + /// + public bool IsDefaultInitializer (Type type) + { + if (type == Type) + return IsDefaultValue; + + return Type == TypeManager.null_type; + } + public abstract bool IsDefaultValue { get; } @@ -322,6 +381,26 @@ namespace Mono.CSharp { get { return false; } } } + + public abstract class IntegralConstant : Constant { + protected IntegralConstant (Location loc) : + base (loc) + { + } + + public override void Error_ValueCannotBeConverted (Location loc, Type target, bool expl) + { + try { + Reduce (true, target); + base.Error_ValueCannotBeConverted (loc, target, expl); + } + catch + { + Report.Error (31, loc, "Constant value `{0}' cannot be converted to a `{1}'", + GetValue ().ToString (), TypeManager.CSharpName (target)); + } + } + } public class BoolConstant : Constant { public readonly bool Value; @@ -375,14 +454,14 @@ namespace Mono.CSharp { get { return Value == false; } } - public override Constant Reduce (EmitContext ec, Type target_type) + public override Constant Reduce (bool inCheckedContext, Type target_type) { return null; } } - public class ByteConstant : Constant { + public class ByteConstant : IntegralConstant { public readonly byte Value; public ByteConstant (byte v, Location loc): @@ -459,10 +538,10 @@ namespace Mono.CSharp { get { return Value == 0; } } - public override Constant Reduce (EmitContext ec, Type target_type) + public override Constant Reduce (bool inCheckedContext, Type target_type) { if (target_type == TypeManager.sbyte_type) { - CheckRange (ec, Value, target_type, SByte.MinValue, SByte.MaxValue); + CheckRange (inCheckedContext, Value, SByte.MinValue, SByte.MaxValue); return new SByteConstant ((sbyte) Value, Location); } if (target_type == TypeManager.short_type) @@ -597,18 +676,18 @@ namespace Mono.CSharp { get { return Value == '\0'; } } - public override Constant Reduce (EmitContext ec, Type target_type) + public override Constant Reduce (bool inCheckedContext, Type target_type) { if (target_type == TypeManager.byte_type) { - CheckRange (ec, Value, target_type, Byte.MinValue, Byte.MaxValue); + CheckRange (inCheckedContext, Value, Byte.MinValue, Byte.MaxValue); return new ByteConstant ((byte) Value, Location); } if (target_type == TypeManager.sbyte_type) { - CheckRange (ec, Value, target_type, SByte.MinValue, SByte.MaxValue); + CheckRange (inCheckedContext, Value, SByte.MinValue, SByte.MaxValue); return new SByteConstant ((sbyte) Value, Location); } if (target_type == TypeManager.short_type) { - CheckRange (ec, Value, target_type, Int16.MinValue, Int16.MaxValue); + CheckRange (inCheckedContext, Value, Int16.MinValue, Int16.MaxValue); return new ShortConstant ((short) Value, Location); } if (target_type == TypeManager.int32_type) @@ -631,7 +710,7 @@ namespace Mono.CSharp { } - public class SByteConstant : Constant { + public class SByteConstant : IntegralConstant { public readonly sbyte Value; public SByteConstant (sbyte v, Location loc): @@ -711,26 +790,26 @@ namespace Mono.CSharp { get { return Value == 0; } } - public override Constant Reduce (EmitContext ec, Type target_type) + public override Constant Reduce (bool inCheckedContext, Type target_type) { if (target_type == TypeManager.byte_type) { - CheckUnsigned (ec, Value, target_type); + CheckUnsigned (inCheckedContext, Value); return new ByteConstant ((byte) Value, Location); } if (target_type == TypeManager.short_type) return new ShortConstant ((short) Value, Location); if (target_type == TypeManager.ushort_type) { - CheckUnsigned (ec, Value, target_type); + CheckUnsigned (inCheckedContext, Value); return new UShortConstant ((ushort) Value, Location); } if (target_type == TypeManager.int32_type) return new IntConstant ((int) Value, Location); if (target_type == TypeManager.uint32_type) { - CheckUnsigned (ec, Value, target_type); + CheckUnsigned (inCheckedContext, Value); return new UIntConstant ((uint) Value, Location); } if (target_type == TypeManager.int64_type) return new LongConstant ((long) Value, Location); if (target_type == TypeManager.uint64_type) { - CheckUnsigned (ec, Value, target_type); + CheckUnsigned (inCheckedContext, Value); return new ULongConstant ((ulong) Value, Location); } if (target_type == TypeManager.float_type) @@ -738,7 +817,7 @@ namespace Mono.CSharp { if (target_type == TypeManager.double_type) return new DoubleConstant ((double) Value, Location); if (target_type == TypeManager.char_type) { - CheckUnsigned (ec, Value, target_type); + CheckUnsigned (inCheckedContext, Value); return new CharConstant ((char) Value, Location); } if (target_type == TypeManager.decimal_type) @@ -749,7 +828,7 @@ namespace Mono.CSharp { } - public class ShortConstant : Constant { + public class ShortConstant : IntegralConstant { public readonly short Value; public ShortConstant (short v, Location loc): @@ -826,30 +905,30 @@ namespace Mono.CSharp { } } - public override Constant Reduce (EmitContext ec, Type target_type) + public override Constant Reduce (bool inCheckedContext, Type target_type) { if (target_type == TypeManager.byte_type) { - CheckRange (ec, Value, target_type, Byte.MinValue, Byte.MaxValue); + CheckRange (inCheckedContext, Value, Byte.MinValue, Byte.MaxValue); return new ByteConstant ((byte) Value, Location); } if (target_type == TypeManager.sbyte_type) { - CheckRange (ec, Value, target_type, SByte.MinValue, SByte.MaxValue); + CheckRange (inCheckedContext, Value, SByte.MinValue, SByte.MaxValue); return new SByteConstant ((sbyte) Value, Location); } if (target_type == TypeManager.ushort_type) { - CheckUnsigned (ec, Value, target_type); + CheckUnsigned (inCheckedContext, Value); return new UShortConstant ((ushort) Value, Location); } if (target_type == TypeManager.int32_type) return new IntConstant ((int) Value, Location); if (target_type == TypeManager.uint32_type) { - CheckUnsigned (ec, Value, target_type); + CheckUnsigned (inCheckedContext, Value); return new UIntConstant ((uint) Value, Location); } if (target_type == TypeManager.int64_type) return new LongConstant ((long) Value, Location); if (target_type == TypeManager.uint64_type) { - CheckUnsigned (ec, Value, target_type); + CheckUnsigned (inCheckedContext, Value); return new ULongConstant ((ulong) Value, Location); } if (target_type == TypeManager.float_type) @@ -857,7 +936,7 @@ namespace Mono.CSharp { if (target_type == TypeManager.double_type) return new DoubleConstant ((double) Value, Location); if (target_type == TypeManager.char_type) { - CheckRange (ec, Value, target_type, Char.MinValue, Char.MaxValue); + CheckRange (inCheckedContext, Value, Char.MinValue, Char.MaxValue); return new CharConstant ((char) Value, Location); } if (target_type == TypeManager.decimal_type) @@ -868,7 +947,7 @@ namespace Mono.CSharp { } - public class UShortConstant : Constant { + public class UShortConstant : IntegralConstant { public readonly ushort Value; public UShortConstant (ushort v, Location loc): @@ -945,18 +1024,18 @@ namespace Mono.CSharp { get { return Value == 0; } } - public override Constant Reduce (EmitContext ec, Type target_type) + public override Constant Reduce (bool inCheckedContext, Type target_type) { if (target_type == TypeManager.byte_type) { - CheckRange (ec, Value, target_type, Byte.MinValue, Byte.MaxValue); + CheckRange (inCheckedContext, Value, Byte.MinValue, Byte.MaxValue); return new ByteConstant ((byte) Value, Location); } if (target_type == TypeManager.sbyte_type) { - CheckRange (ec, Value, target_type, SByte.MinValue, SByte.MaxValue); + CheckRange (inCheckedContext, Value, SByte.MinValue, SByte.MaxValue); return new SByteConstant ((sbyte) Value, Location); } if (target_type == TypeManager.short_type) { - CheckRange (ec, Value, target_type, Int16.MinValue, Int16.MaxValue); + CheckRange (inCheckedContext, Value, Int16.MinValue, Int16.MaxValue); return new ShortConstant ((short) Value, Location); } if (target_type == TypeManager.int32_type) @@ -972,7 +1051,7 @@ namespace Mono.CSharp { if (target_type == TypeManager.double_type) return new DoubleConstant ((double) Value, Location); if (target_type == TypeManager.char_type) { - CheckRange (ec, Value, target_type, Char.MinValue, Char.MaxValue); + CheckRange (inCheckedContext, Value, Char.MinValue, Char.MaxValue); return new CharConstant ((char) Value, Location); } if (target_type == TypeManager.decimal_type) @@ -982,7 +1061,7 @@ namespace Mono.CSharp { } } - public class IntConstant : Constant { + public class IntConstant : IntegralConstant { public readonly int Value; public IntConstant (int v, Location loc): @@ -1122,32 +1201,32 @@ namespace Mono.CSharp { get { return Value == 0; } } - public override Constant Reduce (EmitContext ec, Type target_type) + public override Constant Reduce (bool inCheckedContext, Type target_type) { if (target_type == TypeManager.byte_type) { - CheckRange (ec, Value, target_type, Byte.MinValue, Byte.MaxValue); + CheckRange (inCheckedContext, Value, Byte.MinValue, Byte.MaxValue); return new ByteConstant ((byte) Value, Location); } if (target_type == TypeManager.sbyte_type) { - CheckRange (ec, Value, target_type, SByte.MinValue, SByte.MaxValue); + CheckRange (inCheckedContext, Value, SByte.MinValue, SByte.MaxValue); return new SByteConstant ((sbyte) Value, Location); } if (target_type == TypeManager.short_type) { - CheckRange (ec, Value, target_type, Int16.MinValue, Int16.MaxValue); + CheckRange (inCheckedContext, Value, Int16.MinValue, Int16.MaxValue); return new ShortConstant ((short) Value, Location); } if (target_type == TypeManager.ushort_type) { - CheckRange (ec, Value, target_type, UInt16.MinValue, UInt16.MaxValue); + CheckRange (inCheckedContext, Value, UInt16.MinValue, UInt16.MaxValue); return new UShortConstant ((ushort) Value, Location); } if (target_type == TypeManager.uint32_type) { - CheckRange (ec, Value, target_type, Int32.MinValue, Int32.MaxValue); + CheckRange (inCheckedContext, Value, UInt32.MinValue, UInt32.MaxValue); return new UIntConstant ((uint) Value, Location); } if (target_type == TypeManager.int64_type) return new LongConstant ((long) Value, Location); if (target_type == TypeManager.uint64_type) { - CheckUnsigned (ec, Value, target_type); + CheckUnsigned (inCheckedContext, Value); return new ULongConstant ((ulong) Value, Location); } if (target_type == TypeManager.float_type) @@ -1155,7 +1234,7 @@ namespace Mono.CSharp { if (target_type == TypeManager.double_type) return new DoubleConstant ((double) Value, Location); if (target_type == TypeManager.char_type) { - CheckRange (ec, Value, target_type, Char.MinValue, Char.MaxValue); + CheckRange (inCheckedContext, Value, Char.MinValue, Char.MaxValue); return new CharConstant ((char) Value, Location); } if (target_type == TypeManager.decimal_type) @@ -1165,7 +1244,7 @@ namespace Mono.CSharp { } } - public class UIntConstant : Constant { + public class UIntConstant : IntegralConstant { public readonly uint Value; public UIntConstant (uint v, Location loc): @@ -1242,26 +1321,26 @@ namespace Mono.CSharp { get { return Value == 0; } } - public override Constant Reduce (EmitContext ec, Type target_type) + public override Constant Reduce (bool inCheckedContext, Type target_type) { if (target_type == TypeManager.byte_type) { - CheckRange (ec, Value, target_type, Char.MinValue, Char.MaxValue); + CheckRange (inCheckedContext, Value, Char.MinValue, Char.MaxValue); return new ByteConstant ((byte) Value, Location); } if (target_type == TypeManager.sbyte_type) { - CheckRange (ec, Value, target_type, SByte.MinValue, SByte.MaxValue); + CheckRange (inCheckedContext, Value, SByte.MinValue, SByte.MaxValue); return new SByteConstant ((sbyte) Value, Location); } if (target_type == TypeManager.short_type) { - CheckRange (ec, Value, target_type, Int16.MinValue, Int16.MaxValue); + CheckRange (inCheckedContext, Value, Int16.MinValue, Int16.MaxValue); return new ShortConstant ((short) Value, Location); } if (target_type == TypeManager.ushort_type) { - CheckRange (ec, Value, target_type, UInt16.MinValue, UInt16.MaxValue); + CheckRange (inCheckedContext, Value, UInt16.MinValue, UInt16.MaxValue); return new UShortConstant ((ushort) Value, Location); } if (target_type == TypeManager.int32_type) { - CheckRange (ec, Value, target_type, Int32.MinValue, Int32.MaxValue); + CheckRange (inCheckedContext, Value, Int32.MinValue, Int32.MaxValue); return new IntConstant ((int) Value, Location); } if (target_type == TypeManager.int64_type) @@ -1273,7 +1352,7 @@ namespace Mono.CSharp { if (target_type == TypeManager.double_type) return new DoubleConstant ((double) Value, Location); if (target_type == TypeManager.char_type) { - CheckRange (ec, Value, target_type, Char.MinValue, Char.MaxValue); + CheckRange (inCheckedContext, Value, Char.MinValue, Char.MaxValue); return new CharConstant ((char) Value, Location); } if (target_type == TypeManager.decimal_type) @@ -1284,7 +1363,7 @@ namespace Mono.CSharp { } - public class LongConstant : Constant { + public class LongConstant : IntegralConstant { public readonly long Value; public LongConstant (long v, Location loc): @@ -1297,19 +1376,17 @@ namespace Mono.CSharp { public override void Emit (EmitContext ec) { - ILGenerator ig = ec.ig; - - EmitLong (ig, Value); + EmitLong (ec.ig, Value); } static public void EmitLong (ILGenerator ig, long l) { - if ((l >> 32) == 0){ + if (l >= int.MinValue && l <= int.MaxValue) { IntLiteral.EmitInt (ig, unchecked ((int) l)); - ig.Emit (OpCodes.Conv_U8); - } else { - ig.Emit (OpCodes.Ldc_I8, l); + ig.Emit (OpCodes.Conv_I8); + return; } + ig.Emit (OpCodes.Ldc_I8, l); } public override string AsString () @@ -1376,34 +1453,34 @@ namespace Mono.CSharp { get { return Value == 0; } } - public override Constant Reduce (EmitContext ec, Type target_type) + public override Constant Reduce (bool inCheckedContext, Type target_type) { if (target_type == TypeManager.byte_type) { - CheckRange (ec, Value, target_type, Byte.MinValue, Byte.MaxValue); + CheckRange (inCheckedContext, Value, Byte.MinValue, Byte.MaxValue); return new ByteConstant ((byte) Value, Location); } if (target_type == TypeManager.sbyte_type) { - CheckRange (ec, Value, target_type, SByte.MinValue, SByte.MaxValue); + CheckRange (inCheckedContext, Value, SByte.MinValue, SByte.MaxValue); return new SByteConstant ((sbyte) Value, Location); } if (target_type == TypeManager.short_type) { - CheckRange (ec, Value, target_type, Int16.MinValue, Int16.MaxValue); + CheckRange (inCheckedContext, Value, Int16.MinValue, Int16.MaxValue); return new ShortConstant ((short) Value, Location); } if (target_type == TypeManager.ushort_type) { - CheckRange (ec, Value, target_type, UInt16.MinValue, UInt16.MaxValue); + CheckRange (inCheckedContext, Value, UInt16.MinValue, UInt16.MaxValue); return new UShortConstant ((ushort) Value, Location); } if (target_type == TypeManager.int32_type) { - CheckRange (ec, Value, target_type, Int32.MinValue, Int32.MaxValue); + CheckRange (inCheckedContext, Value, Int32.MinValue, Int32.MaxValue); return new IntConstant ((int) Value, Location); } if (target_type == TypeManager.uint32_type) { - CheckRange (ec, Value, target_type, UInt32.MinValue, UInt32.MaxValue); + CheckRange (inCheckedContext, Value, UInt32.MinValue, UInt32.MaxValue); return new UIntConstant ((uint) Value, Location); } if (target_type == TypeManager.uint64_type) { - CheckUnsigned (ec, Value, target_type); + CheckUnsigned (inCheckedContext, Value); return new ULongConstant ((ulong) Value, Location); } if (target_type == TypeManager.float_type) @@ -1411,7 +1488,7 @@ namespace Mono.CSharp { if (target_type == TypeManager.double_type) return new DoubleConstant ((double) Value, Location); if (target_type == TypeManager.char_type) { - CheckRange (ec, Value, target_type, Char.MinValue, Char.MaxValue); + CheckRange (inCheckedContext, Value, Char.MinValue, Char.MaxValue); return new CharConstant ((char) Value, Location); } if (target_type == TypeManager.decimal_type) @@ -1422,7 +1499,7 @@ namespace Mono.CSharp { } - public class ULongConstant : Constant { + public class ULongConstant : IntegralConstant { public readonly ulong Value; public ULongConstant (ulong v, Location loc): @@ -1501,34 +1578,34 @@ namespace Mono.CSharp { get { return Value == 0; } } - public override Constant Reduce (EmitContext ec, Type target_type) + public override Constant Reduce (bool inCheckedContext, Type target_type) { if (target_type == TypeManager.byte_type) { - CheckRange (ec, Value, target_type, Byte.MaxValue); + CheckRange (inCheckedContext, Value, Byte.MaxValue); return new ByteConstant ((byte) Value, Location); } if (target_type == TypeManager.sbyte_type) { - CheckRange (ec, Value, target_type, (ulong) SByte.MaxValue); + CheckRange (inCheckedContext, Value, (ulong) SByte.MaxValue); return new SByteConstant ((sbyte) Value, Location); } if (target_type == TypeManager.short_type) { - CheckRange (ec, Value, target_type, (ulong) Int16.MaxValue); + CheckRange (inCheckedContext, Value, (ulong) Int16.MaxValue); return new ShortConstant ((short) Value, Location); } if (target_type == TypeManager.ushort_type) { - CheckRange (ec, Value, target_type, UInt16.MaxValue); + CheckRange (inCheckedContext, Value, UInt16.MaxValue); return new UShortConstant ((ushort) Value, Location); } if (target_type == TypeManager.int32_type) { - CheckRange (ec, Value, target_type, Int32.MaxValue); + CheckRange (inCheckedContext, Value, Int32.MaxValue); return new IntConstant ((int) Value, Location); } if (target_type == TypeManager.uint32_type) { - CheckRange (ec, Value, target_type, UInt32.MaxValue); + CheckRange (inCheckedContext, Value, UInt32.MaxValue); return new UIntConstant ((uint) Value, Location); } if (target_type == TypeManager.int64_type) { - CheckRange (ec, Value, target_type, (ulong) Int64.MaxValue); + CheckRange (inCheckedContext, Value, (ulong) Int64.MaxValue); return new LongConstant ((long) Value, Location); } if (target_type == TypeManager.float_type) @@ -1536,7 +1613,7 @@ namespace Mono.CSharp { if (target_type == TypeManager.double_type) return new DoubleConstant ((double) Value, Location); if (target_type == TypeManager.char_type) { - CheckRange (ec, Value, target_type, Char.MaxValue); + CheckRange (inCheckedContext, Value, Char.MaxValue); return new CharConstant ((char) Value, Location); } if (target_type == TypeManager.decimal_type) @@ -1548,7 +1625,7 @@ namespace Mono.CSharp { } public class FloatConstant : Constant { - public readonly float Value; + public float Value; public FloatConstant (float v, Location loc): base (loc) @@ -1615,28 +1692,46 @@ namespace Mono.CSharp { } } - public override Constant Reduce (EmitContext ec, Type target_type) + public override Constant Reduce (bool inCheckedContext, Type target_type) { - if (target_type == TypeManager.byte_type) + if (target_type == TypeManager.byte_type) { + CheckRange (inCheckedContext, Value, byte.MinValue, byte.MaxValue); return new ByteConstant ((byte) Value, Location); - if (target_type == TypeManager.sbyte_type) + } + if (target_type == TypeManager.sbyte_type) { + CheckRange (inCheckedContext, Value, sbyte.MinValue, sbyte.MaxValue); return new SByteConstant ((sbyte) Value, Location); - if (target_type == TypeManager.short_type) + } + if (target_type == TypeManager.short_type) { + CheckRange (inCheckedContext, Value, short.MinValue, short.MaxValue); return new ShortConstant ((short) Value, Location); - if (target_type == TypeManager.ushort_type) + } + if (target_type == TypeManager.ushort_type) { + CheckRange (inCheckedContext, Value, ushort.MinValue, ushort.MaxValue); return new UShortConstant ((ushort) Value, Location); - if (target_type == TypeManager.int32_type) + } + if (target_type == TypeManager.int32_type) { + CheckRange (inCheckedContext, Value, int.MinValue, int.MaxValue); return new IntConstant ((int) Value, Location); - if (target_type == TypeManager.uint32_type) + } + if (target_type == TypeManager.uint32_type) { + CheckRange (inCheckedContext, Value, uint.MinValue, uint.MaxValue); return new UIntConstant ((uint) Value, Location); - if (target_type == TypeManager.int64_type) + } + if (target_type == TypeManager.int64_type) { + CheckRange (inCheckedContext, Value, long.MinValue, long.MaxValue); return new LongConstant ((long) Value, Location); - if (target_type == TypeManager.uint64_type) + } + if (target_type == TypeManager.uint64_type) { + CheckRange (inCheckedContext, Value, ulong.MinValue, ulong.MaxValue); return new ULongConstant ((ulong) Value, Location); + } if (target_type == TypeManager.double_type) return new DoubleConstant ((double) Value, Location); - if (target_type == TypeManager.char_type) + if (target_type == TypeManager.char_type) { + CheckRange (inCheckedContext, Value, char.MinValue, char.MaxValue); return new CharConstant ((char) Value, Location); + } if (target_type == TypeManager.decimal_type) return new DecimalConstant ((decimal) Value, Location); @@ -1646,7 +1741,7 @@ namespace Mono.CSharp { } public class DoubleConstant : Constant { - public readonly double Value; + public double Value; public DoubleConstant (double v, Location loc): base (loc) @@ -1718,32 +1813,44 @@ namespace Mono.CSharp { } } - public override Constant Reduce (EmitContext ec, Type target_type) + public override Constant Reduce (bool inCheckedContext, Type target_type) { if (target_type == TypeManager.byte_type) { - CheckRange (ec, Value, target_type, Byte.MinValue, Byte.MaxValue); + CheckRange (inCheckedContext, Value, Byte.MinValue, Byte.MaxValue); return new ByteConstant ((byte) Value, Location); } if (target_type == TypeManager.sbyte_type) { - CheckRange (ec, Value, target_type, SByte.MinValue, SByte.MaxValue); + CheckRange (inCheckedContext, Value, SByte.MinValue, SByte.MaxValue); return new SByteConstant ((sbyte) Value, Location); } - if (target_type == TypeManager.short_type) + if (target_type == TypeManager.short_type) { + CheckRange (inCheckedContext, Value, short.MinValue, short.MaxValue); return new ShortConstant ((short) Value, Location); - if (target_type == TypeManager.ushort_type) + } + if (target_type == TypeManager.ushort_type) { + CheckRange (inCheckedContext, Value, ushort.MinValue, ushort.MaxValue); return new UShortConstant ((ushort) Value, Location); - if (target_type == TypeManager.int32_type) + } + if (target_type == TypeManager.int32_type) { + CheckRange (inCheckedContext, Value, int.MinValue, int.MaxValue); return new IntConstant ((int) Value, Location); - if (target_type == TypeManager.uint32_type) + } + if (target_type == TypeManager.uint32_type) { + CheckRange (inCheckedContext, Value, uint.MinValue, uint.MaxValue); return new UIntConstant ((uint) Value, Location); - if (target_type == TypeManager.int64_type) + } + if (target_type == TypeManager.int64_type) { + CheckRange (inCheckedContext, Value, long.MinValue, long.MaxValue); return new LongConstant ((long) Value, Location); - if (target_type == TypeManager.uint64_type) + } + if (target_type == TypeManager.uint64_type) { + CheckRange (inCheckedContext, Value, ulong.MinValue, ulong.MaxValue); return new ULongConstant ((ulong) Value, Location); + } if (target_type == TypeManager.float_type) return new FloatConstant ((float) Value, Location); if (target_type == TypeManager.char_type) { - CheckRange (ec, Value, target_type, char.MinValue, char.MaxValue); + CheckRange (inCheckedContext, Value, char.MinValue, char.MaxValue); return new CharConstant ((char) Value, Location); } if (target_type == TypeManager.decimal_type) @@ -1825,7 +1932,7 @@ namespace Mono.CSharp { } } - public override Constant Reduce (EmitContext ec, Type target_type) + public override Constant Reduce (bool inCheckedContext, Type target_type) { if (target_type == TypeManager.sbyte_type) return new SByteConstant ((sbyte)Value, loc); @@ -1902,7 +2009,7 @@ namespace Mono.CSharp { } } - public override Constant Reduce (EmitContext ec, Type target_type) + public override Constant Reduce (bool inCheckedContext, Type target_type) { return null; }