Revert until fixed
[mono.git] / mcs / mcs / constant.cs
index 0f0a580477a720c951b3b203f7d378e0f55f6cb8..76c2c5667a8574a363f163ea62e0f84844823968 100644 (file)
@@ -3,6 +3,7 @@
 //
 // Author:
 //   Miguel de Icaza (miguel@ximian.com)
+//   Marek Safar (marek.safar@seznam.cz)
 //
 // (C) 2001 Ximian, Inc.
 //
@@ -205,6 +206,69 @@ namespace Mono.CSharp {
                        return retval;
                }
 
+               protected void CheckRange (EmitContext ec, ulong value, Type type, ulong max)
+               {
+                       if (!ec.ConstantCheckState)
+                               return;
+
+                       if (value > max)
+                               throw new OverflowException ();
+               }
+
+               protected void CheckRange (EmitContext ec, double value, Type type, long min, long max)
+               {
+                       if (!ec.ConstantCheckState)
+                               return;
+
+                       if (((value < min) || (value > max)))
+                               throw new OverflowException ();
+               }
+
+               protected void CheckUnsigned (EmitContext ec, long value, Type type)
+               {
+                       if (!ec.ConstantCheckState)
+                               return;
+
+                       if (value < 0)
+                               throw new OverflowException ();
+               }
+
+               public abstract Constant Reduce (EmitContext ec, Type target_type);
+
+               /// <summary>
+               ///   Attempts to do a compile-time folding of a constant cast.
+               /// </summary>
+               public Constant TryReduce (EmitContext ec, Type target_type, Location loc)
+               {
+                       try {
+                               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)",
+                                               GetValue ().ToString (), TypeManager.CSharpName (target_type));
+                               }
+                               return null;
+                       }
+               }
+
+               Constant TryReduce (EmitContext ec, Type target_type)
+               {
+                       if (Type == target_type)
+                               return this;
+
+                       if (TypeManager.IsEnumType (target_type)) {
+                               Constant c = TryReduce (ec, TypeManager.EnumToUnderlying (target_type));
+                               if (c == null)
+                                       return null;
+
+                               return new EnumConstant (c, target_type);
+                       }
+
+                       return Reduce (ec, target_type);
+               }
+
+
                public virtual DecimalConstant ConvertToDecimal ()
                {
                        return null;
@@ -310,6 +374,12 @@ namespace Mono.CSharp {
                public override bool IsZeroInteger {
                        get { return Value == false; }
                }
+
+               public override Constant Reduce (EmitContext ec, Type target_type)
+               {
+                       return null;
+               }
+
        }
 
        public class ByteConstant : Constant {
@@ -388,6 +458,37 @@ namespace Mono.CSharp {
                public override bool IsZeroInteger {
                        get { return Value == 0; }
                }
+
+               public override Constant Reduce (EmitContext ec, Type target_type)
+               {
+                       if (target_type == TypeManager.sbyte_type) {
+                               CheckRange (ec, Value, target_type, SByte.MinValue, SByte.MaxValue);
+                               return new SByteConstant ((sbyte) Value, Location);
+                       }
+                       if (target_type == TypeManager.short_type)
+                               return new ShortConstant ((short) Value, Location);
+                       if (target_type == TypeManager.ushort_type)
+                               return new UShortConstant ((ushort) Value, Location);
+                       if (target_type == TypeManager.int32_type)
+                               return new IntConstant ((int) Value, Location);
+                       if (target_type == TypeManager.uint32_type)
+                               return new UIntConstant ((uint) Value, Location);
+                       if (target_type == TypeManager.int64_type)
+                               return new LongConstant ((long) Value, Location);
+                       if (target_type == TypeManager.uint64_type)
+                               return new ULongConstant ((ulong) Value, Location);
+                       if (target_type == TypeManager.float_type)
+                               return new FloatConstant ((float) Value, Location);
+                       if (target_type == TypeManager.double_type)
+                               return new DoubleConstant ((double) Value, Location);
+                       if (target_type == TypeManager.char_type)
+                               return new CharConstant ((char) Value, Location);
+                       if (target_type == TypeManager.decimal_type)
+                               return new DecimalConstant ((decimal) Value, Location);
+
+                       return null;
+               }
+
        }
 
        public class CharConstant : Constant {
@@ -495,6 +596,39 @@ namespace Mono.CSharp {
                public override bool IsZeroInteger {
                        get { return Value == '\0'; }
                }
+
+               public override Constant Reduce (EmitContext ec, Type target_type)
+               {
+                       if (target_type == TypeManager.byte_type) {
+                               CheckRange (ec, Value, target_type, 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);
+                               return new SByteConstant ((sbyte) Value, Location);
+                       }
+                       if (target_type == TypeManager.short_type) {
+                               CheckRange (ec, Value, target_type, Int16.MinValue, Int16.MaxValue);
+                               return new ShortConstant ((short) Value, Location);
+                       }
+                       if (target_type == TypeManager.int32_type)
+                               return new IntConstant ((int) Value, Location);
+                       if (target_type == TypeManager.uint32_type)
+                               return new UIntConstant ((uint) Value, Location);
+                       if (target_type == TypeManager.int64_type)
+                               return new LongConstant ((long) Value, Location);
+                       if (target_type == TypeManager.uint64_type)
+                               return new ULongConstant ((ulong) Value, Location);
+                       if (target_type == TypeManager.float_type)
+                               return new FloatConstant ((float) Value, Location);
+                       if (target_type == TypeManager.double_type)
+                               return new DoubleConstant ((double) Value, Location);
+                       if (target_type == TypeManager.decimal_type)
+                               return new DecimalConstant ((decimal) Value, Location);
+
+                       return null;
+               }
+
        }
 
        public class SByteConstant : Constant {
@@ -576,6 +710,43 @@ namespace Mono.CSharp {
                public override bool IsZeroInteger {
                        get { return Value == 0; }
                }
+
+               public override Constant Reduce (EmitContext ec, Type target_type)
+               {
+                       if (target_type == TypeManager.byte_type) {
+                               CheckUnsigned (ec, Value, target_type);
+                               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);
+                               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);
+                               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);
+                               return new ULongConstant ((ulong) Value, Location);
+                       }
+                       if (target_type == TypeManager.float_type)
+                               return new FloatConstant ((float) Value, Location);
+                       if (target_type == TypeManager.double_type)
+                               return new DoubleConstant ((double) Value, Location);
+                       if (target_type == TypeManager.char_type) {
+                               CheckUnsigned (ec, Value, target_type);
+                               return new CharConstant ((char) Value, Location);
+                       }
+                       if (target_type == TypeManager.decimal_type)
+                               return new DecimalConstant ((decimal) Value, Location);
+
+                       return null;
+               }
+
        }
 
        public class ShortConstant : Constant {
@@ -654,6 +825,47 @@ namespace Mono.CSharp {
                                return Value < 0;
                        }
                }
+
+               public override Constant Reduce (EmitContext ec, Type target_type)
+               {
+                       if (target_type == TypeManager.byte_type) {
+                               CheckRange (ec, Value, target_type, 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);
+                               return new SByteConstant ((sbyte) Value, Location);
+                       }
+                       if (target_type == TypeManager.ushort_type) {
+                               CheckUnsigned (ec, Value, target_type);
+                               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);
+                               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);
+                               return new ULongConstant ((ulong) Value, Location);
+                       }
+                       if (target_type == TypeManager.float_type)
+                               return new FloatConstant ((float) Value, Location);
+                       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);
+                               return new CharConstant ((char) Value, Location);
+                       }
+                       if (target_type == TypeManager.decimal_type)
+                               return new DecimalConstant ((decimal) Value, Location);
+
+                       return null;
+               }
+
        }
 
        public class UShortConstant : Constant {
@@ -732,6 +944,42 @@ namespace Mono.CSharp {
                public override bool IsZeroInteger {
                        get { return Value == 0; }
                }
+
+               public override Constant Reduce (EmitContext ec, Type target_type)
+               {
+                       if (target_type == TypeManager.byte_type) {
+                               CheckRange (ec, Value, target_type, 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);
+                               return new SByteConstant ((sbyte) Value, Location);
+                       }
+                       if (target_type == TypeManager.short_type) {
+                               CheckRange (ec, Value, target_type, Int16.MinValue, Int16.MaxValue);
+                               return new ShortConstant ((short) Value, Location);
+                       }
+                       if (target_type == TypeManager.int32_type)
+                               return new IntConstant ((int) Value, Location);
+                       if (target_type == TypeManager.uint32_type)
+                               return new UIntConstant ((uint) Value, Location);
+                       if (target_type == TypeManager.int64_type)
+                               return new LongConstant ((long) Value, Location);
+                       if (target_type == TypeManager.uint64_type)
+                               return new ULongConstant ((ulong) Value, Location);
+                       if (target_type == TypeManager.float_type)
+                               return new FloatConstant ((float) Value, Location);
+                       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);
+                               return new CharConstant ((char) Value, Location);
+                       }
+                       if (target_type == TypeManager.decimal_type)
+                               return new DecimalConstant ((decimal) Value, Location);
+
+                       return null;
+               }
        }
 
        public class IntConstant : Constant {
@@ -873,6 +1121,48 @@ namespace Mono.CSharp {
                public override bool IsZeroInteger {
                        get { return Value == 0; }
                }
+
+               public override Constant Reduce (EmitContext ec, Type target_type)
+               {
+                       if (target_type == TypeManager.byte_type) {
+                               CheckRange (ec, Value, target_type, 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);
+                               return new SByteConstant ((sbyte) Value, Location);
+                       }
+                       if (target_type == TypeManager.short_type) {
+                               CheckRange (ec, Value, target_type, 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);
+                               return new UShortConstant ((ushort) Value, Location);
+                       }
+                       if (target_type == TypeManager.uint32_type) {
+                               CheckRange (ec, Value, target_type, Int32.MinValue, Int32.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);
+                               return new ULongConstant ((ulong) Value, Location);
+                       }
+                       if (target_type == TypeManager.float_type)
+                               return new FloatConstant ((float) Value, Location);
+                       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);
+                               return new CharConstant ((char) Value, Location);
+                       }
+                       if (target_type == TypeManager.decimal_type)
+                               return new DecimalConstant ((decimal) Value, Location);
+
+                       return null;
+               }
        }
 
        public class UIntConstant : Constant {
@@ -951,6 +1241,47 @@ namespace Mono.CSharp {
                public override bool IsZeroInteger {
                        get { return Value == 0; }
                }
+
+               public override Constant Reduce (EmitContext ec, Type target_type)
+               {
+                       if (target_type == TypeManager.byte_type) {
+                               CheckRange (ec, Value, target_type, 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);
+                               return new SByteConstant ((sbyte) Value, Location);
+                       }
+                       if (target_type == TypeManager.short_type) {
+                               CheckRange (ec, Value, target_type, 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);
+                               return new UShortConstant ((ushort) Value, Location);
+                       }
+                       if (target_type == TypeManager.int32_type) {
+                               CheckRange (ec, Value, target_type, Int32.MinValue, Int32.MaxValue);
+                               return new IntConstant ((int) Value, Location);
+                       }
+                       if (target_type == TypeManager.int64_type)
+                               return new LongConstant ((long) Value, Location);
+                       if (target_type == TypeManager.uint64_type)
+                               return new ULongConstant ((ulong) Value, Location);
+                       if (target_type == TypeManager.float_type)
+                               return new FloatConstant ((float) Value, Location);
+                       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);
+                               return new CharConstant ((char) Value, Location);
+                       }
+                       if (target_type == TypeManager.decimal_type)
+                               return new DecimalConstant ((decimal) Value, Location);
+
+                       return null;
+               }
+
        }
 
        public class LongConstant : Constant {
@@ -1044,6 +1375,51 @@ namespace Mono.CSharp {
                public override bool IsZeroInteger {
                        get { return Value == 0; }
                }
+
+               public override Constant Reduce (EmitContext ec, Type target_type)
+               {
+                       if (target_type == TypeManager.byte_type) {
+                               CheckRange (ec, Value, target_type, 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);
+                               return new SByteConstant ((sbyte) Value, Location);
+                       }
+                       if (target_type == TypeManager.short_type) {
+                               CheckRange (ec, Value, target_type, 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);
+                               return new UShortConstant ((ushort) Value, Location);
+                       }
+                       if (target_type == TypeManager.int32_type) {
+                               CheckRange (ec, Value, target_type, 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);
+                               return new UIntConstant ((uint) Value, Location);
+                       }
+                       if (target_type == TypeManager.uint64_type) {
+                               CheckUnsigned (ec, Value, target_type);
+                               return new ULongConstant ((ulong) Value, Location);
+                       }
+                       if (target_type == TypeManager.float_type)
+                               return new FloatConstant ((float) Value, Location);
+                       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);
+                               return new CharConstant ((char) Value, Location);
+                       }
+                       if (target_type == TypeManager.decimal_type)
+                               return new DecimalConstant ((decimal) Value, Location);
+
+                       return null;
+               }
+
        }
 
        public class ULongConstant : Constant {
@@ -1124,6 +1500,51 @@ namespace Mono.CSharp {
                public override bool IsZeroInteger {
                        get { return Value == 0; }
                }
+
+               public override Constant Reduce (EmitContext ec, Type target_type)
+               {
+                       if (target_type == TypeManager.byte_type) {
+                               CheckRange (ec, Value, target_type, Byte.MaxValue);
+                               return new ByteConstant ((byte) Value, Location);
+                       }
+                       if (target_type == TypeManager.sbyte_type) {
+                               CheckRange (ec, Value, target_type, (ulong) SByte.MaxValue);
+                               return new SByteConstant ((sbyte) Value, Location);
+                       }
+                       if (target_type == TypeManager.short_type) {
+                               CheckRange (ec, Value, target_type, (ulong) Int16.MaxValue);
+                               return new ShortConstant ((short) Value, Location);
+                       }
+                       if (target_type == TypeManager.ushort_type) {
+                               CheckRange (ec, Value, target_type, UInt16.MaxValue);
+                               return new UShortConstant ((ushort) Value, Location);
+                       }
+                       if (target_type == TypeManager.int32_type) {
+                               CheckRange (ec, Value, target_type, Int32.MaxValue);
+                               return new IntConstant ((int) Value, Location);
+                       }
+                       if (target_type == TypeManager.uint32_type) {
+                               CheckRange (ec, Value, target_type, UInt32.MaxValue);
+                               return new UIntConstant ((uint) Value, Location);
+                       }
+                       if (target_type == TypeManager.int64_type) {
+                               CheckRange (ec, Value, target_type, (ulong) Int64.MaxValue);
+                               return new LongConstant ((long) Value, Location);
+                       }
+                       if (target_type == TypeManager.float_type)
+                               return new FloatConstant ((float) Value, Location);
+                       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);
+                               return new CharConstant ((char) Value, Location);
+                       }
+                       if (target_type == TypeManager.decimal_type)
+                               return new DecimalConstant ((decimal) Value, Location);
+
+                       return null;
+               }
+
        }
 
        public class FloatConstant : Constant {
@@ -1193,6 +1614,35 @@ namespace Mono.CSharp {
                                return Value < 0;
                        }
                }
