Author: marek
Date: 2005-10-17 04:14:10 -0400 (Mon, 17 Oct 2005)
New Revision: 51787
Modified:
trunk/mcs/mcs/ChangeLog
trunk/mcs/mcs/cfold.cs
trunk/mcs/mcs/constant.cs
trunk/mcs/mcs/ecore.cs
trunk/mcs/mcs/expression.cs
trunk/mcs/mcs/literal.cs
Log:
2005-10-17 Marek Safar <[EMAIL PROTECTED]>
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.
Modified: trunk/mcs/mcs/ChangeLog
===================================================================
--- trunk/mcs/mcs/ChangeLog 2005-10-17 08:08:33 UTC (rev 51786)
+++ trunk/mcs/mcs/ChangeLog 2005-10-17 08:14:10 UTC (rev 51787)
@@ -1,3 +1,16 @@
+2005-10-17 Marek Safar <[EMAIL PROTECTED]>
+
+ 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 <[EMAIL PROTECTED]>
* ecore.cs (GetMemberType): Report the correct mapping for the
MemberCore
Modified: trunk/mcs/mcs/cfold.cs
===================================================================
--- trunk/mcs/mcs/cfold.cs 2005-10-17 08:08:33 UTC (rev 51786)
+++ trunk/mcs/mcs/cfold.cs 2005-10-17 08:14:10 UTC (rev 51787)
@@ -141,33 +141,6 @@
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)
@@ -555,7 +528,7 @@
}
if (wrap_as != null)
- return new EnumConstant (result,
wrap_as);
+ return result.TryReduce (ec, wrap_as,
loc);
else
return result;
@@ -685,10 +658,11 @@
} catch (OverflowException){
Error_CompileTimeOverflow (loc);
}
+
if (wrap_as != null)
- return new EnumConstant (result,
wrap_as);
- else
- return result;
+ return result.TryReduce (ec, wrap_as,
loc);
+
+ return result;
case Binary.Operator.Multiply:
DoConstantNumericPromotions (ec, oper, ref
left, ref right, loc);
Modified: trunk/mcs/mcs/constant.cs
===================================================================
--- trunk/mcs/mcs/constant.cs 2005-10-17 08:08:33 UTC (rev 51786)
+++ trunk/mcs/mcs/constant.cs 2005-10-17 08:14:10 UTC (rev 51787)
@@ -3,6 +3,7 @@
//
// Author:
// Miguel de Icaza ([EMAIL PROTECTED])
+// Marek Safar ([EMAIL PROTECTED])
//
// (C) 2001 Ximian, Inc.
//
@@ -205,6 +206,69 @@
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;
@@ -310,6 +374,12 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
return false;
}
}
+
+ public override Constant Reduce (EmitContext ec, Type
target_type)
+ {
+ return null;
+ }
}
}
Modified: trunk/mcs/mcs/ecore.cs
===================================================================
--- trunk/mcs/mcs/ecore.cs 2005-10-17 08:08:33 UTC (rev 51786)
+++ trunk/mcs/mcs/ecore.cs 2005-10-17 08:14:10 UTC (rev 51787)
@@ -1298,6 +1298,12 @@
return false;
}
}
+
+ public override Constant Reduce (EmitContext ec, Type
target_type)
+ {
+ throw new NotImplementedException ();
+ }
+
}
@@ -1404,6 +1410,14 @@
}
}
+ 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) {
Modified: trunk/mcs/mcs/expression.cs
===================================================================
--- trunk/mcs/mcs/expression.cs 2005-10-17 08:08:33 UTC (rev 51786)
+++ trunk/mcs/mcs/expression.cs 2005-10-17 08:14:10 UTC (rev 51787)
@@ -1290,503 +1290,6 @@
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)
{
@@ -1821,11 +1324,11 @@
eclass = ExprClass.Value;
- if (expr is Constant){
- Expression e = TryReduce (ec, type);
-
- if (e != null)
- return e;
+ Constant c = expr as Constant;
+ if (c != null) {
+ c = c.TryReduce (ec, type, loc);
+ if (c != null)
+ return c;
}
if (type.IsPointer && !ec.InUnsafe) {
@@ -1932,7 +1435,7 @@
/// <summary>
/// Returns a stringified representation of the Operator
/// </summary>
- static string OperName (Operator oper)
+ public static string OperName (Operator oper)
{
switch (oper){
case Operator.Multiply:
@@ -2767,6 +2270,43 @@
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)) {
@@ -2800,9 +2340,18 @@
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;
+ }
+
if (oper == Operator.BitwiseAnd) {
if (rc != null && rc.IsZeroInteger) {
return lc is EnumConstant ?
Modified: trunk/mcs/mcs/literal.cs
===================================================================
--- trunk/mcs/mcs/literal.cs 2005-10-17 08:08:33 UTC (rev 51786)
+++ trunk/mcs/mcs/literal.cs 2005-10-17 08:14:10 UTC (rev 51787)
@@ -114,6 +114,13 @@
return base.ToType (type, loc);
}
+ public override Constant Reduce(EmitContext ec, Type
target_type)
+ {
+ if (target_type == TypeManager.string_type)
+ return this;
+
+ return null;
+ }
}
//
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches