2005-01-31 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mcs / mcs / expression.cs
old mode 100755 (executable)
new mode 100644 (file)
index 1c0f376..7ea0a61
@@ -217,6 +217,10 @@ namespace Mono.CSharp {
                                e = new IntConstant (-((ShortConstant) expr).Value);
                        else if (expr is UShortConstant)
                                e = new IntConstant (-((UShortConstant) expr).Value);
+                       else if (expr is SByteConstant)
+                               e = new IntConstant (-((SByteConstant) expr).Value);
+                       else if (expr is ByteConstant)
+                               e = new IntConstant (-((ByteConstant) expr).Value);
                        return e;
                }
 
@@ -237,7 +241,7 @@ namespace Mono.CSharp {
                                
                        case Operator.UnaryNegation:
                                result = TryReduceNegative (e);
-                               return true;
+                               return result != null;
                                
                        case Operator.LogicalNot:
                                if (expr_type != TypeManager.bool_type) {
@@ -427,13 +431,15 @@ namespace Mono.CSharp {
                                }
 
                                IVariable variable = Expr as IVariable;
-                               if (!ec.InFixedInitializer && ((variable == null) || !variable.VerifyFixed (false))) {
+                               bool is_fixed = variable != null && variable.VerifyFixed (false);
+
+                               if (!ec.InFixedInitializer && !is_fixed) {
                                        Error (212, "You can only take the address of an unfixed expression inside " +
                                               "of a fixed statement initializer");
                                        return null;
                                }
 
-                               if (ec.InFixedInitializer && ((variable != null) && variable.VerifyFixed (false))) {
+                               if (ec.InFixedInitializer && is_fixed) {
                                        Error (213, "You can not fix an already fixed expression");
                                        return null;
                                }
@@ -655,7 +661,7 @@ namespace Mono.CSharp {
        // after semantic analysis (this is so we can take the address
        // of an indirection).
        //
-       public class Indirection : Expression, IMemoryLocation, IAssignMethod {
+       public class Indirection : Expression, IMemoryLocation, IAssignMethod, IVariable {
                Expression expr;
                LocalTemporary temporary;
                bool prepared;
@@ -729,6 +735,21 @@ namespace Mono.CSharp {
                {
                        return "*(" + expr + ")";
                }
+
+               #region IVariable Members
+
+               public VariableInfo VariableInfo {
+                       get {
+                               return null;
+                       }
+               }
+
+               public bool VerifyFixed (bool is_expression)
+               {
+                       return true;
+               }
+
+               #endregion
        }
        
        /// <summary>
@@ -2684,16 +2705,27 @@ namespace Mono.CSharp {
                                }
                        } else
                                left = left.Resolve (ec);
-                       right = right.Resolve (ec);
 
-                       if (left == null || right == null)
+                       if (left == null)
+                               return null;
+
+                       Constant lc = left as Constant;
+                       if (lc != null && lc.Type == TypeManager.bool_type && 
+                               ((oper == Operator.LogicalAnd && (bool)lc.GetValue () == false) ||
+                                (oper == Operator.LogicalOr && (bool)lc.GetValue () == true))) {
+
+                               // TODO: make a sense to resolve unreachable expression as we do for statement
+                               Report.Warning (429, 4, loc, "Unreachable expression code detected");
+                               return left;
+                       }
+
+                       right = right.Resolve (ec);
+                       if (right == null)
                                return null;
 
                        eclass = ExprClass.Value;
 
                        Constant rc = right as Constant;
-                       Constant lc = left as Constant;
-
                        if (rc != null & lc != null){
                                Expression e = ConstantFold.BinaryFold (
                                        ec, oper, lc, rc, loc);
@@ -3398,17 +3430,26 @@ namespace Mono.CSharp {
                                //
                                left.Emit (ec);
                                ig.Emit (OpCodes.Conv_I);
-                               right.Emit (ec);
-                               if (size != 1){
-                                       if (size == 0)
-                                               ig.Emit (OpCodes.Sizeof, element);
-                                       else 
-                                               IntLiteral.EmitInt (ig, size);
-                                       if (rtype == TypeManager.int64_type)
-                                               ig.Emit (OpCodes.Conv_I8);
-                                       else if (rtype == TypeManager.uint64_type)
-                                               ig.Emit (OpCodes.Conv_U8);
-                                       ig.Emit (OpCodes.Mul);
+
+                               Constant right_const = right as Constant;
+                               if (right_const != null && size != 0) {
+                                       Expression ex = ConstantFold.BinaryFold (ec, Binary.Operator.Multiply, new IntConstant (size), right_const, loc);
+                                       if (ex == null)
+                                               return;
+                                       ex.Emit (ec);
+                               } else {
+                                       right.Emit (ec);
+                                       if (size != 1){
+                                               if (size == 0)
+                                                       ig.Emit (OpCodes.Sizeof, element);
+                                               else 
+                                                       IntLiteral.EmitInt (ig, size);
+                                               if (rtype == TypeManager.int64_type)
+                                                       ig.Emit (OpCodes.Conv_I8);
+                                               else if (rtype == TypeManager.uint64_type)
+                                                       ig.Emit (OpCodes.Conv_U8);
+                                               ig.Emit (OpCodes.Mul);
+                                       }
                                }
                                
                                if (rtype == TypeManager.int64_type || rtype == TypeManager.uint64_type)
@@ -3514,13 +3555,12 @@ namespace Mono.CSharp {
                                }
                        }
 
+                       // Dead code optimalization
                        if (expr is BoolConstant){
                                BoolConstant bc = (BoolConstant) expr;
 
-                               if (bc.Value)
-                                       return trueExpr;
-                               else
-                                       return falseExpr;
+                               Report.Warning (429, 4, bc.Value ? falseExpr.Location : trueExpr.Location, "Unreachable expression code detected");
+                               return bc.Value ? trueExpr : falseExpr;
                        }
 
                        return this;
@@ -4201,7 +4241,14 @@ namespace Mono.CSharp {
                                                pr.AddressOf (ec, mode);
                                        }
                                } else {
-                                       ((IMemoryLocation)Expr).AddressOf (ec, mode);
+                                       if (Expr is IMemoryLocation)
+                                               ((IMemoryLocation) Expr).AddressOf (ec, mode);
+                                       else {
+                                               Report.Error (
+                                                       1510, Expr.Location,
+                                                       "An lvalue is required as an argument to out or ref");
+                                               return;
+                                       }
                                }
                        } else
                                Expr.Emit (ec);
@@ -5713,7 +5760,7 @@ namespace Mono.CSharp {
                        if (IsDelegate){
                                RequestedType = (new NewDelegate (type, Arguments, loc)).Resolve (ec);
                                if (RequestedType != null)
-                                       if (!(RequestedType is NewDelegate))
+                                       if (!(RequestedType is DelegateCreation))
                                                throw new Exception ("NewDelegate.Resolve returned a non NewDelegate: " + RequestedType.GetType ());
                                return RequestedType;
                        }
@@ -5763,11 +5810,16 @@ namespace Mono.CSharp {
                                }
 
                                method = Invocation.OverloadResolve (
-                                       ec, (MethodGroupExpr) ml, Arguments, false, loc);
+                                       ec, (MethodGroupExpr) ml, Arguments, true, loc);
                                
                        }
 
-                       if (method == null) { 
+                       if (method == null) {
+                               if (almostMatchedMembers.Count != 0) {
+                                       MemberLookupFailed (ec, type, type, ".ctor", null, loc);
+                                       return null;
+                               }
+
                                 if (!is_struct || Arguments.Count > 0) {
                                        Error (1501, String.Format (
                                            "New invocation: Can not find a constructor in `{0}' for this argument list",
@@ -7040,7 +7092,7 @@ namespace Mono.CSharp {
                        if (sn == null || left == null || left.Type.Name != sn.Name)
                                return false;
 
-                       return RootContext.LookupType (ec.DeclSpace, sn.Name, true, loc) != null;
+                       return ec.DeclSpace.LookupType (sn.Name, true, loc) != null;
                }
                
                // TODO: possible optimalization
@@ -7083,7 +7135,15 @@ namespace Mono.CSharp {
 
                                                object real_value = ((Constant) c.Expr).GetValue ();
 
-                                               return Constantify (real_value, t);
+                                               Expression exp = Constantify (real_value, t);
+
+                                               if (left_is_explicit && !left_is_type && !IdenticalNameAndTypeName (ec, left_original, left, loc)) {
+                                                       Report.SymbolRelatedToPreviousError (c);
+                                                       error176 (loc, c.GetSignatureForError ());
+                                                       return null;
+                                               }
+                                       
+                                               return exp;
                                        }
                                }
 
@@ -7259,12 +7319,12 @@ namespace Mono.CSharp {
                        if (expr == null)
                                return null;
 
-                       if (expr is SimpleName){
-                               SimpleName child_expr = (SimpleName) expr;
-
-                               Expression new_expr = new SimpleName (child_expr.Name, Identifier, loc);
-
-                               return new_expr.Resolve (ec, flags);
+                       if (expr is Namespace) {
+                               Namespace ns = (Namespace) expr;
+                               FullNamedExpression retval = ns.Lookup (ec.DeclSpace, Identifier, loc);
+                               if (retval == null)
+                                       Report.Error (234, loc, "The type or namespace name `{0}' could not be found in namespace `{1}'", Identifier, ns.FullName);
+                               return retval;
                        }
                                        
                        //
@@ -7328,7 +7388,8 @@ namespace Mono.CSharp {
                                return null;
 
                        if (member_lookup is TypeExpr) {
-                               if (!(expr is TypeExpr) && !(expr is SimpleName)) {
+                               if (!(expr is TypeExpr) && 
+                                   !IdenticalNameAndTypeName (ec, original, expr, loc)) {
                                        Error (572, "Can't reference type `" + Identifier + "' through an expression; try `" +
                                               member_lookup.Type + "' instead");
                                        return null;
@@ -7354,47 +7415,32 @@ namespace Mono.CSharp {
 
                public override Expression DoResolve (EmitContext ec)
                {
-                       return DoResolve (ec, null, ResolveFlags.VariableOrValue |
-                                         ResolveFlags.SimpleName | ResolveFlags.Type);
+                       return DoResolve (ec, null, ResolveFlags.VariableOrValue | ResolveFlags.Type);
                }
 
                public override Expression DoResolveLValue (EmitContext ec, Expression right_side)
                {
-                       return DoResolve (ec, right_side, ResolveFlags.VariableOrValue |
-                                         ResolveFlags.SimpleName | ResolveFlags.Type);
+                       return DoResolve (ec, right_side, ResolveFlags.VariableOrValue | ResolveFlags.Type);
                }
 
-               public override Expression ResolveAsTypeStep (EmitContext ec)
+               public override FullNamedExpression ResolveAsTypeStep (EmitContext ec)
                {
-                       string fname = null;
-                       MemberAccess full_expr = this;
-                       while (full_expr != null) {
-                               if (fname != null)
-                                       fname = String.Concat (full_expr.Identifier, ".", fname);
-                               else
-                                       fname = full_expr.Identifier;
-
-                               if (full_expr.Expr is SimpleName) {
-                                       string full_name = String.Concat (((SimpleName) full_expr.Expr).Name, ".", fname);
-                                       Type fully_qualified = ec.DeclSpace.FindType (loc, full_name);
-                                       if (fully_qualified != null)
-                                               return new TypeExpression (fully_qualified, loc);
-                               }
-
-                               full_expr = full_expr.Expr as MemberAccess;
-                       }
+                       return ResolveNamespaceOrType (ec, false);
+               }
 
-                       Expression new_expr = expr.ResolveAsTypeStep (ec);
+               public FullNamedExpression ResolveNamespaceOrType (EmitContext ec, bool silent)
+               {
+                       FullNamedExpression new_expr = expr.ResolveAsTypeStep (ec);
 
                        if (new_expr == null)
                                return null;
 
-                       if (new_expr is SimpleName){
-                               SimpleName child_expr = (SimpleName) new_expr;
-                               
-                               new_expr = new SimpleName (child_expr.Name, Identifier, loc);
-
-                               return new_expr.ResolveAsTypeStep (ec);
+                       if (new_expr is Namespace) {
+                               Namespace ns = (Namespace) new_expr;
+                               FullNamedExpression retval = ns.Lookup (ec.DeclSpace, Identifier, loc);
+                               if (!silent && retval == null)
+                                       Report.Error (234, loc, "The type or namespace name `{0}' could not be found in namespace `{1}'", Identifier, ns.FullName);
+                               return retval;
                        }
 
                        Type expr_type = new_expr.Type;
@@ -7405,17 +7451,21 @@ namespace Mono.CSharp {
                                return null;
                        }
                        
-                       Expression member_lookup;
-                       member_lookup = MemberLookupFinal (ec, expr_type, expr_type, Identifier, loc);
-                       if (member_lookup == null)
+                       Expression member_lookup = MemberLookupFinal (ec, expr_type, expr_type, Identifier, loc);
+                       if (!silent && member_lookup == null) {
+                               Report.Error (234, loc, "The type name `{0}' could not be found in type `{1}'", 
+                                             Identifier, new_expr.FullName);
                                return null;
+                       }
 
-                       if (member_lookup is TypeExpr){
-                               member_lookup.Resolve (ec, ResolveFlags.Type);
-                               return member_lookup;
+                       if (!(member_lookup is TypeExpr)) {
+                               Report.Error (118, loc, "'{0}.{1}' denotes a '{2}', where a type was expected",
+                                             new_expr.FullName, Identifier, member_lookup.ExprClassName ());
+                               return null;
                        } 
 
-                       return null;                    
+                       member_lookup = member_lookup.Resolve (ec, ResolveFlags.Type);
+                       return (member_lookup as TypeExpr);
                }
 
                public override void Emit (EmitContext ec)
@@ -8565,9 +8615,9 @@ namespace Mono.CSharp {
                                //
                                // For now, fall back to the full lookup in that case.
                                //
-                               type = RootContext.LookupType (
-                                       ec.DeclSpace, cname, false, loc);
-
+                               FullNamedExpression e = ec.DeclSpace.LookupType (cname, false, loc);
+                               if (e is TypeExpr)
+                                       type = ((TypeExpr) e).ResolveType (ec);
                                if (type == null)
                                        return null;
                        }
@@ -8576,6 +8626,12 @@ namespace Mono.CSharp {
                                UnsafeError (loc);
                                return null;
                        }
+
+                       if (type.IsArray && (type.GetElementType () == TypeManager.arg_iterator_type ||
+                               type.GetElementType () == TypeManager.typed_reference_type)) {
+                               Report.Error (611, loc, "Array elements cannot be of type '{0}'", TypeManager.CSharpName (type.GetElementType ()));
+                               return null;
+                       }
                        
                        eclass = ExprClass.Type;
                        return this;
@@ -8586,6 +8642,12 @@ namespace Mono.CSharp {
                                return left + dim;
                        }
                }
+
+               public override string FullName {
+                       get {
+                               return type.FullName;
+                       }
+               }
        }
 
        //