X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fcfold.cs;h=9e8a5a1a6293a1de740c20cb86e3fc3ef0ebbc6d;hb=a4c049eb2217fb63d763181b7a1280b2190ebe31;hp=ecc3fa20718a44c73356dced57f3fbeed9fd5848;hpb=c987b196d9d3d64635778b90662e4fad89c914fd;p=mono.git diff --git a/mcs/mcs/cfold.cs b/mcs/mcs/cfold.cs old mode 100755 new mode 100644 index ecc3fa20718..9e8a5a1a629 --- a/mcs/mcs/cfold.cs +++ b/mcs/mcs/cfold.cs @@ -4,7 +4,7 @@ // Author: // Miguel de Icaza (miguel@ximian.com) // -// (C) 2002 Ximian, Inc. +// (C) 2002, 2003 Ximian, Inc. // using System; @@ -26,8 +26,10 @@ namespace Mono.CSharp { // (long, long) // (uint, uint) // (int, int) + // (short, short) (Happens with enumerations with underlying short type) + // (ushort, ushort) (Happens with enumerations with underlying short type) // - static void DoConstantNumericPromotions (Binary.Operator oper, + static void DoConstantNumericPromotions (EmitContext ec, Binary.Operator oper, ref Constant left, ref Constant right, Location loc) { @@ -50,23 +52,29 @@ namespace Mono.CSharp { if (!(right is FloatConstant)) right = right.ToFloat (loc); - return; +; return; } else if (left is ULongConstant || right is ULongConstant){ // // If either operand is of type ulong, the other operand is // converted to type ulong. or an error ocurrs if the other // operand is of type sbyte, short, int or long // +#if WRONG Constant match, other; +#endif if (left is ULongConstant){ +#if WRONG other = right; match = left; +#endif if (!(right is ULongConstant)) right = right.ToULong (loc); } else { +#if WRONG other = left; match = right; +#endif left = left.ToULong (loc); } @@ -93,14 +101,54 @@ namespace Mono.CSharp { } else if (left is UIntConstant || right is UIntConstant){ // // If either operand is of type uint, and the other - // operand is of type sbyte, short or int, othe operands are + // operand is of type sbyte, short or int, the operands are // converted to type long. // - if (!(left is UIntConstant)) + Constant other; + if (left is UIntConstant) + other = right; + else + other = left; + + // Nothing to do. + if (other is UIntConstant) + return; + + IntConstant ic = other as IntConstant; + if (ic != null){ + if (ic.Value >= 0){ + if (left == other) + left = new UIntConstant ((uint) ic.Value, ic.Location); + else + right = new UIntConstant ((uint) ic.Value, ic.Location); + return; + } + } + + if (other is SByteConstant || other is ShortConstant || ic != null){ + left = left.ToLong (loc); + right = right.ToLong (loc); + } else { left = left.ToUInt (loc); - else if (!(right is UIntConstant)) - right = right.ToUInt (loc); + right = left.ToUInt (loc); + } + + return; + } else if (left is DecimalConstant || right is DecimalConstant) { + if (!(left is DecimalConstant)) + left = left.ToDecimal (loc); + else if (!(right is DecimalConstant)) + right = right.ToDecimal (loc); return; + } else if (left is EnumConstant || right is EnumConstant){ + 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 { // // Force conversions to int32 @@ -130,24 +178,37 @@ namespace Mono.CSharp { Type rt = right.Type; Type result_type = null; bool bool_res; - + // // Enumerator folding // if (rt == lt && left is EnumConstant) result_type = lt; + // + // During an enum evaluation, we need to unwrap enumerations + // + if (ec.InEnumContext){ + if (left is EnumConstant) + left = ((EnumConstant) left).Child; + + if (right is EnumConstant) + right = ((EnumConstant) right).Child; + } + + Type wrap_as; + Constant result = null; switch (oper){ case Binary.Operator.BitwiseOr: - DoConstantNumericPromotions (oper, ref left, ref right, loc); + 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 @@ -156,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 @@ -165,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 @@ -175,7 +236,27 @@ 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 + return new EnumConstant (v, result_type); + } else if (left is UShortConstant){ + UShortConstant v; + ushort res = (ushort) (((UShortConstant)left).Value | + ((UShortConstant)right).Value); + + v = new UShortConstant (res, left.Location); + if (result_type == null) + return v; + else + return new EnumConstant (v, result_type); + } else if (left is ShortConstant){ + ShortConstant v; + short res = (short) (((ShortConstant)left).Value | + ((ShortConstant)right).Value); + + v = new ShortConstant (res, left.Location); if (result_type == null) return v; else @@ -184,7 +265,7 @@ namespace Mono.CSharp { break; case Binary.Operator.BitwiseAnd: - DoConstantNumericPromotions (oper, ref left, ref right, loc); + DoConstantNumericPromotions (ec, oper, ref left, ref right, loc); if (left == null || right == null) return null; @@ -192,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 @@ -201,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 @@ -210,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 @@ -220,7 +301,27 @@ 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 + return new EnumConstant (v, result_type); + } else if (left is UShortConstant){ + UShortConstant v; + ushort res = (ushort) (((UShortConstant)left).Value & + ((UShortConstant)right).Value); + + v = new UShortConstant (res, left.Location); + if (result_type == null) + return v; + else + return new EnumConstant (v, result_type); + } else if (left is ShortConstant){ + ShortConstant v; + short res = (short) (((ShortConstant)left).Value & + ((ShortConstant)right).Value); + + v = new ShortConstant (res, left.Location); if (result_type == null) return v; else @@ -229,7 +330,7 @@ namespace Mono.CSharp { break; case Binary.Operator.ExclusiveOr: - DoConstantNumericPromotions (oper, ref left, ref right, loc); + DoConstantNumericPromotions (ec, oper, ref left, ref right, loc); if (left == null || right == null) return null; @@ -237,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 @@ -246,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 @@ -255,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 @@ -265,7 +366,27 @@ 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 + return new EnumConstant (v, result_type); + } else if (left is UShortConstant){ + UShortConstant v; + ushort res = (ushort) (((UShortConstant)left).Value ^ + ((UShortConstant)right).Value); + + v = new UShortConstant (res, left.Location); + if (result_type == null) + return v; + else + return new EnumConstant (v, result_type); + } else if (left is ShortConstant){ + ShortConstant v; + short res = (short)(((ShortConstant)left).Value ^ + ((ShortConstant)right).Value); + + v = new ShortConstant (res, left.Location); if (result_type == null) return v; else @@ -282,16 +403,42 @@ namespace Mono.CSharp { // one is a string, and the other is not, then defer // to runtime concatenation // + wrap_as = null; if (left_is_string || right_is_string){ if (left_is_string && right_is_string) return new StringConstant ( ((StringConstant) left).Value + - ((StringConstant) right).Value); + ((StringConstant) right).Value, left.Location); return null; } - DoConstantNumericPromotions (oper, ref left, ref right, loc); + // + // handle "E operator + (E x, U y)" + // handle "E operator + (Y y, E x)" + // + // note that E operator + (E x, E y) is invalid + // + if (left is EnumConstant){ + if (right is EnumConstant){ + return null; + } + + right = right.ToType (((EnumConstant) left).Child.Type, loc); + if (right == null) + return null; + + wrap_as = left.Type; + } else if (right is EnumConstant){ + left = left.ToType (((EnumConstant) right).Child.Type, loc); + if (left == null) + return null; + + wrap_as = right.Type; + } + + result = null; + DoConstantNumericPromotions (ec, oper, ref left, ref right, loc); if (left == null || right == null) return null; @@ -306,7 +453,7 @@ namespace Mono.CSharp { res = unchecked (((DoubleConstant) left).Value + ((DoubleConstant) right).Value); - return new DoubleConstant (res); + result = new DoubleConstant (res, left.Location); } else if (left is FloatConstant){ float res; @@ -317,7 +464,7 @@ namespace Mono.CSharp { res = unchecked (((FloatConstant) left).Value + ((FloatConstant) right).Value); - return new FloatConstant (res); + result = new FloatConstant (res, left.Location); } else if (left is ULongConstant){ ulong res; @@ -327,8 +474,8 @@ namespace Mono.CSharp { else res = unchecked (((ULongConstant) left).Value + ((ULongConstant) right).Value); - - return new ULongConstant (res); + + result = new ULongConstant (res, left.Location); } else if (left is LongConstant){ long res; @@ -339,7 +486,7 @@ namespace Mono.CSharp { res = unchecked (((LongConstant) left).Value + ((LongConstant) right).Value); - return new LongConstant (res); + result = new LongConstant (res, left.Location); } else if (left is UIntConstant){ uint res; @@ -350,7 +497,7 @@ namespace Mono.CSharp { res = unchecked (((UIntConstant) left).Value + ((UIntConstant) right).Value); - return new UIntConstant (res); + result = new UIntConstant (res, left.Location); } else if (left is IntConstant){ int res; @@ -361,17 +508,69 @@ namespace Mono.CSharp { res = unchecked (((IntConstant) left).Value + ((IntConstant) right).Value); - return 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 input: " + left); + throw new Exception ( "Unexepected addition input: " + left); } } catch (OverflowException){ Error_CompileTimeOverflow (loc); } - break; + + if (wrap_as != null) + return result.TryReduce (ec, wrap_as, loc); + else + return result; case Binary.Operator.Subtraction: - DoConstantNumericPromotions (oper, ref left, ref right, loc); + // + // handle "E operator - (E x, U y)" + // handle "E operator - (Y y, E x)" + // handle "U operator - (E x, E y)" + // + wrap_as = null; + if (left is EnumConstant){ + if (right is EnumConstant){ + 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; + } + else { + right = right.ToType (((EnumConstant) left).Child.Type, loc); + if (right == null) + return null; + + wrap_as = left.Type; + } + } else if (right is EnumConstant){ + left = left.ToType (((EnumConstant) right).Child.Type, loc); + if (left == null) + return null; + + wrap_as = right.Type; + } + + DoConstantNumericPromotions (ec, oper, ref left, ref right, loc); if (left == null || right == null) return null; @@ -386,7 +585,7 @@ namespace Mono.CSharp { res = unchecked (((DoubleConstant) left).Value - ((DoubleConstant) right).Value); - return new DoubleConstant (res); + result = new DoubleConstant (res, left.Location); } else if (left is FloatConstant){ float res; @@ -397,7 +596,7 @@ namespace Mono.CSharp { res = unchecked (((FloatConstant) left).Value - ((FloatConstant) right).Value); - return new FloatConstant (res); + result = new FloatConstant (res, left.Location); } else if (left is ULongConstant){ ulong res; @@ -408,7 +607,7 @@ namespace Mono.CSharp { res = unchecked (((ULongConstant) left).Value - ((ULongConstant) right).Value); - return new ULongConstant (res); + result = new ULongConstant (res, left.Location); } else if (left is LongConstant){ long res; @@ -419,7 +618,7 @@ namespace Mono.CSharp { res = unchecked (((LongConstant) left).Value - ((LongConstant) right).Value); - return new LongConstant (res); + result = new LongConstant (res, left.Location); } else if (left is UIntConstant){ uint res; @@ -430,7 +629,7 @@ namespace Mono.CSharp { res = unchecked (((UIntConstant) left).Value - ((UIntConstant) right).Value); - return new UIntConstant (res); + result = new UIntConstant (res, left.Location); } else if (left is IntConstant){ int res; @@ -441,17 +640,32 @@ namespace Mono.CSharp { res = unchecked (((IntConstant) left).Value - ((IntConstant) right).Value); - return 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 input: " + left); + throw new Exception ( "Unexepected subtraction input: " + left); } } catch (OverflowException){ Error_CompileTimeOverflow (loc); } - break; + + if (wrap_as != null) + return result.TryReduce (ec, wrap_as, loc); + + return result; case Binary.Operator.Multiply: - DoConstantNumericPromotions (oper, ref left, ref right, loc); + DoConstantNumericPromotions (ec, oper, ref left, ref right, loc); if (left == null || right == null) return null; @@ -461,69 +675,80 @@ namespace Mono.CSharp { if (ec.ConstantCheckState) res = checked (((DoubleConstant) left).Value * - ((DoubleConstant) right).Value); + ((DoubleConstant) right).Value); else res = unchecked (((DoubleConstant) left).Value * - ((DoubleConstant) right).Value); + ((DoubleConstant) right).Value); - return new DoubleConstant (res); + return new DoubleConstant (res, left.Location); } else if (left is FloatConstant){ float res; if (ec.ConstantCheckState) res = checked (((FloatConstant) left).Value * - ((FloatConstant) right).Value); + ((FloatConstant) right).Value); else res = unchecked (((FloatConstant) left).Value * - ((FloatConstant) right).Value); + ((FloatConstant) right).Value); - return new FloatConstant (res); + return new FloatConstant (res, left.Location); } else if (left is ULongConstant){ ulong res; if (ec.ConstantCheckState) res = checked (((ULongConstant) left).Value * - ((ULongConstant) right).Value); + ((ULongConstant) right).Value); else res = unchecked (((ULongConstant) left).Value * - ((ULongConstant) right).Value); + ((ULongConstant) right).Value); - return new ULongConstant (res); + return new ULongConstant (res, left.Location); } else if (left is LongConstant){ long res; if (ec.ConstantCheckState) res = checked (((LongConstant) left).Value * - ((LongConstant) right).Value); + ((LongConstant) right).Value); else res = unchecked (((LongConstant) left).Value * - ((LongConstant) right).Value); + ((LongConstant) right).Value); - return new LongConstant (res); + return new LongConstant (res, left.Location); } else if (left is UIntConstant){ uint res; if (ec.ConstantCheckState) res = checked (((UIntConstant) left).Value * - ((UIntConstant) right).Value); + ((UIntConstant) right).Value); else res = unchecked (((UIntConstant) left).Value * - ((UIntConstant) right).Value); + ((UIntConstant) right).Value); - return new UIntConstant (res); + return new UIntConstant (res, left.Location); } else if (left is IntConstant){ int res; if (ec.ConstantCheckState) res = checked (((IntConstant) left).Value * - ((IntConstant) right).Value); + ((IntConstant) right).Value); else res = unchecked (((IntConstant) left).Value * - ((IntConstant) right).Value); + ((IntConstant) right).Value); + + return new IntConstant (res, left.Location); + } else if (left is DecimalConstant) { + decimal res; - return new IntConstant (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 input: " + left); + throw new Exception ( "Unexepected multiply input: " + left); } } catch (OverflowException){ Error_CompileTimeOverflow (loc); @@ -531,7 +756,7 @@ namespace Mono.CSharp { break; case Binary.Operator.Division: - DoConstantNumericPromotions (oper, ref left, ref right, loc); + DoConstantNumericPromotions (ec, oper, ref left, ref right, loc); if (left == null || right == null) return null; @@ -541,77 +766,92 @@ namespace Mono.CSharp { if (ec.ConstantCheckState) res = checked (((DoubleConstant) left).Value / - ((DoubleConstant) right).Value); + ((DoubleConstant) right).Value); else res = unchecked (((DoubleConstant) left).Value / - ((DoubleConstant) right).Value); + ((DoubleConstant) right).Value); - return new DoubleConstant (res); + return new DoubleConstant (res, left.Location); } else if (left is FloatConstant){ float res; if (ec.ConstantCheckState) res = checked (((FloatConstant) left).Value / - ((FloatConstant) right).Value); + ((FloatConstant) right).Value); else res = unchecked (((FloatConstant) left).Value / - ((FloatConstant) right).Value); + ((FloatConstant) right).Value); - return new FloatConstant (res); + return new FloatConstant (res, left.Location); } else if (left is ULongConstant){ ulong res; if (ec.ConstantCheckState) res = checked (((ULongConstant) left).Value / - ((ULongConstant) right).Value); + ((ULongConstant) right).Value); else res = unchecked (((ULongConstant) left).Value / - ((ULongConstant) right).Value); + ((ULongConstant) right).Value); - return new ULongConstant (res); + return new ULongConstant (res, left.Location); } else if (left is LongConstant){ long res; if (ec.ConstantCheckState) res = checked (((LongConstant) left).Value / - ((LongConstant) right).Value); + ((LongConstant) right).Value); else res = unchecked (((LongConstant) left).Value / - ((LongConstant) right).Value); + ((LongConstant) right).Value); - return new LongConstant (res); + return new LongConstant (res, left.Location); } else if (left is UIntConstant){ uint res; if (ec.ConstantCheckState) res = checked (((UIntConstant) left).Value / - ((UIntConstant) right).Value); + ((UIntConstant) right).Value); else res = unchecked (((UIntConstant) left).Value / - ((UIntConstant) right).Value); + ((UIntConstant) right).Value); - return new UIntConstant (res); + return new UIntConstant (res, left.Location); } else if (left is IntConstant){ int res; if (ec.ConstantCheckState) res = checked (((IntConstant) left).Value / - ((IntConstant) right).Value); + ((IntConstant) right).Value); else res = unchecked (((IntConstant) left).Value / - ((IntConstant) right).Value); + ((IntConstant) right).Value); - return new IntConstant (res); + return 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 input: " + left); + throw new Exception ( "Unexepected division input: " + left); } } catch (OverflowException){ Error_CompileTimeOverflow (loc); + + } catch (DivideByZeroException) { + Report.Error (020, loc, "Division by constant zero"); } + break; case Binary.Operator.Modulus: - DoConstantNumericPromotions (oper, ref left, ref right, loc); + DoConstantNumericPromotions (ec, oper, ref left, ref right, loc); if (left == null || right == null) return null; @@ -626,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; @@ -637,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; @@ -648,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; @@ -659,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; @@ -670,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; @@ -681,10 +921,12 @@ 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 input: " + left); + throw new Exception ( "Unexepected modulus input: " + left); } + } catch (DivideByZeroException){ + Report.Error (020, loc, "Division by constant zero"); } catch (OverflowException){ Error_CompileTimeOverflow (loc); } @@ -703,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; @@ -733,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; @@ -754,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; @@ -762,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; @@ -770,17 +1012,30 @@ 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, left.Location); + else if (right is StringConstant) + return new BoolConstant ( + ((StringConstant) right).Value == null, left.Location); + } else if (right is NullLiteral){ + if (left is NullLiteral) + return new BoolConstant (true, left.Location); + else if (left is StringConstant) + return new BoolConstant ( + ((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 (oper, ref left, ref right, loc); + + DoConstantNumericPromotions (ec, oper, ref left, ref right, loc); if (left == null || right == null) return null; @@ -806,21 +1061,34 @@ 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, left.Location); + else if (right is StringConstant) + return new BoolConstant ( + ((StringConstant) right).Value != null, left.Location); + } else if (right is NullLiteral){ + if (left is NullLiteral) + return new BoolConstant (false, left.Location); + else if (left is StringConstant) + return new BoolConstant ( + ((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 (oper, ref left, ref right, loc); + DoConstantNumericPromotions (ec, oper, ref left, ref right, loc); if (left == null || right == null) return null; @@ -846,10 +1114,10 @@ namespace Mono.CSharp { else return null; - return new BoolConstant (bool_res); + return new BoolConstant (bool_res, left.Location); case Binary.Operator.LessThan: - DoConstantNumericPromotions (oper, ref left, ref right, loc); + DoConstantNumericPromotions (ec, oper, ref left, ref right, loc); if (left == null || right == null) return null; @@ -875,10 +1143,10 @@ namespace Mono.CSharp { else return null; - return new BoolConstant (bool_res); + return new BoolConstant (bool_res, left.Location); case Binary.Operator.GreaterThan: - DoConstantNumericPromotions (oper, ref left, ref right, loc); + DoConstantNumericPromotions (ec, oper, ref left, ref right, loc); if (left == null || right == null) return null; @@ -904,10 +1172,10 @@ namespace Mono.CSharp { else return null; - return new BoolConstant (bool_res); + return new BoolConstant (bool_res, left.Location); case Binary.Operator.GreaterThanOrEqual: - DoConstantNumericPromotions (oper, ref left, ref right, loc); + DoConstantNumericPromotions (ec, oper, ref left, ref right, loc); if (left == null || right == null) return null; @@ -933,10 +1201,10 @@ namespace Mono.CSharp { else return null; - return new BoolConstant (bool_res); + return new BoolConstant (bool_res, left.Location); case Binary.Operator.LessThanOrEqual: - DoConstantNumericPromotions (oper, ref left, ref right, loc); + DoConstantNumericPromotions (ec, oper, ref left, ref right, loc); if (left == null || right == null) return null; @@ -962,7 +1230,7 @@ namespace Mono.CSharp { else return null; - return new BoolConstant (bool_res); + return new BoolConstant (bool_res, left.Location); } return null;