+
+               public override Constant Reduce (EmitContext ec, Type target_type)
+               {
+                       if (target_type == TypeManager.byte_type)
+                               return new ByteConstant ((byte) Value, Location);
+                       if (target_type == TypeManager.sbyte_type)
+                               return new SByteConstant ((sbyte) Value, Location);
+                       if (target_type == TypeManager.short_type)
+                               return new ShortConstant ((short) Value, Location);
+                       if (target_type == TypeManager.ushort_type)
+                               return new UShortConstant ((ushort) Value, Location);
+                       if (target_type == TypeManager.int32_type)
+                               return new IntConstant ((int) Value, Location);
+                       if (target_type == TypeManager.uint32_type)
+                               return new UIntConstant ((uint) Value, Location);
+                       if (target_type == TypeManager.int64_type)
+                               return new LongConstant ((long) Value, Location);
+                       if (target_type == TypeManager.uint64_type)
+                               return new ULongConstant ((ulong) Value, Location);
+                       if (target_type == TypeManager.double_type)
+                               return new DoubleConstant ((double) Value, Location);
+                       if (target_type == TypeManager.char_type)
+                               return new CharConstant ((char) Value, Location);
+                       if (target_type == TypeManager.decimal_type)
+                               return new DecimalConstant ((decimal) Value, Location);
+
+                       return null;
+               }
+
        }
 
        public class DoubleConstant : Constant {
@@ -1267,6 +1717,41 @@ namespace Mono.CSharp {
                                return Value < 0;
                        }
                }
