2009-03-17 Marek Safar <marek.safar@gmail.com>
[mono.git] / mcs / mcs / cfold.cs
index e46b792cdb7c0a8146ff327175b54554102eaf9b..a23a20a122cf186f500363663fb6e52710d62706 100644 (file)
@@ -5,9 +5,9 @@
 //   Miguel de Icaza (miguel@ximian.com)
 //   Marek Safar (marek.safar@seznam.cz)
 //
-// (C) 2002, 2003 Ximian, Inc.
-//
-
+// Copyright 2002, 2003 Ximian, Inc.
+// Copyright 2003-2008, Novell, Inc.
+// 
 using System;
 
 namespace Mono.CSharp {
@@ -20,7 +20,7 @@ namespace Mono.CSharp {
 
                //
                // Performs the numeric promotions on the left and right expresions
-               // and desposits the results on `lc' and `rc'.
+               // and deposits the results on `lc' and `rc'.
                //
                // On success, the types of `lc' and `rc' on output will always match,
                // and the pair will be one of:
@@ -80,7 +80,7 @@ namespace Mono.CSharp {
                                return BinaryFold (ec, oper, ((EmptyConstantCast)left).child, right, loc);
 
                        if (left is SideEffectConstant) {
-                               result = BinaryFold (ec, oper, ((SideEffectConstant) left).left, right, loc);
+                               result = BinaryFold (ec, oper, ((SideEffectConstant) left).value, right, loc);
                                if (result == null)
                                        return null;
                                return new SideEffectConstant (result, left, loc);
@@ -90,7 +90,7 @@ namespace Mono.CSharp {
                                return BinaryFold (ec, oper, left, ((EmptyConstantCast)right).child, loc);
 
                        if (right is SideEffectConstant) {
-                               result = BinaryFold (ec, oper, left, ((SideEffectConstant) right).left, loc);
+                               result = BinaryFold (ec, oper, left, ((SideEffectConstant) right).value, loc);
                                if (result == null)
                                        return null;
                                return new SideEffectConstant (result, right, loc);
@@ -101,8 +101,8 @@ namespace Mono.CSharp {
                        bool bool_res;
 
                        if (lt == TypeManager.bool_type && lt == rt) {
-                               bool lv = ((BoolConstant) left ).Value;
-                               bool rv = ((BoolConstant) right).Value;
+                               bool lv = (bool) left.GetValue ();
+                               bool rv = (bool) right.GetValue ();                     
                                switch (oper) {
                                case Binary.Operator.BitwiseAnd:
                                case Binary.Operator.LogicalAnd:
@@ -254,23 +254,25 @@ namespace Mono.CSharp {
                                break;
 
                        case Binary.Operator.Addition:
+                               if (lt == TypeManager.null_type)
+                                       return right;
+
+                               if (rt == TypeManager.null_type)
+                                       return left;
+
                                //
                                // If both sides are strings, then concatenate, if
                                // one is a string, and the other is not, then defer
                                // to runtime concatenation
                                //
                                if (lt == TypeManager.string_type || rt == TypeManager.string_type){
-                                       if (lt == TypeManager.string_type && rt == TypeManager.string_type)
-                                               return new StringConstant (
-                                                       ((StringConstant) left).Value +
-                                                       ((StringConstant) right).Value, left.Location);
+                                       if (lt == rt)
+                                               return new StringConstant ((string)left.GetValue () + (string)right.GetValue (),
+                                                       left.Location);
                                        
                                        return null;
                                }
 
-                               if (lt == TypeManager.null_type && lt == rt)
-                                       return left;
-
                                //
                                // handle "E operator + (E x, U y)"
                                // handle "E operator + (Y y, E x)"
@@ -382,8 +384,6 @@ namespace Mono.CSharp {
                                                                ((DecimalConstant) right).Value);
 
                                                result = new DecimalConstant (res, left.Location);
-                                       } else {
-                                               throw new Exception ( "Unexepected addition input: " + left);
                                        }
                                } catch (OverflowException){
                                        Error_CompileTimeOverflow (loc);
@@ -782,7 +782,7 @@ namespace Mono.CSharp {
                        case Binary.Operator.LeftShift:
                                IntConstant ic = right.ConvertImplicitly (TypeManager.int32_type) as IntConstant;
                                if (ic == null){
-                                       Binary.Error_OperatorCannotBeApplied (loc, "<<", lt, rt);
+                                       Binary.Error_OperatorCannotBeApplied (left, right, oper, loc);
                                        return null;
                                }
 
@@ -798,7 +798,7 @@ namespace Mono.CSharp {
                                if (left.Type == TypeManager.int32_type)
                                        return new IntConstant (((IntConstant)left).Value << lshift_val, left.Location);
 
-                               Binary.Error_OperatorCannotBeApplied (loc, "<<", lt, rt);
+                               Binary.Error_OperatorCannotBeApplied (left, right, oper, loc);
                                break;
 
                                //
@@ -807,7 +807,7 @@ namespace Mono.CSharp {
                        case Binary.Operator.RightShift:
                                IntConstant sic = right.ConvertImplicitly (TypeManager.int32_type) as IntConstant;
                                if (sic == null){
-                                       Binary.Error_OperatorCannotBeApplied (loc, ">>", lt, rt);
+                                       Binary.Error_OperatorCannotBeApplied (left, right, oper, loc); ;
                                        return null;
                                }
                                int rshift_val = sic.Value;
@@ -822,7 +822,7 @@ namespace Mono.CSharp {
                                if (left.Type == TypeManager.int32_type)
                                        return new IntConstant (((IntConstant)left).Value >> rshift_val, left.Location);
 
-                               Binary.Error_OperatorCannotBeApplied (loc, ">>", lt, rt);
+                               Binary.Error_OperatorCannotBeApplied (left, right, oper, loc);
                                break;
 
                        case Binary.Operator.Equality: