2008-09-17 Marek Safar <marek.safar@gmail.com>
[mono.git] / mcs / mcs / expression.cs
index d56cc097e883b94c3dfb93a4d6e9696c29b5a96e..b3a88cccca53b401678513fbbfe2904bc8d030a2 100644 (file)
@@ -147,6 +147,9 @@ namespace Mono.CSharp {
                // </summary>
                Constant TryReduceConstant (EmitContext ec, Constant e)
                {
+                       if (e is EmptyConstantCast)
+                               return TryReduceConstant (ec, ((EmptyConstantCast) e).child);
+                       
                        if (e is SideEffectConstant) {
                                Constant r = TryReduceConstant (ec, ((SideEffectConstant) e).value);
                                return r == null ? null : new SideEffectConstant (r, e, r.Location);
@@ -1140,12 +1143,6 @@ namespace Mono.CSharp {
                        if (expr == null)
                                return null;
 
-                       if (probe_type_expr.Type == TypeManager.void_type) {
-                               // TODO: Void is missing location (ProbeType.Location)
-                               Error_VoidInvalidInTheContext (Location);
-                               return null;
-                       }
-
                        if ((probe_type_expr.Type.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute) {
                                Report.Error (-244, loc, "The `{0}' operator cannot be applied to an operand of a static type",
                                        OperatorName);
@@ -1468,9 +1465,6 @@ namespace Mono.CSharp {
                        this.target_type = cast_type;
                        this.expr = expr;
                        this.loc = loc;
-
-                       if (target_type == TypeManager.system_void_expr)
-                               Error_VoidInvalidInTheContext (loc);
                }
 
                public Expression TargetType {
@@ -1563,11 +1557,13 @@ namespace Mono.CSharp {
 
                        type = texpr.Type;
 
-                       if (type == TypeManager.void_type) {
-                               Error_VoidInvalidInTheContext (loc);
-                               return null;
+                       if ((type.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute) {
+                               Report.Error (-244, loc, "The `default value' operator cannot be applied to an operand of a static type");
                        }
 
+                       if (type.IsPointer)
+                               return new NullLiteral (Location).ConvertImplicitly (type);
+
                        if (TypeManager.IsReferenceType (type)) {
                                return new EmptyConstantCast (new NullLiteral (Location), type);
 
@@ -2544,13 +2540,14 @@ namespace Mono.CSharp {
                                                return null;
                                        }
 
-                                       if (rc != null) {
-                                               right = left;
-                                               lc = rc;
-                                       }
-
+                                       //
                                        // The result is a constant with side-effect
-                                       return new SideEffectConstant (lc, right, loc);
+                                       //
+                                       Constant side_effect = rc == null ?
+                                               new SideEffectConstant (lc, right, loc) :
+                                               new SideEffectConstant (rc, left, loc);
+
+                                       return ReducedExpression.Create (side_effect, this);
                                }
                        }
 
@@ -3300,7 +3297,8 @@ namespace Mono.CSharp {
                        right.Emit (ec);
 
                        Type t = left.Type;
-                       bool is_unsigned = IsUnsigned (t) || IsFloat (t);
+                       bool is_float = IsFloat (t);
+                       bool is_unsigned = is_float || IsUnsigned (t);
                        
                        switch (oper){
                        case Operator.Equality:
@@ -3319,7 +3317,7 @@ namespace Mono.CSharp {
 
                        case Operator.LessThan:
                                if (on_true)
-                                       if (is_unsigned)
+                                       if (is_unsigned && !is_float)
                                                ig.Emit (OpCodes.Blt_Un, target);
                                        else
                                                ig.Emit (OpCodes.Blt, target);
@@ -3332,7 +3330,7 @@ namespace Mono.CSharp {
 
                        case Operator.GreaterThan:
                                if (on_true)
-                                       if (is_unsigned)
+                                       if (is_unsigned && !is_float)
                                                ig.Emit (OpCodes.Bgt_Un, target);
                                        else
                                                ig.Emit (OpCodes.Bgt, target);
@@ -3345,7 +3343,7 @@ namespace Mono.CSharp {
 
                        case Operator.LessThanOrEqual:
                                if (on_true)
-                                       if (is_unsigned)
+                                       if (is_unsigned && !is_float)
                                                ig.Emit (OpCodes.Ble_Un, target);
                                        else
                                                ig.Emit (OpCodes.Ble, target);
@@ -3359,7 +3357,7 @@ namespace Mono.CSharp {
 
                        case Operator.GreaterThanOrEqual:
                                if (on_true)
-                                       if (is_unsigned)
+                                       if (is_unsigned && !is_float)
                                                ig.Emit (OpCodes.Bge_Un, target);
                                        else
                                                ig.Emit (OpCodes.Bge, target);
@@ -5404,11 +5402,6 @@ namespace Mono.CSharp {
 
                        type = texpr.Type;
 
-                       if (type == TypeManager.void_type) {
-                               Error_VoidInvalidInTheContext (loc);
-                               return null;
-                       }
-
                        if (type.IsPointer) {
                                Report.Error (1919, loc, "Unsafe type `{0}' cannot be used in an object creation expression",
                                        TypeManager.CSharpName (type));
@@ -5988,6 +5981,11 @@ namespace Mono.CSharp {
                                Report.Error (622, loc, "Can only use array initializer expressions to assign to array types. Try using a new expression instead");
                                return false;
                        }
+
+                       if (requested_base_type is VarExpr) {
+                               Report.Error (820, loc, "An implicitly typed local variable declarator cannot use an array initializer");
+                               return false;
+                       }
                        
                        StringBuilder array_qualifier = new StringBuilder (rank);
 
@@ -6666,6 +6664,9 @@ namespace Mono.CSharp {
 
                public bool ResolveBase (EmitContext ec)
                {
+                       if (eclass != ExprClass.Invalid)
+                               return true;
+
                        eclass = ExprClass.Variable;
 
                        if (ec.TypeContainer.CurrentType != null)
@@ -7200,11 +7201,6 @@ namespace Mono.CSharp {
                        if (TypeManager.IsEnumType (type_queried))
                                type_queried = TypeManager.GetEnumUnderlyingType (type_queried);
 
-                       if (type_queried == TypeManager.void_type) {
-                               Expression.Error_VoidInvalidInTheContext (loc);
-                               return null;
-                       }
-
                        int size_of = GetTypeSize (type_queried);
                        if (size_of > 0) {
                                return new IntConstant (size_of, loc);
@@ -8948,17 +8944,6 @@ namespace Mono.CSharp {
                        loc = l;
                }
 
-               public Expression RemoveNullable ()
-               {
-                       if (dim.EndsWith ("?")) {
-                               dim = dim.Substring (0, dim.Length - 1);
-                               if (dim.Length == 0)
-                                       return left;
-                       }
-
-                       return this;
-               }
-
                protected override TypeExpr DoResolveAsTypeStep (IResolveContext ec)
                {
                        TypeExpr lexpr = left.ResolveAsTypeTerminal (ec, false);
@@ -8966,11 +8951,6 @@ namespace Mono.CSharp {
                                return null;
 
                        Type ltype = lexpr.Type;
-                       if ((ltype == TypeManager.void_type) && (dim != "*")) {
-                               Error_VoidInvalidInTheContext (loc);
-                               return null;
-                       }
-
 #if GMCS_SOURCE
                        if ((dim.Length > 0) && (dim [0] == '?')) {
                                TypeExpr nullable = new Nullable.NullableType (left, loc);
@@ -8984,7 +8964,7 @@ namespace Mono.CSharp {
                                return null;
 
                        if (dim.Length != 0 && dim [0] == '[') {
-                               if (ltype == TypeManager.arg_iterator_type || ltype == TypeManager.typed_reference_type) {
+                               if (TypeManager.IsSpecialType (ltype)) {
                                        Report.Error (611, loc, "Array elements cannot be of type `{0}'", TypeManager.CSharpName (ltype));
                                        return null;
                                }