Revert this patch as it breaks mscorlib and System.Web's test compilation
authorMiguel de Icaza <miguel@gnome.org>
Tue, 18 Oct 2005 01:32:46 +0000 (01:32 -0000)
committerMiguel de Icaza <miguel@gnome.org>
Tue, 18 Oct 2005 01:32:46 +0000 (01:32 -0000)
svn path=/trunk/mcs/; revision=51846

mcs/mcs/ChangeLog
mcs/mcs/cfold.cs
mcs/mcs/class.cs
mcs/mcs/constant.cs
mcs/mcs/ecore.cs
mcs/mcs/expression.cs
mcs/mcs/literal.cs
mcs/mcs/rootcontext.cs

index 9502b91ffafd32242f467abd4051f6ae1787c40d..74a7b0c8f55c74b09ace620a9638731deac2d70a 100644 (file)
@@ -1,16 +1,3 @@
-2005-10-17  Marek Safar  <marek.safar@seznam.cz>
-
-       Fix #76273.
-       * cfold.cs (BinaryFold): Reduce constant in enum conversion.
-       
-       * constant.cs (Constant.TryReduce): Moved from Cast class.
-       (Reduce): Made little bit more OO and fixed missing conversions.
-       
-       * ecore.cs (Reduce): Implemented.
-       (Binary.EnumLiftUp): New method to upgrade values to enum values.
-       
-       * literal.cs (Reduce): Implemented.
-
 2005-10-14  Miguel de Icaza  <miguel@novell.com>
 
        * ecore.cs (GetMemberType): Report the correct mapping for the MemberCore