+
+               public override Constant Reduce (EmitContext ec, Type target_type)
+               {
+                       if (target_type == TypeManager.byte_type) {
+                               CheckRange (ec, Value, target_type, 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);
+                               return new SByteConstant ((sbyte) Value, Location);
+                       }
+                       if (target_type == TypeManager.short_type)
+                               return new ShortConstant ((short) Value, Location);
+                       if (target_type == TypeManager.ushort_type)
+                               return new UShortConstant ((ushort) Value, Location);
+                       if (target_type == TypeManager.int32_type)
+                               return new IntConstant ((int) Value, Location);
+                       if (target_type == TypeManager.uint32_type)
+                               return new UIntConstant ((uint) Value, Location);
+                       if (target_type == TypeManager.int64_type)
+                               return new LongConstant ((long) Value, Location);
+                       if (target_type == TypeManager.uint64_type)
+                               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);
+                               return new CharConstant ((char) Value, Location);
+                       }
+                       if (target_type == TypeManager.decimal_type)
+                               return new DecimalConstant ((decimal) Value, Location);
+
+                       return null;
+               }
+
        }
 
        public class DecimalConstant : Constant {
@@ -1339,6 +1824,35 @@ namespace Mono.CSharp {
                                return Value < 0;
                        }
                }
+
+               public override Constant Reduce (EmitContext ec, Type target_type)
+               {
+                       if (target_type == TypeManager.sbyte_type)
+                               return new SByteConstant ((sbyte)Value, loc);
+                       if (target_type == TypeManager.byte_type)
+                               return new ByteConstant ((byte)Value, loc);
+                       if (target_type == TypeManager.short_type)
+                               return new ShortConstant ((short)Value, loc);
+                       if (target_type == TypeManager.ushort_type)
+                               return new UShortConstant ((ushort)Value, loc);
+                       if (target_type == TypeManager.int32_type)
+                               return new IntConstant ((int)Value, loc);
+                       if (target_type == TypeManager.uint32_type)
+                               return new UIntConstant ((uint)Value, loc);
+                       if (target_type == TypeManager.int64_type)
+                               return new LongConstant ((long)Value, loc);
+                       if (target_type == TypeManager.uint64_type)
+                               return new ULongConstant ((ulong)Value, loc);
+                       if (target_type == TypeManager.char_type)
+                               return new CharConstant ((char)Value, loc);
+                       if (target_type == TypeManager.float_type)
+                               return new FloatConstant ((float)Value, loc);
+                       if (target_type == TypeManager.double_type)
+                               return new DoubleConstant ((double)Value, loc);
+
+                       return null;
+               }
+
        }
 
        public class StringConstant : Constant {
@@ -1387,6 +1901,11 @@ namespace Mono.CSharp {
                                return false;
                        }
                }
+
+               public override Constant Reduce (EmitContext ec, Type target_type)
+               {
+                       return null;
+               }
        }
 
 }