X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fcfold.cs;h=9e8a5a1a6293a1de740c20cb86e3fc3ef0ebbc6d;hb=a4c049eb2217fb63d763181b7a1280b2190ebe31;hp=2d3c96942aa8d842996751643355a132c288650a;hpb=28776e66837c35ad00ca409831350697af055b78;p=mono.git diff --git a/mcs/mcs/cfold.cs b/mcs/mcs/cfold.cs old mode 100755 new mode 100644 index 2d3c96942aa..9e8a5a1a629 --- a/mcs/mcs/cfold.cs +++ b/mcs/mcs/cfold.cs @@ -118,9 +118,9 @@ namespace Mono.CSharp { if (ic != null){ if (ic.Value >= 0){ if (left == other) - left = new UIntConstant ((uint) ic.Value); + left = new UIntConstant ((uint) ic.Value, ic.Location); else - right = new UIntConstant ((uint) ic.Value); + right = new UIntConstant ((uint) ic.Value, ic.Location); return; } } @@ -141,36 +141,12 @@ 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)); - - if (need_check && - !Convert.ImplicitConversionExists (ec, match, other.Type)) { - Convert.Error_CannotImplicitConversion (loc, match.Type, other.Type); - left = null; - right = null; - return; - } - if (left is EnumConstant) left = ((EnumConstant) left).Child; if (right is EnumConstant) right = ((EnumConstant) right).Child; + + DoConstantNumericPromotions (ec, oper, ref left, ref right, loc); return; } else { @@ -227,12 +203,12 @@ namespace Mono.CSharp { DoConstantNumericPromotions (ec, oper, ref left, ref right, loc); if (left == null || right == null) return null; - + if (left is IntConstant){ IntConstant v; int res = ((IntConstant) left).Value | ((IntConstant) right).Value; - v = new IntConstant (res); + v = new IntConstant (res, left.Location); if (result_type == null) return v; else @@ -241,7 +217,7 @@ namespace Mono.CSharp { UIntConstant v; uint res = ((UIntConstant)left).Value | ((UIntConstant)right).Value; - v = new UIntConstant (res); + v = new UIntConstant (res, left.Location); if (result_type == null) return v; else @@ -250,7 +226,7 @@ namespace Mono.CSharp { LongConstant v; long res = ((LongConstant)left).Value | ((LongConstant)right).Value; - v = new LongConstant (res); + v = new LongConstant (res, left.Location); if (result_type == null) return v; else @@ -260,7 +236,7 @@ namespace Mono.CSharp { ulong res = ((ULongConstant)left).Value | ((ULongConstant)right).Value; - v = new ULongConstant (res); + v = new ULongConstant (res, left.Location); if (result_type == null) return v; else @@ -270,7 +246,7 @@ namespace Mono.CSharp { ushort res = (ushort) (((UShortConstant)left).Value | ((UShortConstant)right).Value); - v = new UShortConstant (res); + v = new UShortConstant (res, left.Location); if (result_type == null) return v; else @@ -280,7 +256,7 @@ namespace Mono.CSharp { short res = (short) (((ShortConstant)left).Value | ((ShortConstant)right).Value); - v = new ShortConstant (res); + v = new ShortConstant (res, left.Location); if (result_type == null) return v; else @@ -297,7 +273,7 @@ namespace Mono.CSharp { IntConstant v; int res = ((IntConstant) left).Value & ((IntConstant) right).Value; - v = new IntConstant (res); + v = new IntConstant (res, left.Location); if (result_type == null) return v; else @@ -306,7 +282,7 @@ namespace Mono.CSharp { UIntConstant v; uint res = ((UIntConstant)left).Value & ((UIntConstant)right).Value; - v = new UIntConstant (res); + v = new UIntConstant (res, left.Location); if (result_type == null) return v; else @@ -315,7 +291,7 @@ namespace Mono.CSharp { LongConstant v; long res = ((LongConstant)left).Value & ((LongConstant)right).Value; - v = new LongConstant (res); + v = new LongConstant (res, left.Location); if (result_type == null) return v; else @@ -325,7 +301,7 @@ namespace Mono.CSharp { ulong res = ((ULongConstant)left).Value & ((ULongConstant)right).Value; - v = new ULongConstant (res); + v = new ULongConstant (res, left.Location); if (result_type == null) return v; else @@ -335,7 +311,7 @@ namespace Mono.CSharp { ushort res = (ushort) (((UShortConstant)left).Value & ((UShortConstant)right).Value); - v = new UShortConstant (res); + v = new UShortConstant (res, left.Location); if (result_type == null) return v; else @@ -345,7 +321,7 @@ namespace Mono.CSharp { short res = (short) (((ShortConstant)left).Value & ((ShortConstant)right).Value); - v = new ShortConstant (res); + v = new ShortConstant (res, left.Location); if (result_type == null) return v; else @@ -362,7 +338,7 @@ namespace Mono.CSharp { IntConstant v; int res = ((IntConstant) left).Value ^ ((IntConstant) right).Value; - v = new IntConstant (res); + v = new IntConstant (res, left.Location); if (result_type == null) return v; else @@ -371,7 +347,7 @@ namespace Mono.CSharp { UIntConstant v; uint res = ((UIntConstant)left).Value ^ ((UIntConstant)right).Value; - v = new UIntConstant (res); + v = new UIntConstant (res, left.Location); if (result_type == null) return v; else @@ -380,7 +356,7 @@ namespace Mono.CSharp { LongConstant v; long res = ((LongConstant)left).Value ^ ((LongConstant)right).Value; - v = new LongConstant (res); + v = new LongConstant (res, left.Location); if (result_type == null) return v; else @@ -390,7 +366,7 @@ namespace Mono.CSharp { ulong res = ((ULongConstant)left).Value ^ ((ULongConstant)right).Value; - v = new ULongConstant (res); + v = new ULongConstant (res, left.Location); if (result_type == null) return v; else @@ -400,7 +376,7 @@ namespace Mono.CSharp { ushort res = (ushort) (((UShortConstant)left).Value ^ ((UShortConstant)right).Value); - v = new UShortConstant (res); + v = new UShortConstant (res, left.Location); if (result_type == null) return v; else @@ -410,7 +386,7 @@ namespace Mono.CSharp { short res = (short)(((ShortConstant)left).Value ^ ((ShortConstant)right).Value); - v = new ShortConstant (res); + v = new ShortConstant (res, left.Location); if (result_type == null) return v; else @@ -432,7 +408,7 @@ namespace Mono.CSharp { if (left_is_string && right_is_string) return new StringConstant ( ((StringConstant) left).Value + - ((StringConstant) right).Value); + ((StringConstant) right).Value, left.Location); return null; } @@ -447,13 +423,17 @@ namespace Mono.CSharp { if (right is EnumConstant){ return null; } - if (((EnumConstant) left).Child.Type != right.Type) + + right = right.ToType (((EnumConstant) left).Child.Type, loc); + if (right == null) return null; wrap_as = left.Type; } else if (right is EnumConstant){ - if (((EnumConstant) right).Child.Type != left.Type) + left = left.ToType (((EnumConstant) right).Child.Type, loc); + if (left == null) return null; + wrap_as = right.Type; } @@ -473,7 +453,7 @@ namespace Mono.CSharp { res = unchecked (((DoubleConstant) left).Value + ((DoubleConstant) right).Value); - result = new DoubleConstant (res); + result = new DoubleConstant (res, left.Location); } else if (left is FloatConstant){ float res; @@ -484,7 +464,7 @@ namespace Mono.CSharp { res = unchecked (((FloatConstant) left).Value + ((FloatConstant) right).Value); - result = new FloatConstant (res); + result = new FloatConstant (res, left.Location); } else if (left is ULongConstant){ ulong res; @@ -495,7 +475,7 @@ namespace Mono.CSharp { res = unchecked (((ULongConstant) left).Value + ((ULongConstant) right).Value); - result = new ULongConstant (res); + result = new ULongConstant (res, left.Location); } else if (left is LongConstant){ long res; @@ -506,7 +486,7 @@ namespace Mono.CSharp { res = unchecked (((LongConstant) left).Value + ((LongConstant) right).Value); - result = new LongConstant (res); + result = new LongConstant (res, left.Location); } else if (left is UIntConstant){ uint res; @@ -517,7 +497,7 @@ namespace Mono.CSharp { res = unchecked (((UIntConstant) left).Value + ((UIntConstant) right).Value); - result = new UIntConstant (res); + result = new UIntConstant (res, left.Location); } else if (left is IntConstant){ int res; @@ -528,7 +508,18 @@ namespace Mono.CSharp { res = unchecked (((IntConstant) left).Value + ((IntConstant) right).Value); - result = new IntConstant (res); + result = new IntConstant (res, left.Location); + } else if (left is DecimalConstant) { + decimal res; + + if (ec.ConstantCheckState) + res = checked (((DecimalConstant) left).Value + + ((DecimalConstant) right).Value); + else + res = unchecked (((DecimalConstant) left).Value + + ((DecimalConstant) right).Value); + + result = new DecimalConstant (res, left.Location); } else { throw new Exception ( "Unexepected addition input: " + left); } @@ -537,7 +528,7 @@ namespace Mono.CSharp { } if (wrap_as != null) - return new EnumConstant (result, wrap_as); + return result.TryReduce (ec, wrap_as, loc); else return result; @@ -550,18 +541,32 @@ namespace Mono.CSharp { wrap_as = null; if (left is EnumConstant){ if (right is EnumConstant){ - if (left.Type == right.Type) - wrap_as = TypeManager.EnumToUnderlying (left.Type); - else + if (left.Type != right.Type) { + Binary.Error_OperatorCannotBeApplied (loc, "-", left.Type, right.Type); + return null; + } + + wrap_as = TypeManager.EnumToUnderlying (left.Type); + right = ((EnumConstant) right).Child.ToType (wrap_as, loc); + if (right == null) + return null; + + left = ((EnumConstant) left).Child.ToType (wrap_as, loc); + if (left == null) return null; } - if (((EnumConstant) left).Child.Type != right.Type) - return null; + else { + right = right.ToType (((EnumConstant) left).Child.Type, loc); + if (right == null) + return null; - wrap_as = left.Type; + wrap_as = left.Type; + } } else if (right is EnumConstant){ - if (((EnumConstant) right).Child.Type != left.Type) + left = left.ToType (((EnumConstant) right).Child.Type, loc); + if (left == null) return null; + wrap_as = right.Type; } @@ -580,7 +585,7 @@ namespace Mono.CSharp { res = unchecked (((DoubleConstant) left).Value - ((DoubleConstant) right).Value); - result = new DoubleConstant (res); + result = new DoubleConstant (res, left.Location); } else if (left is FloatConstant){ float res; @@ -591,7 +596,7 @@ namespace Mono.CSharp { res = unchecked (((FloatConstant) left).Value - ((FloatConstant) right).Value); - result = new FloatConstant (res); + result = new FloatConstant (res, left.Location); } else if (left is ULongConstant){ ulong res; @@ -602,7 +607,7 @@ namespace Mono.CSharp { res = unchecked (((ULongConstant) left).Value - ((ULongConstant) right).Value); - result = new ULongConstant (res); + result = new ULongConstant (res, left.Location); } else if (left is LongConstant){ long res; @@ -613,7 +618,7 @@ namespace Mono.CSharp { res = unchecked (((LongConstant) left).Value - ((LongConstant) right).Value); - result = new LongConstant (res); + result = new LongConstant (res, left.Location); } else if (left is UIntConstant){ uint res; @@ -624,7 +629,7 @@ namespace Mono.CSharp { res = unchecked (((UIntConstant) left).Value - ((UIntConstant) right).Value); - result = new UIntConstant (res); + result = new UIntConstant (res, left.Location); } else if (left is IntConstant){ int res; @@ -635,17 +640,29 @@ namespace Mono.CSharp { res = unchecked (((IntConstant) left).Value - ((IntConstant) right).Value); - result = new IntConstant (res); + result = new IntConstant (res, left.Location); + } else if (left is DecimalConstant) { + decimal res; + + if (ec.ConstantCheckState) + res = checked (((DecimalConstant) left).Value - + ((DecimalConstant) right).Value); + else + res = unchecked (((DecimalConstant) left).Value - + ((DecimalConstant) right).Value); + + return new DecimalConstant (res, left.Location); } else { throw new Exception ( "Unexepected subtraction input: " + left); } } 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); @@ -663,7 +680,7 @@ namespace Mono.CSharp { res = unchecked (((DoubleConstant) left).Value * ((DoubleConstant) right).Value); - return new DoubleConstant (res); + return new DoubleConstant (res, left.Location); } else if (left is FloatConstant){ float res; @@ -674,7 +691,7 @@ namespace Mono.CSharp { res = unchecked (((FloatConstant) left).Value * ((FloatConstant) right).Value); - return new FloatConstant (res); + return new FloatConstant (res, left.Location); } else if (left is ULongConstant){ ulong res; @@ -685,7 +702,7 @@ namespace Mono.CSharp { res = unchecked (((ULongConstant) left).Value * ((ULongConstant) right).Value); - return new ULongConstant (res); + return new ULongConstant (res, left.Location); } else if (left is LongConstant){ long res; @@ -696,7 +713,7 @@ namespace Mono.CSharp { res = unchecked (((LongConstant) left).Value * ((LongConstant) right).Value); - return new LongConstant (res); + return new LongConstant (res, left.Location); } else if (left is UIntConstant){ uint res; @@ -707,7 +724,7 @@ namespace Mono.CSharp { res = unchecked (((UIntConstant) left).Value * ((UIntConstant) right).Value); - return new UIntConstant (res); + return new UIntConstant (res, left.Location); } else if (left is IntConstant){ int res; @@ -718,7 +735,7 @@ namespace Mono.CSharp { res = unchecked (((IntConstant) left).Value * ((IntConstant) right).Value); - return new IntConstant (res); + return new IntConstant (res, left.Location); } else if (left is DecimalConstant) { decimal res; @@ -729,7 +746,7 @@ namespace Mono.CSharp { res = unchecked (((DecimalConstant) left).Value * ((DecimalConstant) right).Value); - return new DecimalConstant (res); + return new DecimalConstant (res, left.Location); } else { throw new Exception ( "Unexepected multiply input: " + left); } @@ -754,7 +771,7 @@ namespace Mono.CSharp { res = unchecked (((DoubleConstant) left).Value / ((DoubleConstant) right).Value); - return new DoubleConstant (res); + return new DoubleConstant (res, left.Location); } else if (left is FloatConstant){ float res; @@ -765,7 +782,7 @@ namespace Mono.CSharp { res = unchecked (((FloatConstant) left).Value / ((FloatConstant) right).Value); - return new FloatConstant (res); + return new FloatConstant (res, left.Location); } else if (left is ULongConstant){ ulong res; @@ -776,7 +793,7 @@ namespace Mono.CSharp { res = unchecked (((ULongConstant) left).Value / ((ULongConstant) right).Value); - return new ULongConstant (res); + return new ULongConstant (res, left.Location); } else if (left is LongConstant){ long res; @@ -787,7 +804,7 @@ namespace Mono.CSharp { res = unchecked (((LongConstant) left).Value / ((LongConstant) right).Value); - return new LongConstant (res); + return new LongConstant (res, left.Location); } else if (left is UIntConstant){ uint res; @@ -798,7 +815,7 @@ namespace Mono.CSharp { res = unchecked (((UIntConstant) left).Value / ((UIntConstant) right).Value); - return new UIntConstant (res); + return new UIntConstant (res, left.Location); } else if (left is IntConstant){ int res; @@ -809,7 +826,7 @@ namespace Mono.CSharp { res = unchecked (((IntConstant) left).Value / ((IntConstant) right).Value); - return new IntConstant (res); + return new IntConstant (res, left.Location); } else if (left is DecimalConstant) { decimal res; @@ -820,7 +837,7 @@ namespace Mono.CSharp { res = unchecked (((DecimalConstant) left).Value / ((DecimalConstant) right).Value); - return new DecimalConstant (res); + return new DecimalConstant (res, left.Location); } else { throw new Exception ( "Unexepected division input: " + left); } @@ -849,7 +866,7 @@ namespace Mono.CSharp { res = unchecked (((DoubleConstant) left).Value % ((DoubleConstant) right).Value); - return new DoubleConstant (res); + return new DoubleConstant (res, left.Location); } else if (left is FloatConstant){ float res; @@ -860,7 +877,7 @@ namespace Mono.CSharp { res = unchecked (((FloatConstant) left).Value % ((FloatConstant) right).Value); - return new FloatConstant (res); + return new FloatConstant (res, left.Location); } else if (left is ULongConstant){ ulong res; @@ -871,7 +888,7 @@ namespace Mono.CSharp { res = unchecked (((ULongConstant) left).Value % ((ULongConstant) right).Value); - return new ULongConstant (res); + return new ULongConstant (res, left.Location); } else if (left is LongConstant){ long res; @@ -882,7 +899,7 @@ namespace Mono.CSharp { res = unchecked (((LongConstant) left).Value % ((LongConstant) right).Value); - return new LongConstant (res); + return new LongConstant (res, left.Location); } else if (left is UIntConstant){ uint res; @@ -893,7 +910,7 @@ namespace Mono.CSharp { res = unchecked (((UIntConstant) left).Value % ((UIntConstant) right).Value); - return new UIntConstant (res); + return new UIntConstant (res, left.Location); } else if (left is IntConstant){ int res; @@ -904,7 +921,7 @@ namespace Mono.CSharp { res = unchecked (((IntConstant) left).Value % ((IntConstant) right).Value); - return new IntConstant (res); + return new IntConstant (res, left.Location); } else { throw new Exception ( "Unexepected modulus input: " + left); } @@ -928,19 +945,19 @@ namespace Mono.CSharp { IntConstant lic; if ((lic = left.ConvertToInt ()) != null) - return new IntConstant (lic.Value << lshift_val); + return new IntConstant (lic.Value << lshift_val, left.Location); UIntConstant luic; if ((luic = left.ConvertToUInt ()) != null) - return new UIntConstant (luic.Value << lshift_val); + return new UIntConstant (luic.Value << lshift_val, left.Location); LongConstant llc; if ((llc = left.ConvertToLong ()) != null) - return new LongConstant (llc.Value << lshift_val); + return new LongConstant (llc.Value << lshift_val, left.Location); ULongConstant lulc; if ((lulc = left.ConvertToULong ()) != null) - return new ULongConstant (lulc.Value << lshift_val); + return new ULongConstant (lulc.Value << lshift_val, left.Location); Binary.Error_OperatorCannotBeApplied (loc, "<<", lt, rt); break; @@ -958,19 +975,19 @@ namespace Mono.CSharp { IntConstant ric; if ((ric = left.ConvertToInt ()) != null) - return new IntConstant (ric.Value >> rshift_val); + return new IntConstant (ric.Value >> rshift_val, left.Location); UIntConstant ruic; if ((ruic = left.ConvertToUInt ()) != null) - return new UIntConstant (ruic.Value >> rshift_val); + return new UIntConstant (ruic.Value >> rshift_val, left.Location); LongConstant rlc; if ((rlc = left.ConvertToLong ()) != null) - return new LongConstant (rlc.Value >> rshift_val); + return new LongConstant (rlc.Value >> rshift_val, left.Location); ULongConstant rulc; if ((rulc = left.ConvertToULong ()) != null) - return new ULongConstant (rulc.Value >> rshift_val); + return new ULongConstant (rulc.Value >> rshift_val, left.Location); Binary.Error_OperatorCannotBeApplied (loc, ">>", lt, rt); break; @@ -979,7 +996,7 @@ namespace Mono.CSharp { if (left is BoolConstant && right is BoolConstant){ return new BoolConstant ( ((BoolConstant) left).Value && - ((BoolConstant) right).Value); + ((BoolConstant) right).Value, left.Location); } break; @@ -987,7 +1004,7 @@ namespace Mono.CSharp { if (left is BoolConstant && right is BoolConstant){ return new BoolConstant ( ((BoolConstant) left).Value || - ((BoolConstant) right).Value); + ((BoolConstant) right).Value, left.Location); } break; @@ -995,26 +1012,26 @@ namespace Mono.CSharp { if (left is BoolConstant && right is BoolConstant){ return new BoolConstant ( ((BoolConstant) left).Value == - ((BoolConstant) right).Value); + ((BoolConstant) right).Value, left.Location); } if (left is NullLiteral){ if (right is NullLiteral) - return new BoolConstant (true); + return new BoolConstant (true, left.Location); else if (right is StringConstant) return new BoolConstant ( - ((StringConstant) right).Value == null); + ((StringConstant) right).Value == null, left.Location); } else if (right is NullLiteral){ if (left is NullLiteral) - return new BoolConstant (true); + return new BoolConstant (true, left.Location); else if (left is StringConstant) return new BoolConstant ( - ((StringConstant) left).Value == null); + ((StringConstant) left).Value == null, left.Location); } if (left is StringConstant && right is StringConstant){ return new BoolConstant ( ((StringConstant) left).Value == - ((StringConstant) right).Value); + ((StringConstant) right).Value, left.Location); } @@ -1044,31 +1061,31 @@ namespace Mono.CSharp { else return null; - return new BoolConstant (bool_res); + return new BoolConstant (bool_res, left.Location); case Binary.Operator.Inequality: if (left is BoolConstant && right is BoolConstant){ return new BoolConstant ( ((BoolConstant) left).Value != - ((BoolConstant) right).Value); + ((BoolConstant) right).Value, left.Location); } if (left is NullLiteral){ if (right is NullLiteral) - return new BoolConstant (false); + return new BoolConstant (false, left.Location); else if (right is StringConstant) return new BoolConstant ( - ((StringConstant) right).Value != null); + ((StringConstant) right).Value != null, left.Location); } else if (right is NullLiteral){ if (left is NullLiteral) - return new BoolConstant (false); + return new BoolConstant (false, left.Location); else if (left is StringConstant) return new BoolConstant ( - ((StringConstant) left).Value != null); + ((StringConstant) left).Value != null, left.Location); } if (left is StringConstant && right is StringConstant){ return new BoolConstant ( ((StringConstant) left).Value != - ((StringConstant) right).Value); + ((StringConstant) right).Value, left.Location); } DoConstantNumericPromotions (ec, oper, ref left, ref right, loc); @@ -1097,7 +1114,7 @@ namespace Mono.CSharp { else return null; - return new BoolConstant (bool_res); + return new BoolConstant (bool_res, left.Location); case Binary.Operator.LessThan: DoConstantNumericPromotions (ec, oper, ref left, ref right, loc); @@ -1126,7 +1143,7 @@ namespace Mono.CSharp { else return null; - return new BoolConstant (bool_res); + return new BoolConstant (bool_res, left.Location); case Binary.Operator.GreaterThan: DoConstantNumericPromotions (ec, oper, ref left, ref right, loc); @@ -1155,7 +1172,7 @@ namespace Mono.CSharp { else return null; - return new BoolConstant (bool_res); + return new BoolConstant (bool_res, left.Location); case Binary.Operator.GreaterThanOrEqual: DoConstantNumericPromotions (ec, oper, ref left, ref right, loc); @@ -1184,7 +1201,7 @@ namespace Mono.CSharp { else return null; - return new BoolConstant (bool_res); + return new BoolConstant (bool_res, left.Location); case Binary.Operator.LessThanOrEqual: DoConstantNumericPromotions (ec, oper, ref left, ref right, loc); @@ -1213,7 +1230,7 @@ namespace Mono.CSharp { else return null; - return new BoolConstant (bool_res); + return new BoolConstant (bool_res, left.Location); } return null;