* XmlTypeAttribute.cs: added property AnonymousType for 2.0
[mono.git] / mcs / mcs / cfold.cs
index f9cc1d2204e198a9e9baf72f954f89697740e9ac..aba3ad37c485097ae96c089ed69eba1aa676322f 100644 (file)
@@ -141,33 +141,6 @@ namespace Mono.CSharp {
                                        right = right.ToDecimal (loc);
                                return;
                        } else if (left is EnumConstant || right is EnumConstant){
-                               //
-                               // If either operand is an enum constant, the other one must
-                               // be implicitly convertable to that enum's underlying type.
-                               //
-                               EnumConstant match;
-                               Constant other;
-                               if (left is EnumConstant){
-                                       other = right;
-                                       match = (EnumConstant) left;
-                               } else {
-                                       other = left;
-                                       match = (EnumConstant) right;
-                               }
-
-                               bool need_check = (other is EnumConstant) ||
-                                       !(oper == Binary.Operator.Addition || 
-                                         oper == Binary.Operator.Subtraction ||
-                                         (other.IsZeroInteger && other is IntConstant));
-
-                               if (need_check &&
-                                   !Convert.ImplicitConversionExists (ec, match, other.Type)) {
-                                       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)
@@ -201,6 +174,12 @@ namespace Mono.CSharp {
                static public Expression BinaryFold (EmitContext ec, Binary.Operator oper,
                                                     Constant left, Constant right, Location loc)
                {
+                       if (left is NullCast)
+                               return BinaryFold (ec, oper, ((NullCast)left).child, right, loc);
+
+                       if (right is NullCast)
+                               return BinaryFold (ec, oper, left, ((NullCast)right).child, loc);
+
                        Type lt = left.Type;
                        Type rt = right.Type;
                        Type result_type = null;
@@ -223,6 +202,23 @@ namespace Mono.CSharp {
                                        right = ((EnumConstant) right).Child;
                        }
 
+                       if (left is BoolConstant && right is BoolConstant) {
+                               bool lv = ((BoolConstant) left ).Value;
+                               bool rv = ((BoolConstant) right).Value;
+                               switch (oper) {
+                               case Binary.Operator.BitwiseAnd:
+                               case Binary.Operator.LogicalAnd:
+                                       return new BoolConstant (lv && rv, left.Location);
+                               case Binary.Operator.BitwiseOr:
+                               case Binary.Operator.LogicalOr:
+                                       return new BoolConstant (lv || rv, left.Location);
+                               case Binary.Operator.ExclusiveOr:
+                                       return new BoolConstant (lv ^ rv, left.Location);
+                               default:
+                                       throw new InternalErrorException ("Invalid operator on booleans: " + oper);
+                               }
+                       }
+
                        Type wrap_as;
                        Constant result = null;
                        switch (oper){
@@ -554,8 +550,14 @@ namespace Mono.CSharp {
                                        Error_CompileTimeOverflow (loc);
                                }
 
-                               if (wrap_as != null)
-                                       return new EnumConstant (result, wrap_as);
+                               if (wrap_as != null) {
+                                       try {
+                                               return result.TryReduce (ec, wrap_as, loc);
+                                       }
+                                       catch (OverflowException) {
+                                               return null;
+                                       }
+                               }
                                else
                                        return result;
 
@@ -685,10 +687,17 @@ namespace Mono.CSharp {
                                } catch (OverflowException){
                                        Error_CompileTimeOverflow (loc);
                                }
-                               if (wrap_as != null)
-                                       return new EnumConstant (result, wrap_as);
-                               else
-                                       return result;
+
+                               if (wrap_as != null) {
+                                       try {
+                                               return result.TryReduce (ec, wrap_as, loc);
+                                       }
+                                       catch (OverflowException) {
+                                               return null;
+                                       }
+                               }
+
+                               return result;
                                
                        case Binary.Operator.Multiply:
                                DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
@@ -1018,22 +1027,6 @@ namespace Mono.CSharp {
                                Binary.Error_OperatorCannotBeApplied (loc, ">>", lt, rt);
                                break;
 
-                       case Binary.Operator.LogicalAnd:
-                               if (left is BoolConstant && right is BoolConstant){
-                                       return new BoolConstant (
-                                               ((BoolConstant) left).Value &&
-                                               ((BoolConstant) right).Value, left.Location);
-                               }
-                               break;
-
-                       case Binary.Operator.LogicalOr:
-                               if (left is BoolConstant && right is BoolConstant){
-                                       return new BoolConstant (
-                                               ((BoolConstant) left).Value ||
-                                               ((BoolConstant) right).Value, left.Location);
-                               }
-                               break;
-                               
                        case Binary.Operator.Equality:
                                if (left is BoolConstant && right is BoolConstant){
                                        return new BoolConstant (