index 9e8a5a1a6293a1de740c20cb86e3fc3ef0ebbc6d..4b09e39b5e93f250a67a346de5ac9843f10081ff 100644 (file)
@@ -141,6 +141,33 @@ namespace Mono.CSharp {
                                        right = right.ToDecimal (loc);
                                return;
                        } else if (left is EnumConstant || right is EnumConstant){
+                               //
+                               // If either operand is an enum constant, the other one must
+                               // be implicitly convertable to that enum's underlying type.
+                               //
+                               EnumConstant match;
+                               Constant other;
+                               if (left is EnumConstant){
+                                       other = right;
+                                       match = (EnumConstant) left;
+                               } else {
+                                       other = left;
+                                       match = (EnumConstant) right;
+                               }
+
+                               bool need_check = (other is EnumConstant) ||
+                                       !(oper == Binary.Operator.Addition || 
+                                         oper == Binary.Operator.Subtraction ||
+                                         (other.IsZeroInteger && other is IntConstant));
+
+                               if (need_check &&
+                                   !Convert.ImplicitConversionExists (ec, match, other.Type)) {
+                                       match.Error_ValueCannotBeConverted (loc, other.Type, false);
+                                       left = null;
+                                       right = null;
+                                       return;
+                               }
+
                                if (left is EnumConstant)
                                        left = ((EnumConstant) left).Child;
                                if (right is EnumConstant)
@@ -528,7 +555,7 @@ namespace Mono.CSharp {
                                }
 
                                if (wrap_as != null)
-                                       return result.TryReduce (ec, wrap_as, loc);
+                                       return new EnumConstant (result, wrap_as);
                                else
                                        return result;
 
@@ -658,11 +685,10 @@ namespace Mono.CSharp {
                                } catch (OverflowException){
                                        Error_CompileTimeOverflow (loc);
                                }
-
                                if (wrap_as != null)
-                                       return result.TryReduce (ec, wrap_as, loc);
-
-                               return result;
+                                       return new EnumConstant (result, wrap_as);
+                               else
+                                       return result;
                                
                        case Binary.Operator.Multiply:
                                DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
index d133ef8e08b1ad08b89d791fd6f6103438f7ca40..ff9480d5249974f506c6792366f8eb459b9ab9f3 100644 (file)
@@ -1279,14 +1279,6 @@ namespace Mono.CSharp {
                                TypeBuilder.SetParent (ptype);
                        }
 
-                       // Attribute is undefined at the begining of corlib compilation
-                       if (TypeManager.obsolete_attribute_type != null) {
-                               TypeResolveEmitContext.TestObsoleteMethodUsage = GetObsoleteAttribute () == null;
-                               if (ptype != null && TypeResolveEmitContext.TestObsoleteMethodUsage) {
-                                       CheckObsoleteType (base_type);
-                               }
-                       }
-
                        // add interfaces that were not added at type creation
                        if (iface_exprs != null) {
                                // FIXME: I think this should be ...ExpandInterfaces (Parent.EmitContext, ...).
@@ -1307,6 +1299,14 @@ namespace Mono.CSharp {
                        if (!(this is Iterator))
                                RootContext.RegisterOrder (this); 
 
+                       // Attribute is undefined at the begining of corlib compilation
+                       if (TypeManager.obsolete_attribute_type != null) {
+                               TypeResolveEmitContext.TestObsoleteMethodUsage = GetObsoleteAttribute () == null;
+                               if (ptype != null && TypeResolveEmitContext.TestObsoleteMethodUsage) {
+                                       CheckObsoleteType (base_type);
+                               }
+                       }
+
                        if (!DefineNestedTypes ()) {
                                error = true;
                                return null;
index 18ca2dd7bdd3d8f57defbfb04817b737b351abec..0f0a580477a720c951b3b203f7d378e0f55f6cb8 100644 (file)
@@ -3,7 +3,6 @@
 //
 // Author:
 //   Miguel de Icaza (miguel@ximian.com)
-//   Marek Safar (marek.safar@seznam.cz)
 //
 // (C) 2001 Ximian, Inc.
 //
@@ -206,69 +205,6 @@ 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)",
-                                               this.GetValue (), 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;
@@ -374,12 +310,6 @@ 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 {
@@ -458,37 +388,6 @@ 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 {
@@ -596,39 +495,6 @@ 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 {
@@ -710,43 +576,6 @@ 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 {
@@ -825,47 +654,6 @@ 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 {
@@ -944,42 +732,6 @@ 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 {
@@ -1121,48 +873,6 @@ 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 {
@@ -1241,47 +951,6 @@ 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 {
@@ -1375,51 +1044,6 @@ 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 {
@@ -1500,51 +1124,6 @@ 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 {
@@ -1614,35 +1193,6 @@ 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 {
@@ -1717,41 +1267,6 @@ 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 {
@@ -1824,35 +1339,6 @@ 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 {
@@ -1901,11 +1387,6 @@ namespace Mono.CSharp {
                                return false;
                        }
                }
-
-               public override Constant Reduce (EmitContext ec, Type target_type)
-               {
-                       return null;
-               }
        }
 
 }
index 9a87d90af9a7b70c6be20d75eafcae904a4b7cd4..53fe57b285cc4c163c4637d9ab1858086b84dee8 100644 (file)
@@ -1298,12 +1298,6 @@ namespace Mono.CSharp {
                                return false;
                        }
                }
-
-               public override Constant Reduce (EmitContext ec, Type target_type)
-               {
-                       throw new NotImplementedException ();
-               }
-
        }
 
 
@@ -1410,14 +1404,6 @@ namespace Mono.CSharp {
                        }
                }
 
-               public override Constant Reduce(EmitContext ec, Type target_type)
-               {
-                       if (Child.Type == target_type)
-                               return Child;
-
-                       return Child.Reduce (ec, target_type);
-               }
-
                public override Constant ToType (Type type, Location loc)
                {
                        if (Type == type) {
index 68903cf59ee086eda4d74f4c5c4149ff5c9347d4..2ee172d001813ec091a98264180f0d6664de8222 100644 (file)
@@ -1290,6 +1290,503 @@ namespace Mono.CSharp {
                                expr = value;
                        }
                }
+
+               bool CheckRange (EmitContext ec, long value, Type type, long min, long max)
+               {
+                       if (!ec.ConstantCheckState)
+                               return true;
+
+                       if ((value < min) || (value > max)) {
+                               Error (221, "Constant value `" + value + "' cannot be converted " +
+                                      "to a `" + TypeManager.CSharpName (type) + "' (use `unchecked' " +
+                                      "syntax to override)");
+                               return false;
+                       }
+
+                       return true;
+               }
+
+               bool CheckRange (EmitContext ec, ulong value, Type type, ulong max)
+               {
+                       if (!ec.ConstantCheckState)
+                               return true;
+
+                       if (value > max) {
+                               Error (221, "Constant value `" + value + "' cannot be converted " +
+                                      "to a `" + TypeManager.CSharpName (type) + "' (use `unchecked' " +
+                                      "syntax to override)");
+                               return false;
+                       }
+
+                       return true;
+               }
+
+               bool CheckUnsigned (EmitContext ec, long value, Type type)
+               {
+                       if (!ec.ConstantCheckState)
+                               return true;
+
+                       if (value < 0) {
+                               Error (221, "Constant value `" + value + "' cannot be converted " +
+                                      "to a `" + TypeManager.CSharpName (type) + "' (use `unchecked' " +
+                                      "syntax to override)");
+                               return false;
+                       }
+
+                       return true;
+               }
+
+               // TODO: move to constant
+               /// <summary>
+               ///   Attempts to do a compile-time folding of a constant cast.
+               /// </summary>
+               Expression TryReduce (EmitContext ec, Type target_type)
+               {
+                       if (expr.Type == target_type)
+                               return expr;
+
+                       if (TypeManager.IsEnumType (target_type) && TypeManager.EnumToUnderlying (target_type) == expr.Type)
+                               return new EnumConstant ((Constant)expr, target_type);
+
+                       Expression real_expr = expr;
+                       if (real_expr is EnumConstant)
+                               real_expr = ((EnumConstant) real_expr).Child;
+
+                       if (real_expr is ByteConstant){
+                               byte v = ((ByteConstant) real_expr).Value;
+       
+                               if (target_type == TypeManager.sbyte_type) {
+                                       if (!CheckRange (ec, v, target_type, SByte.MinValue, SByte.MaxValue))
+                                               return null;
+                                       return new SByteConstant ((sbyte) v, real_expr.Location);
+                               }
+                               if (target_type == TypeManager.short_type)
+                                       return new ShortConstant ((short) v, real_expr.Location);
+                               if (target_type == TypeManager.ushort_type)
+                                       return new UShortConstant ((ushort) v, real_expr.Location);
+                               if (target_type == TypeManager.int32_type)
+                                       return new IntConstant ((int) v, real_expr.Location);
+                               if (target_type == TypeManager.uint32_type)
+                                       return new UIntConstant ((uint) v, real_expr.Location);
+                               if (target_type == TypeManager.int64_type)
+                                       return new LongConstant ((long) v, real_expr.Location);
+                               if (target_type == TypeManager.uint64_type)
+                                       return new ULongConstant ((ulong) v, real_expr.Location);
+                               if (target_type == TypeManager.float_type)
+                                       return new FloatConstant ((float) v, real_expr.Location);
+                               if (target_type == TypeManager.double_type)
+                                       return new DoubleConstant ((double) v, real_expr.Location);
+                               if (target_type == TypeManager.char_type)
+                                       return new CharConstant ((char) v, real_expr.Location);
+                               if (target_type == TypeManager.decimal_type)
+                                       return new DecimalConstant ((decimal) v, real_expr.Location);
+                       }
+                       if (real_expr is SByteConstant){
+                               sbyte v = ((SByteConstant) real_expr).Value;
+       
+                               if (target_type == TypeManager.byte_type) {
+                                       if (!CheckUnsigned (ec, v, target_type))
+                                               return null;
+                                       return new ByteConstant ((byte) v, real_expr.Location);
+                               }
+                               if (target_type == TypeManager.short_type)
+                                       return new ShortConstant ((short) v, real_expr.Location);
+                               if (target_type == TypeManager.ushort_type) {
+                                       if (!CheckUnsigned (ec, v, target_type))
+                                               return null;
+                                       return new UShortConstant ((ushort) v, real_expr.Location);
+                               } if (target_type == TypeManager.int32_type)
+                                       return new IntConstant ((int) v, real_expr.Location);
+                               if (target_type == TypeManager.uint32_type) {
+                                       if (!CheckUnsigned (ec, v, target_type))
+                                               return null;
+                                       return new UIntConstant ((uint) v, real_expr.Location);
+                               } if (target_type == TypeManager.int64_type)
+                                       return new LongConstant ((long) v, real_expr.Location);
+                               if (target_type == TypeManager.uint64_type) {
+                                       if (!CheckUnsigned (ec, v, target_type))
+                                               return null;
+                                       return new ULongConstant ((ulong) v, real_expr.Location);
+                               }
+                               if (target_type == TypeManager.float_type)
+                                       return new FloatConstant ((float) v, real_expr.Location);
+                               if (target_type == TypeManager.double_type)
+                                       return new DoubleConstant ((double) v, real_expr.Location);
+                               if (target_type == TypeManager.char_type) {
+                                       if (!CheckUnsigned (ec, v, target_type))
+                                               return null;
+                                       return new CharConstant ((char) v, real_expr.Location);
+                               }
+                               if (target_type == TypeManager.decimal_type)
+                                       return new DecimalConstant ((decimal) v, real_expr.Location);
+                       }
+                       if (real_expr is ShortConstant){
+                               short v = ((ShortConstant) real_expr).Value;
+       
+                               if (target_type == TypeManager.byte_type) {
+                                       if (!CheckRange (ec, v, target_type, Byte.MinValue, Byte.MaxValue))
+                                               return null;
+                                       return new ByteConstant ((byte) v, real_expr.Location);
+                               }
+                               if (target_type == TypeManager.sbyte_type) {
+                                       if (!CheckRange (ec, v, target_type, SByte.MinValue, SByte.MaxValue))
+                                               return null;
+                                       return new SByteConstant ((sbyte) v, real_expr.Location);
+                               }
+                               if (target_type == TypeManager.ushort_type) {
+                                       if (!CheckUnsigned (ec, v, target_type))
+                                               return null;
+                                       return new UShortConstant ((ushort) v, real_expr.Location);
+                               }
+                               if (target_type == TypeManager.int32_type)
+                                       return new IntConstant ((int) v, real_expr.Location);
+                               if (target_type == TypeManager.uint32_type) {
+                                       if (!CheckUnsigned (ec, v, target_type))
+                                               return null;
+                                       return new UIntConstant ((uint) v, real_expr.Location);
+                               }
+                               if (target_type == TypeManager.int64_type)
+                                       return new LongConstant ((long) v, real_expr.Location);
+                               if (target_type == TypeManager.uint64_type) {
+                                       if (!CheckUnsigned (ec, v, target_type))
+                                               return null;
+                                       return new ULongConstant ((ulong) v, real_expr.Location);
+                               }
+                               if (target_type == TypeManager.float_type)
+                                       return new FloatConstant ((float) v, real_expr.Location);
+                               if (target_type == TypeManager.double_type)
+                                       return new DoubleConstant ((double) v, real_expr.Location);
+                               if (target_type == TypeManager.char_type) {
+                                       if (!CheckRange (ec, v, target_type, Char.MinValue, Char.MaxValue))
+                                               return null;
+                                       return new CharConstant ((char) v, real_expr.Location);
+                               }
+                               if (target_type == TypeManager.decimal_type)
+                                       return new DecimalConstant ((decimal) v, real_expr.Location);
+                       }
+                       if (real_expr is UShortConstant){
+                               ushort v = ((UShortConstant) real_expr).Value;
+       
+                               if (target_type == TypeManager.byte_type) {
+                                       if (!CheckRange (ec, v, target_type, Byte.MinValue, Byte.MaxValue))
+                                               return null;
+                                       return new ByteConstant ((byte) v, real_expr.Location);
+                               }
+                               if (target_type == TypeManager.sbyte_type) {
+                                       if (!CheckRange (ec, v, target_type, SByte.MinValue, SByte.MaxValue))
+                                               return null;
+                                       return new SByteConstant ((sbyte) v, real_expr.Location);
+                               }
+                               if (target_type == TypeManager.short_type) {
+                                       if (!CheckRange (ec, v, target_type, Int16.MinValue, Int16.MaxValue))
+                                               return null;
+                                       return new ShortConstant ((short) v, real_expr.Location);
+                               }
+                               if (target_type == TypeManager.int32_type)
+                                       return new IntConstant ((int) v, real_expr.Location);
+                               if (target_type == TypeManager.uint32_type)
+                                       return new UIntConstant ((uint) v, real_expr.Location);
+                               if (target_type == TypeManager.int64_type)
+                                       return new LongConstant ((long) v, real_expr.Location);
+                               if (target_type == TypeManager.uint64_type)
+                                       return new ULongConstant ((ulong) v, real_expr.Location);
+                               if (target_type == TypeManager.float_type)
+                                       return new FloatConstant ((float) v, real_expr.Location);
+                               if (target_type == TypeManager.double_type)
+                                       return new DoubleConstant ((double) v, real_expr.Location);
+                               if (target_type == TypeManager.char_type) {
+                                       if (!CheckRange (ec, v, target_type, Char.MinValue, Char.MaxValue))
+                                               return null;
+                                       return new CharConstant ((char) v, real_expr.Location);
+                               }
+                               if (target_type == TypeManager.decimal_type)
+                                       return new DecimalConstant ((decimal) v, real_expr.Location);
+                       }
+                       if (real_expr is IntConstant){
+                               int v = ((IntConstant) real_expr).Value;
+       
+                               if (target_type == TypeManager.byte_type) {
+                                       if (!CheckRange (ec, v, target_type, Byte.MinValue, Byte.MaxValue))
+                                               return null;
+                                       return new ByteConstant ((byte) v, real_expr.Location);
+                               }
+                               if (target_type == TypeManager.sbyte_type) {
+                                       if (!CheckRange (ec, v, target_type, SByte.MinValue, SByte.MaxValue))
+                                               return null;
+                                       return new SByteConstant ((sbyte) v, real_expr.Location);
+                               }
+                               if (target_type == TypeManager.short_type) {
+                                       if (!CheckRange (ec, v, target_type, Int16.MinValue, Int16.MaxValue))
+                                               return null;
+                                       return new ShortConstant ((short) v, real_expr.Location);
+                               }
+                               if (target_type == TypeManager.ushort_type) {
+                                       if (!CheckRange (ec, v, target_type, UInt16.MinValue, UInt16.MaxValue))
+                                               return null;
+                                       return new UShortConstant ((ushort) v, real_expr.Location);
+                               }
+                               if (target_type == TypeManager.uint32_type) {
+                                       if (!CheckRange (ec, v, target_type, Int32.MinValue, Int32.MaxValue))
+                                               return null;
+                                       return new UIntConstant ((uint) v, real_expr.Location);
+                               }
+                               if (target_type == TypeManager.int64_type)
+                                       return new LongConstant ((long) v, real_expr.Location);
+                               if (target_type == TypeManager.uint64_type) {
+                                       if (!CheckUnsigned (ec, v, target_type))
+                                               return null;
+                                       return new ULongConstant ((ulong) v, real_expr.Location);
+                               }
+                               if (target_type == TypeManager.float_type)
+                                       return new FloatConstant ((float) v, real_expr.Location);
+                               if (target_type == TypeManager.double_type)
+                                       return new DoubleConstant ((double) v, real_expr.Location);
+                               if (target_type == TypeManager.char_type) {
+                                       if (!CheckRange (ec, v, target_type, Char.MinValue, Char.MaxValue))
+                                               return null;
+                                       return new CharConstant ((char) v, real_expr.Location);
+                               }
+                               if (target_type == TypeManager.decimal_type)
+                                       return new DecimalConstant ((decimal) v, real_expr.Location);
+                       }
+                       if (real_expr is UIntConstant){
+                               uint v = ((UIntConstant) real_expr).Value;
+       
+                               if (target_type == TypeManager.byte_type) {
+                                       if (!CheckRange (ec, v, target_type, Char.MinValue, Char.MaxValue))
+                                               return null;
+                                       return new ByteConstant ((byte) v, real_expr.Location);
+                               }
+                               if (target_type == TypeManager.sbyte_type) {
+                                       if (!CheckRange (ec, v, target_type, SByte.MinValue, SByte.MaxValue))
+                                               return null;
+                                       return new SByteConstant ((sbyte) v, real_expr.Location);
+                               }
+                               if (target_type == TypeManager.short_type) {
+                                       if (!CheckRange (ec, v, target_type, Int16.MinValue, Int16.MaxValue))
+                                               return null;
+                                       return new ShortConstant ((short) v, real_expr.Location);
+                               }
+                               if (target_type == TypeManager.ushort_type) {
+                                       if (!CheckRange (ec, v, target_type, UInt16.MinValue, UInt16.MaxValue))
+                                               return null;
+                                       return new UShortConstant ((ushort) v, real_expr.Location);
+                               }
+                               if (target_type == TypeManager.int32_type) {
+                                       if (!CheckRange (ec, v, target_type, Int32.MinValue, Int32.MaxValue))
+                                               return null;
+                                       return new IntConstant ((int) v, real_expr.Location);
+                               }
+                               if (target_type == TypeManager.int64_type)
+                                       return new LongConstant ((long) v, real_expr.Location);
+                               if (target_type == TypeManager.uint64_type)
+                                       return new ULongConstant ((ulong) v, real_expr.Location);
+                               if (target_type == TypeManager.float_type)
+                                       return new FloatConstant ((float) v, real_expr.Location);
+                               if (target_type == TypeManager.double_type)
+                                       return new DoubleConstant ((double) v, real_expr.Location);
+                               if (target_type == TypeManager.char_type) {
+                                       if (!CheckRange (ec, v, target_type, Char.MinValue, Char.MaxValue))
+                                               return null;
+                                       return new CharConstant ((char) v, real_expr.Location);
+                               }
+                               if (target_type == TypeManager.decimal_type)
+                                       return new DecimalConstant ((decimal) v, real_expr.Location);
+                       }
+                       if (real_expr is LongConstant){
+                               long v = ((LongConstant) real_expr).Value;
+       
+                               if (target_type == TypeManager.byte_type) {
+                                       if (!CheckRange (ec, v, target_type, Byte.MinValue, Byte.MaxValue))
+                                               return null;
+                                       return new ByteConstant ((byte) v, real_expr.Location);
+                               }
+                               if (target_type == TypeManager.sbyte_type) {
+                                       if (!CheckRange (ec, v, target_type, SByte.MinValue, SByte.MaxValue))
+                                               return null;
+                                       return new SByteConstant ((sbyte) v, real_expr.Location);
+                               }
+                               if (target_type == TypeManager.short_type) {
+                                       if (!CheckRange (ec, v, target_type, Int16.MinValue, Int16.MaxValue))
+                                               return null;
+                                       return new ShortConstant ((short) v, real_expr.Location);
+                               }
+                               if (target_type == TypeManager.ushort_type) {
+                                       if (!CheckRange (ec, v, target_type, UInt16.MinValue, UInt16.MaxValue))
+                                               return null;
+                                       return new UShortConstant ((ushort) v, real_expr.Location);
+                               }
+                               if (target_type == TypeManager.int32_type) {
+                                       if (!CheckRange (ec, v, target_type, Int32.MinValue, Int32.MaxValue))
+                                               return null;
+                                       return new IntConstant ((int) v, real_expr.Location);
+                               }
+                               if (target_type == TypeManager.uint32_type) {
+                                       if (!CheckRange (ec, v, target_type, UInt32.MinValue, UInt32.MaxValue))
+                                               return null;
+                                       return new UIntConstant ((uint) v, real_expr.Location);
+                               }
+                               if (target_type == TypeManager.uint64_type) {
+                                       if (!CheckUnsigned (ec, v, target_type))
+                                               return null;
+                                       return new ULongConstant ((ulong) v, real_expr.Location);
+                               }
+                               if (target_type == TypeManager.float_type)
+                                       return new FloatConstant ((float) v, real_expr.Location);
+                               if (target_type == TypeManager.double_type)
+                                       return new DoubleConstant ((double) v, real_expr.Location);
+                               if (target_type == TypeManager.char_type) {
+                                       if (!CheckRange (ec, v, target_type, Char.MinValue, Char.MaxValue))
+                                               return null;
+                                       return new CharConstant ((char) v, real_expr.Location);
+                               }
+                               if (target_type == TypeManager.decimal_type)
+                                       return new DecimalConstant ((decimal) v, real_expr.Location);
+                       }
+                       if (real_expr is ULongConstant){
+                               ulong v = ((ULongConstant) real_expr).Value;
+       
+                               if (target_type == TypeManager.byte_type) {
+                                       if (!CheckRange (ec, v, target_type, Byte.MaxValue))
+                                               return null;
+                                       return new ByteConstant ((byte) v, real_expr.Location);
+                               }
+                               if (target_type == TypeManager.sbyte_type) {
+                                       if (!CheckRange (ec, v, target_type, (ulong) SByte.MaxValue))
+                                               return null;
+                                       return new SByteConstant ((sbyte) v, real_expr.Location);
+                               }
+                               if (target_type == TypeManager.short_type) {
+                                       if (!CheckRange (ec, v, target_type, (ulong) Int16.MaxValue))
+                                               return null;
+                                       return new ShortConstant ((short) v, real_expr.Location);
+                               }
+                               if (target_type == TypeManager.ushort_type) {
+                                       if (!CheckRange (ec, v, target_type, UInt16.MaxValue))
+                                               return null;
+                                       return new UShortConstant ((ushort) v, real_expr.Location);
+                               }
+                               if (target_type == TypeManager.int32_type) {
+                                       if (!CheckRange (ec, v, target_type, Int32.MaxValue))
+                                               return null;
+                                       return new IntConstant ((int) v, real_expr.Location);
+                               }
+                               if (target_type == TypeManager.uint32_type) {
+                                       if (!CheckRange (ec, v, target_type, UInt32.MaxValue))
+                                               return null;
+                                       return new UIntConstant ((uint) v, real_expr.Location);
+                               }
+                               if (target_type == TypeManager.int64_type) {
+                                       if (!CheckRange (ec, v, target_type, (ulong) Int64.MaxValue))
+                                               return null;
+                                       return new LongConstant ((long) v, real_expr.Location);
+                               }
+                               if (target_type == TypeManager.float_type)
+                                       return new FloatConstant ((float) v, real_expr.Location);
+                               if (target_type == TypeManager.double_type)
+                                       return new DoubleConstant ((double) v, real_expr.Location);
+                               if (target_type == TypeManager.char_type) {
+                                       if (!CheckRange (ec, v, target_type, Char.MaxValue))
+                                               return null;
+                                       return new CharConstant ((char) v, real_expr.Location);
+                               }
+                               if (target_type == TypeManager.decimal_type)
+                                       return new DecimalConstant ((decimal) v, real_expr.Location);
+                       }
+                       if (real_expr is FloatConstant){
+                               float v = ((FloatConstant) real_expr).Value;
+       
+                               if (target_type == TypeManager.byte_type)
+                                       return new ByteConstant ((byte) v, real_expr.Location);
+                               if (target_type == TypeManager.sbyte_type)
+                                       return new SByteConstant ((sbyte) v, real_expr.Location);
+                               if (target_type == TypeManager.short_type)
+                                       return new ShortConstant ((short) v, real_expr.Location);
+                               if (target_type == TypeManager.ushort_type)
+                                       return new UShortConstant ((ushort) v, real_expr.Location);
+                               if (target_type == TypeManager.int32_type)
+                                       return new IntConstant ((int) v, real_expr.Location);
+                               if (target_type == TypeManager.uint32_type)
+                                       return new UIntConstant ((uint) v, real_expr.Location);
+                               if (target_type == TypeManager.int64_type)
+                                       return new LongConstant ((long) v, real_expr.Location);
+                               if (target_type == TypeManager.uint64_type)
+                                       return new ULongConstant ((ulong) v, real_expr.Location);
+                               if (target_type == TypeManager.double_type)
+                                       return new DoubleConstant ((double) v, real_expr.Location);
+                               if (target_type == TypeManager.char_type)
+                                       return new CharConstant ((char) v, real_expr.Location);
+                               if (target_type == TypeManager.decimal_type)
+                                       return new DecimalConstant ((decimal) v, real_expr.Location);
+                       }
+                       if (real_expr is DoubleConstant){
+                               double v = ((DoubleConstant) real_expr).Value;
+       
+                               if (target_type == TypeManager.byte_type){
+                                       return new ByteConstant ((byte) v, real_expr.Location);
+                               } if (target_type == TypeManager.sbyte_type)
+                                       return new SByteConstant ((sbyte) v, real_expr.Location);
+                               if (target_type == TypeManager.short_type)
+                                       return new ShortConstant ((short) v, real_expr.Location);
+                               if (target_type == TypeManager.ushort_type)
+                                       return new UShortConstant ((ushort) v, real_expr.Location);
+                               if (target_type == TypeManager.int32_type)
+                                       return new IntConstant ((int) v, real_expr.Location);
+                               if (target_type == TypeManager.uint32_type)
+                                       return new UIntConstant ((uint) v, real_expr.Location);
+                               if (target_type == TypeManager.int64_type)
+                                       return new LongConstant ((long) v, real_expr.Location);
+                               if (target_type == TypeManager.uint64_type)
+                                       return new ULongConstant ((ulong) v, real_expr.Location);
+                               if (target_type == TypeManager.float_type)
+                                       return new FloatConstant ((float) v, real_expr.Location);
+                               if (target_type == TypeManager.char_type)
+                                       return new CharConstant ((char) v, real_expr.Location);
+                               if (target_type == TypeManager.decimal_type)
+                                       return new DecimalConstant ((decimal) v, real_expr.Location);
+                       }
+
+                       if (real_expr is CharConstant){
+                               char v = ((CharConstant) real_expr).Value;
+                               
+                               if (target_type == TypeManager.byte_type) {
+                                       if (!CheckRange (ec, v, target_type, Byte.MinValue, Byte.MaxValue))
+                                               return null;
+                                       return new ByteConstant ((byte) v, real_expr.Location);
+                               }
+                               if (target_type == TypeManager.sbyte_type) {
+                                       if (!CheckRange (ec, v, target_type, SByte.MinValue, SByte.MaxValue))
+                                               return null;
+                                       return new SByteConstant ((sbyte) v, real_expr.Location);
+                               }
+                               if (target_type == TypeManager.short_type) {
+                                       if (!CheckRange (ec, v, target_type, Int16.MinValue, Int16.MaxValue))
+                                               return null;
+                                       return new ShortConstant ((short) v, real_expr.Location);
+                               }
+                               if (target_type == TypeManager.int32_type)
+                                       return new IntConstant ((int) v, real_expr.Location);
+                               if (target_type == TypeManager.uint32_type)
+                                       return new UIntConstant ((uint) v, real_expr.Location);
+                               if (target_type == TypeManager.int64_type)
+                                       return new LongConstant ((long) v, real_expr.Location);
+                               if (target_type == TypeManager.uint64_type)
+                                       return new ULongConstant ((ulong) v, real_expr.Location);
+                               if (target_type == TypeManager.float_type)
+                                       return new FloatConstant ((float) v, real_expr.Location);
+                               if (target_type == TypeManager.double_type)
+                                       return new DoubleConstant ((double) v, real_expr.Location);
+                               if (target_type == TypeManager.char_type) {
+                                       if (!CheckRange (ec, v, target_type, Char.MinValue, Char.MaxValue))
+                                               return null;
+                                       return new CharConstant ((char) v, real_expr.Location);
+                               }
+                               if (target_type == TypeManager.decimal_type)
+                                       return new DecimalConstant ((decimal) v, real_expr.Location);
+                       }
+
+                       return null;
+               }
                
                public override Expression DoResolveLValue (EmitContext ec, Expression right_side)
                {
@@ -1324,11 +1821,11 @@ namespace Mono.CSharp {
 
                        eclass = ExprClass.Value;
 
-                       Constant c = expr as Constant;
-                       if (c != null) {
-                               c = c.TryReduce (ec, type, loc);
-                               if (c != null)
-                                       return c;
+                       if (expr is Constant){
+                               Expression e = TryReduce (ec, type);
+
+                               if (e != null)
+                                       return e;
                        }
 
                        if (type.IsPointer && !ec.InUnsafe) {
@@ -1435,7 +1932,7 @@ namespace Mono.CSharp {
                /// <summary>
                ///   Returns a stringified representation of the Operator
                /// </summary>
-               public static string OperName (Operator oper)
+               static string OperName (Operator oper)
                {
                        switch (oper){
                        case Operator.Multiply:
@@ -2270,43 +2767,6 @@ namespace Mono.CSharp {
                        return this;
                }
 
-               Constant EnumLiftUp (EmitContext ec, Constant left, Constant right)
-               {
-                       switch (oper) {
-                               case Operator.BitwiseOr:
-                               case Operator.BitwiseAnd:
-                               case Operator.ExclusiveOr:
-                               case Operator.Equality:
-                               case Operator.Inequality:
-                               case Operator.LessThan:
-                               case Operator.LessThanOrEqual:
-                               case Operator.GreaterThan:
-                               case Operator.GreaterThanOrEqual:
-                                       if (left is EnumConstant)
-                                               return left;
-
-                                       if (left.IsZeroInteger)
-                                               return new EnumConstant (left, right.Type);
-
-                                       break;
-
-                               case Operator.Addition:
-                               case Operator.Subtraction:
-                                       return left;
-
-                               case Operator.Multiply:
-                               case Operator.Division:
-                               case Operator.Modulus:
-                               case Operator.LeftShift:
-                               case Operator.RightShift:
-                                       if (right is EnumConstant || left is EnumConstant)
-                                               break;
-                                       return left;
-                       }
-                       Error_OperatorCannotBeApplied (loc, Binary.OperName (oper), left.Type, right.Type);
-                       return null;
-               }
-
                public override Expression DoResolve (EmitContext ec)
                {
                        if ((oper == Operator.Subtraction) && (left is ParenthesizedExpression)) {
@@ -2340,17 +2800,8 @@ namespace Mono.CSharp {
                                return null;
 
                        eclass = ExprClass.Value;
-                       Constant rc = right as Constant;
 
-                       if (lc != null && rc != null && (TypeManager.IsEnumType (left.Type) || TypeManager.IsEnumType (right.Type))) {
-                               left = lc = EnumLiftUp (ec, lc, rc);
-                               if (lc == null)
-                                       return null;
-
-                               right = rc = EnumLiftUp (ec, rc, lc);
-                               if (rc == null)
-                                       return null;
-                       }
+                       Constant rc = right as Constant;
 
                        if (oper == Operator.BitwiseAnd) {
                                if (rc != null && rc.IsZeroInteger) {
index 1f3ea1124741b3a933f1668a28fc98b1bc384cd2..639e5368c81699ea34af5cfb32eab4d7e8c5ceb3 100644 (file)
@@ -114,13 +114,6 @@ namespace Mono.CSharp {
                        return base.ToType (type, loc);
                }
 
-               public override Constant Reduce(EmitContext ec, Type target_type)
-               {
-                       if (target_type == TypeManager.string_type)
-                               return this;
-
-                       return null;
-               }
        }
 
        //
index 5d306e64559903815dd346d5acd2bbb68f41f2e6..4e1e1abfc3f14cea12cc384b4a12a6c7c1088723 100644 (file)
@@ -511,6 +511,7 @@ namespace Mono.CSharp {
                                if (RootContext.StdLib){
                                        foreach (TypeContainer tc in type_container_resolve_order)
                                                tc.DefineMembers (root);
+
                                } else {
                                        foreach (TypeContainer tc in type_container_resolve_order) {
                                                // When compiling corlib, these types have already been