2009-01-23 Marek Safar <marek.safar@gmail.com>
[mono.git] / mcs / mcs / expression.cs
index 0331d60789f6b94621480699541dd157646f7c70..93e4db14fc4def3eaea94eb2b4a143ddf83868b1 100644 (file)
@@ -91,8 +91,8 @@ namespace Mono.CSharp {
 
                public ParenthesizedExpression (Expression expr)
                {
-                       this.Expr = expr;
-                       this.loc = expr.Location;
+                       Expr = expr;
+                       loc = expr.Location;
                }
 
                public override Expression CreateExpressionTree (EmitContext ec)
@@ -106,6 +106,11 @@ namespace Mono.CSharp {
                        return Expr;
                }
 
+               public override Expression DoResolveLValue (EmitContext ec, Expression right_side)
+               {
+                       return Expr.DoResolveLValue (ec, right_side);
+               }
+
                public override void Emit (EmitContext ec)
                {
                        throw new Exception ("Should not happen");
@@ -134,11 +139,11 @@ namespace Mono.CSharp {
                public Expression Expr;
                Expression enum_conversion;
 
-               public Unary (Operator op, Expression expr, Location loc)
+               public Unary (Operator op, Expression expr)
                {
-                       this.Oper = op;
-                       this.Expr = expr;
-                       this.loc = loc;
+                       Oper = op;
+                       Expr = expr;
+                       loc = expr.Location;
                }
 
                // <summary>
@@ -158,149 +163,145 @@ namespace Mono.CSharp {
                        Type expr_type = e.Type;
                        
                        switch (Oper){
-                               case Operator.UnaryPlus:
-                                       // Unary numeric promotions
-                                       if (expr_type == TypeManager.byte_type)
-                                               return new IntConstant (((ByteConstant)e).Value, e.Location);
-                                       if (expr_type == TypeManager.sbyte_type)
-                                               return new IntConstant (((SByteConstant)e).Value, e.Location);
-                                       if (expr_type == TypeManager.short_type)
-                                               return new IntConstant (((ShortConstant)e).Value, e.Location);
-                                       if (expr_type == TypeManager.ushort_type)
-                                               return new IntConstant (((UShortConstant)e).Value, e.Location);
-                                       if (expr_type == TypeManager.char_type)
-                                               return new IntConstant (((CharConstant)e).Value, e.Location);
-
-                                       // Predefined operators
-                                       if (expr_type == TypeManager.int32_type || expr_type == TypeManager.uint32_type ||
-                                               expr_type == TypeManager.int64_type || expr_type == TypeManager.uint64_type ||
-                                               expr_type == TypeManager.float_type || expr_type == TypeManager.double_type ||
-                                               expr_type == TypeManager.decimal_type)
-                                       {
-                                               return e;
-                                       }
-
-                                       return null;
+                       case Operator.UnaryPlus:
+                               // Unary numeric promotions
+                               if (expr_type == TypeManager.byte_type)
+                                       return new IntConstant (((ByteConstant)e).Value, e.Location);
+                               if (expr_type == TypeManager.sbyte_type)
+                                       return new IntConstant (((SByteConstant)e).Value, e.Location);
+                               if (expr_type == TypeManager.short_type)
+                                       return new IntConstant (((ShortConstant)e).Value, e.Location);
+                               if (expr_type == TypeManager.ushort_type)
+                                       return new IntConstant (((UShortConstant)e).Value, e.Location);
+                               if (expr_type == TypeManager.char_type)
+                                       return new IntConstant (((CharConstant)e).Value, e.Location);
                                
-                               case Operator.UnaryNegation:
-                                       // Unary numeric promotions
-                                       if (expr_type == TypeManager.byte_type)
-                                               return new IntConstant (-((ByteConstant)e).Value, e.Location);
-                                       if (expr_type == TypeManager.sbyte_type)
-                                               return new IntConstant (-((SByteConstant)e).Value, e.Location);
-                                       if (expr_type == TypeManager.short_type)
-                                               return new IntConstant (-((ShortConstant)e).Value, e.Location);
-                                       if (expr_type == TypeManager.ushort_type)
-                                               return new IntConstant (-((UShortConstant)e).Value, e.Location);
-                                       if (expr_type == TypeManager.char_type)
-                                               return new IntConstant (-((CharConstant)e).Value, e.Location);
-
-                                       // Predefined operators
-                                       if (expr_type == TypeManager.int32_type) {
-                                               int value = ((IntConstant)e).Value;
-                                               if (value == int.MinValue) {
-                                                       if (ec.ConstantCheckState) {
-                                                               ConstantFold.Error_CompileTimeOverflow (loc);
-                                                               return null;
-                                                       }
-                                                       return e;
-                                               }
-                                               return new IntConstant (-value, e.Location);
-                                       }
-                                       if (expr_type == TypeManager.int64_type) {
-                                               long value = ((LongConstant)e).Value;
-                                               if (value == long.MinValue) {
-                                                       if (ec.ConstantCheckState) {
-                                                               ConstantFold.Error_CompileTimeOverflow (loc);
-                                                               return null;
-                                                       }
-                                                       return e;
+                               // Predefined operators
+                               if (expr_type == TypeManager.int32_type || expr_type == TypeManager.uint32_type ||
+                                   expr_type == TypeManager.int64_type || expr_type == TypeManager.uint64_type ||
+                                   expr_type == TypeManager.float_type || expr_type == TypeManager.double_type ||
+                                   expr_type == TypeManager.decimal_type) {
+                                       return e;
+                               }
+                               
+                               return null;
+                               
+                       case Operator.UnaryNegation:
+                               // Unary numeric promotions
+                               if (expr_type == TypeManager.byte_type)
+                                       return new IntConstant (-((ByteConstant)e).Value, e.Location);
+                               if (expr_type == TypeManager.sbyte_type)
+                                       return new IntConstant (-((SByteConstant)e).Value, e.Location);
+                               if (expr_type == TypeManager.short_type)
+                                       return new IntConstant (-((ShortConstant)e).Value, e.Location);
+                               if (expr_type == TypeManager.ushort_type)
+                                       return new IntConstant (-((UShortConstant)e).Value, e.Location);
+                               if (expr_type == TypeManager.char_type)
+                                       return new IntConstant (-((CharConstant)e).Value, e.Location);
+                               
+                               // Predefined operators
+                               if (expr_type == TypeManager.int32_type) {
+                                       int value = ((IntConstant)e).Value;
+                                       if (value == int.MinValue) {
+                                               if (ec.ConstantCheckState) {
+                                                       ConstantFold.Error_CompileTimeOverflow (loc);
+                                                       return null;
                                                }
-                                               return new LongConstant (-value, e.Location);
+                                               return e;
                                        }
-
-                                       if (expr_type == TypeManager.uint32_type) {
-                                               UIntLiteral uil = e as UIntLiteral;
-                                               if (uil != null) {
-                                                       if (uil.Value == 2147483648)
-                                                               return new IntLiteral (int.MinValue, e.Location);
-                                                       return new LongLiteral (-uil.Value, e.Location);
+                                       return new IntConstant (-value, e.Location);
+                               }
+                               if (expr_type == TypeManager.int64_type) {
+                                       long value = ((LongConstant)e).Value;
+                                       if (value == long.MinValue) {
+                                               if (ec.ConstantCheckState) {
+                                                       ConstantFold.Error_CompileTimeOverflow (loc);
+                                                       return null;
                                                }
-                                               return new LongConstant (-((UIntConstant)e).Value, e.Location);
-                                       }
-
-                                       if (expr_type == TypeManager.uint64_type) {
-                                               ULongLiteral ull = e as ULongLiteral;
-                                               if (ull != null && ull.Value == 9223372036854775808)
-                                                       return new LongLiteral (long.MinValue, e.Location);
-                                               return null;
+                                               return e;
                                        }
-
-                                       if (expr_type == TypeManager.float_type) {
-                                               FloatLiteral fl = e as FloatLiteral;
-                                               // For better error reporting
-                                               if (fl != null) {
-                                                       fl.Value = -fl.Value;
-                                                       return fl;
-                                               }
-                                               return new FloatConstant (-((FloatConstant)e).Value, e.Location);
+                                       return new LongConstant (-value, e.Location);
+                               }
+                               
+                               if (expr_type == TypeManager.uint32_type) {
+                                       UIntLiteral uil = e as UIntLiteral;
+                                       if (uil != null) {
+                                               if (uil.Value == 2147483648)
+                                                       return new IntLiteral (int.MinValue, e.Location);
+                                               return new LongLiteral (-uil.Value, e.Location);
                                        }
-                                       if (expr_type == TypeManager.double_type) {
-                                               DoubleLiteral dl = e as DoubleLiteral;
-                                               // For better error reporting
-                                               if (dl != null) {
-                                                       dl.Value = -dl.Value;
-                                                       return dl;
-                                               }
+                                       return new LongConstant (-((UIntConstant)e).Value, e.Location);
+                               }
+                               
+                               if (expr_type == TypeManager.uint64_type) {
+                                       ULongLiteral ull = e as ULongLiteral;
+                                       if (ull != null && ull.Value == 9223372036854775808)
+                                               return new LongLiteral (long.MinValue, e.Location);
+                                       return null;
+                               }
+                               
+                               if (expr_type == TypeManager.float_type) {
+                                       FloatLiteral fl = e as FloatLiteral;
+                                       // For better error reporting
+                                       if (fl != null)
+                                               return new FloatLiteral (-fl.Value, e.Location);
 
-                                               return new DoubleConstant (-((DoubleConstant)e).Value, e.Location);
-                                       }
-                                       if (expr_type == TypeManager.decimal_type)
-                                               return new DecimalConstant (-((DecimalConstant)e).Value, e.Location);
+                                       return new FloatConstant (-((FloatConstant)e).Value, e.Location);
+                               }
+                               if (expr_type == TypeManager.double_type) {
+                                       DoubleLiteral dl = e as DoubleLiteral;
+                                       // For better error reporting
+                                       if (dl != null)
+                                               return new DoubleLiteral (-dl.Value, e.Location);
 
-                                       return null;
+                                       return new DoubleConstant (-((DoubleConstant)e).Value, e.Location);
+                               }
+                               if (expr_type == TypeManager.decimal_type)
+                                       return new DecimalConstant (-((DecimalConstant)e).Value, e.Location);
                                
-                               case Operator.LogicalNot:
-                                       if (expr_type != TypeManager.bool_type)
-                                               return null;
-                                       
-                                       bool b = (bool)e.GetValue ();
-                                       return new BoolConstant (!b, e.Location);
+                               return null;
                                
-                               case Operator.OnesComplement:
-                                       // Unary numeric promotions
-                                       if (expr_type == TypeManager.byte_type)
-                                               return new IntConstant (~((ByteConstant)e).Value, e.Location);
-                                       if (expr_type == TypeManager.sbyte_type)
-                                               return new IntConstant (~((SByteConstant)e).Value, e.Location);
-                                       if (expr_type == TypeManager.short_type)
-                                               return new IntConstant (~((ShortConstant)e).Value, e.Location);
-                                       if (expr_type == TypeManager.ushort_type)
-                                               return new IntConstant (~((UShortConstant)e).Value, e.Location);
-                                       if (expr_type == TypeManager.char_type)
-                                               return new IntConstant (~((CharConstant)e).Value, e.Location);
-
-                                       // Predefined operators
-                                       if (expr_type == TypeManager.int32_type)
-                                               return new IntConstant (~((IntConstant)e).Value, e.Location);
-                                       if (expr_type == TypeManager.uint32_type)
-                                               return new UIntConstant (~((UIntConstant)e).Value, e.Location);
-                                       if (expr_type == TypeManager.int64_type)
-                                               return new LongConstant (~((LongConstant)e).Value, e.Location);
-                                       if (expr_type == TypeManager.uint64_type){
-                                               return new ULongConstant (~((ULongConstant)e).Value, e.Location);
-                                       }
-                                       if (e is EnumConstant) {
-                                               e = TryReduceConstant (ec, ((EnumConstant)e).Child);
-                                               if (e != null)
-                                                       e = new EnumConstant (e, expr_type);
-                                               return e;
-                                       }
+                       case Operator.LogicalNot:
+                               if (expr_type != TypeManager.bool_type)
                                        return null;
+                               
+                               bool b = (bool)e.GetValue ();
+                               return new BoolConstant (!b, e.Location);
+                               
+                       case Operator.OnesComplement:
+                               // Unary numeric promotions
+                               if (expr_type == TypeManager.byte_type)
+                                       return new IntConstant (~((ByteConstant)e).Value, e.Location);
+                               if (expr_type == TypeManager.sbyte_type)
+                                       return new IntConstant (~((SByteConstant)e).Value, e.Location);
+                               if (expr_type == TypeManager.short_type)
+                                       return new IntConstant (~((ShortConstant)e).Value, e.Location);
+                               if (expr_type == TypeManager.ushort_type)
+                                       return new IntConstant (~((UShortConstant)e).Value, e.Location);
+                               if (expr_type == TypeManager.char_type)
+                                       return new IntConstant (~((CharConstant)e).Value, e.Location);
+                               
+                               // Predefined operators
+                               if (expr_type == TypeManager.int32_type)
+                                       return new IntConstant (~((IntConstant)e).Value, e.Location);
+                               if (expr_type == TypeManager.uint32_type)
+                                       return new UIntConstant (~((UIntConstant)e).Value, e.Location);
+                               if (expr_type == TypeManager.int64_type)
+                                       return new LongConstant (~((LongConstant)e).Value, e.Location);
+                               if (expr_type == TypeManager.uint64_type){
+                                       return new ULongConstant (~((ULongConstant)e).Value, e.Location);
+                               }
+                               if (e is EnumConstant) {
+                                       e = TryReduceConstant (ec, ((EnumConstant)e).Child);
+                                       if (e != null)
+                                               e = new EnumConstant (e, expr_type);
+                                       return e;
+                               }
+                               return null;
                        }
                        throw new Exception ("Can not constant fold: " + Oper.ToString());
                }
-
+               
                protected Expression ResolveOperator (EmitContext ec, Expression expr)
                {
                        eclass = ExprClass.Value;
@@ -451,7 +452,7 @@ namespace Mono.CSharp {
                                return null;
 
                        if (TypeManager.IsNullableValueType (Expr.Type))
-                               return new Nullable.LiftedUnaryOperator (Oper, Expr, loc).Resolve (ec);
+                               return new Nullable.LiftedUnaryOperator (Oper, Expr).Resolve (ec);
 
                        //
                        // Attempt to use a constant folding operation.
@@ -616,17 +617,15 @@ namespace Mono.CSharp {
                                        vi.SetAssigned (ec);
                                }
 
-                               is_fixed = vr.IsFixedVariable;
+                               is_fixed = vr.IsFixed;
                                vr.SetHasAddressTaken ();
 
                                if (vr.IsHoisted) {
                                        AnonymousMethodExpression.Error_AddressOfCapturedVar (vr, loc);
                                }
                        } else {
-                               //
-                               // A pointer-indirection is always fixed
-                               //
-                               is_fixed = Expr is Indirection;
+                               IFixedExpression fe = Expr as IFixedExpression;
+                               is_fixed = fe != null && fe.IsFixed;
                        }
 
                        if (!is_fixed && !ec.InFixedInitializer) {
@@ -754,7 +753,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, IFixedExpression {
                Expression expr;
                LocalTemporary temporary;
                bool prepared;
@@ -853,6 +852,10 @@ namespace Mono.CSharp {
                        return this;
                }
 
+               public bool IsFixed {
+                       get { return true; }
+               }
+
                public override string ToString ()
                {
                        return "*(" + expr + ")";
@@ -898,10 +901,10 @@ namespace Mono.CSharp {
                //
                UserOperatorCall method;
 
-               public UnaryMutator (Mode m, Expression e, Location l)
+               public UnaryMutator (Mode m, Expression e)
                {
                        mode = m;
-                       loc = l;
+                       loc = e.Location;
                        expr = e;
                }
 
@@ -937,6 +940,17 @@ namespace Mono.CSharp {
                Expression ResolveOperator (EmitContext ec)
                {
                        type = expr.Type;
+                       
+                       //
+                       // The operand of the prefix/postfix increment decrement operators
+                       // should be an expression that is classified as a variable,
+                       // a property access or an indexer access
+                       //
+                       if (expr.eclass == ExprClass.Variable || expr.eclass == ExprClass.IndexerAccess || expr.eclass == ExprClass.PropertyAccess) {
+                               expr = expr.ResolveLValue (ec, expr, Location);
+                       } else {
+                               Report.Error (1059, loc, "The operand of an increment or decrement operator must be a variable, property or indexer");
+                       }
 
                        //
                        // Step 1: Perform Operator Overload location
@@ -969,17 +983,6 @@ namespace Mono.CSharp {
                                return null;
                        }
 
-                       //
-                       // The operand of the prefix/postfix increment decrement operators
-                       // should be an expression that is classified as a variable,
-                       // a property access or an indexer access
-                       //
-                       if (expr.eclass == ExprClass.Variable || expr.eclass == ExprClass.IndexerAccess || expr.eclass == ExprClass.PropertyAccess) {
-                               expr = expr.ResolveLValue (ec, expr, Location);
-                       } else {
-                               Report.Error (1059, loc, "The operand of an increment or decrement operator must be a variable, property or indexer");
-                       }
-
                        return this;
                }
 
@@ -1143,12 +1146,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);
@@ -1273,7 +1270,7 @@ namespace Mono.CSharp {
                                t_is_nullable = true;
                        }
 
-                       if (t.IsValueType) {
+                       if (TypeManager.IsStruct (t)) {
                                if (d == t) {
                                        //
                                        // D and T are the same value types but D can be null
@@ -1301,7 +1298,7 @@ namespace Mono.CSharp {
                                if (TypeManager.IsGenericParameter (t))
                                        return ResolveGenericParameter (d, t);
 
-                               if (d.IsValueType) {
+                               if (TypeManager.IsStruct (d)) {
                                        bool temp;
                                        if (Convert.ImplicitBoxingConversionExists (expr, t, out temp))
                                                return CreateConstantResult (true);
@@ -1327,10 +1324,10 @@ namespace Mono.CSharp {
 #if GMCS_SOURCE
                        GenericConstraints constraints = TypeManager.GetTypeParameterConstraints (t);
                        if (constraints != null) {
-                               if (constraints.IsReferenceType && d.IsValueType)
+                               if (constraints.IsReferenceType && TypeManager.IsStruct (d))
                                        return CreateConstantResult (false);
 
-                               if (constraints.IsValueType && !d.IsValueType)
+                               if (constraints.IsValueType && !TypeManager.IsStruct (d))
                                        return CreateConstantResult (TypeManager.IsEqual (d, t));
                        }
 
@@ -1375,16 +1372,20 @@ namespace Mono.CSharp {
                        expr.Emit (ec);
 
                        if (do_isinst)
-                               ig.Emit (OpCodes.Isinst, probe_type_expr.Type);
+                               ig.Emit (OpCodes.Isinst, type);
 
 #if GMCS_SOURCE
-                       if (TypeManager.IsNullableType (type))
+                       if (TypeManager.IsGenericParameter (type) || TypeManager.IsNullableType (type))
                                ig.Emit (OpCodes.Unbox_Any, type);
 #endif
                }
 
                public override Expression DoResolve (EmitContext ec)
                {
+                       // Because expr is modified
+                       if (eclass != ExprClass.Invalid)
+                               return this;
+
                        if (resolved_type == null) {
                                resolved_type = base.DoResolve (ec);
 
@@ -1399,7 +1400,7 @@ namespace Mono.CSharp {
                        if (!TypeManager.IsReferenceType (type) && !TypeManager.IsNullableType (type)) {
                                if (probe_type_expr is TypeParameterExpr) {
                                        Report.Error (413, loc,
-                                               "The `as' operator cannot be used with a non-reference type parameter `{0}'",
+                                               "The `as' operator cannot be used with a non-reference type parameter `{0}'. Consider adding `class' or a reference type constraint",
                                                probe_type_expr.GetSignatureForError ());
                                } else {
                                        Report.Error (77, loc,
@@ -1444,6 +1445,12 @@ namespace Mono.CSharp {
                protected override string OperatorName {
                        get { return "as"; }
                }
+
+               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
+               {
+                       type = storey.MutateType (type);
+                       base.MutateHoistedGenericType (storey);
+               }
        
                public override bool GetAttributableValue (EmitContext ec, Type value_type, out object value)
                {
@@ -1471,9 +1478,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 {
@@ -1566,11 +1570,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);
 
@@ -1813,14 +1819,23 @@ namespace Mono.CSharp {
                                }
 
                                Type r_type = ReturnType;
+                               Expression left_arg, right_arg;
                                if (r_type == null) {
-                                       if (left == null)
+                                       if (left == null) {
+                                               left_arg = b.left;
+                                               right_arg = b.right;
                                                r_type = b.left.Type;
-                                       else 
+                                       } else {
+                                               left_arg = b.right;
+                                               right_arg = b.left;
                                                r_type = b.right.Type;
+                                       }
+                               } else {
+                                       left_arg = b.left;
+                                       right_arg = b.right;
                                }
 
-                               return new PointerArithmetic (b.oper, b.left, b.right, r_type, b.loc).Resolve (ec);
+                               return new PointerArithmetic (b.oper, left_arg, right_arg, r_type, b.loc).Resolve (ec);
                        }
                }
 
@@ -2523,13 +2538,9 @@ namespace Mono.CSharp {
 
                        // The conversion rules are ignored in enum context but why
                        if (!ec.InEnumContext && lc != null && rc != null && (TypeManager.IsEnumType (left.Type) || TypeManager.IsEnumType (right.Type))) {
-                               left = lc = EnumLiftUp (ec, lc, rc, loc);
-                               if (lc == null)
-                                       return null;
-
-                               right = rc = EnumLiftUp (ec, rc, lc, loc);
-                               if (rc == null)
-                                       return null;
+                               lc = EnumLiftUp (ec, lc, rc, loc);
+                               if (lc != null)
+                                       rc = EnumLiftUp (ec, rc, lc, loc);
                        }
 
                        if (rc != null && lc != null) {
@@ -2568,8 +2579,10 @@ namespace Mono.CSharp {
                        }
 
                        if (RootContext.Version >= LanguageVersion.ISO_2 &&
-                               (TypeManager.IsNullableType (left.Type) || TypeManager.IsNullableType (right.Type) ||
-                               (left is NullLiteral && right.Type.IsValueType) || (right is NullLiteral && left.Type.IsValueType)))
+                               ((TypeManager.IsNullableType (left.Type) && (right is NullLiteral || TypeManager.IsNullableType (right.Type) || TypeManager.IsValueType (right.Type))) ||
+                               (TypeManager.IsValueType (left.Type) && right is NullLiteral) ||
+                               (TypeManager.IsNullableType (right.Type) && (left is NullLiteral || TypeManager.IsNullableType (left.Type) || TypeManager.IsValueType (left.Type))) ||
+                               (TypeManager.IsValueType (right.Type) && left is NullLiteral)))
                                return new Nullable.LiftedBinaryOperator (oper, left, right, loc).Resolve (ec);
 
                        return DoResolveCore (ec, left, right);
@@ -2881,7 +2894,7 @@ namespace Mono.CSharp {
                                        return null;
                        } else if (l.IsInterface) {
                                l = TypeManager.object_type;
-                       } else if (l.IsValueType) {
+                       } else if (TypeManager.IsStruct (l)) {
                                return null;
                        }
 
@@ -2891,7 +2904,7 @@ namespace Mono.CSharp {
                                        return null;
                        } else if (r.IsInterface) {
                                r = TypeManager.object_type;
-                       } else if (r.IsValueType) {
+                       } else if (TypeManager.IsStruct (r)) {
                                return null;
                        }
 
@@ -3794,6 +3807,18 @@ namespace Mono.CSharp {
                                //
                                // handle + and - on (pointer op int)
                                //
+                               Constant left_const = left as Constant;
+                               if (left_const != null) {
+                                       //
+                                       // Optimize ((T*)null) pointer operations
+                                       //
+                                       if (left_const.IsDefaultValue) {
+                                               left = EmptyExpression.Null;
+                                       } else {
+                                               left_const = null;
+                                       }
+                               }
+
                                left.Emit (ec);
 
                                Constant right_const = right as Constant;
@@ -3833,12 +3858,14 @@ namespace Mono.CSharp {
                                        Binary.EmitOperatorOpcode (ec, Binary.Operator.Multiply, rtype);
                                }
 
-                               if (rtype == TypeManager.int64_type)
-                                       ig.Emit (OpCodes.Conv_I);
-                               else if (rtype == TypeManager.uint64_type)
-                                       ig.Emit (OpCodes.Conv_U);
+                               if (left_const == null) {
+                                       if (rtype == TypeManager.int64_type)
+                                               ig.Emit (OpCodes.Conv_I);
+                                       else if (rtype == TypeManager.uint64_type)
+                                               ig.Emit (OpCodes.Conv_U);
 
-                               Binary.EmitOperatorOpcode (ec, op, op_type);
+                                       Binary.EmitOperatorOpcode (ec, op, op_type);
+                               }
                        }
                }
        }
@@ -4005,8 +4032,8 @@ namespace Mono.CSharp {
                LocalTemporary temp;
 
                #region Abstract
-               public abstract HoistedVariable HoistedVariable { get; }
-               public abstract bool IsFixedVariable { get; }
+               public abstract HoistedVariable GetHoistedVariable (EmitContext ec);
+               public abstract bool IsFixed { get; }
                public abstract bool IsRef { get; }
                public abstract string Name { get; }
                public abstract void SetHasAddressTaken ();
@@ -4024,8 +4051,9 @@ namespace Mono.CSharp {
 
                public void AddressOf (EmitContext ec, AddressOp mode)
                {
-                       if (IsHoistedEmitRequired (ec)) {
-                               HoistedVariable.AddressOf (ec, mode);
+                       HoistedVariable hv = GetHoistedVariable (ec);
+                       if (hv != null) {
+                               hv.AddressOf (ec, mode);
                                return;
                        }
 
@@ -4057,8 +4085,9 @@ namespace Mono.CSharp {
                {
                        Report.Debug (64, "VARIABLE EMIT", this, Variable, type, IsRef, loc);
 
-                       if (IsHoistedEmitRequired (ec)) {
-                               HoistedVariable.Emit (ec, leave_copy);
+                       HoistedVariable hv = GetHoistedVariable (ec);
+                       if (hv != null) {
+                               hv.Emit (ec, leave_copy);
                                return;
                        }
 
@@ -4085,25 +4114,24 @@ namespace Mono.CSharp {
                public void EmitAssign (EmitContext ec, Expression source, bool leave_copy,
                                        bool prepare_for_load)
                {
-                       Report.Debug (64, "VARIABLE EMIT ASSIGN", this, Variable, type, IsRef,
-                                     source, loc);
-
-                       if (IsHoistedEmitRequired (ec)) {
-                               HoistedVariable.EmitAssign (ec, source, leave_copy, prepare_for_load);
+                       HoistedVariable hv = GetHoistedVariable (ec);
+                       if (hv != null) {
+                               hv.EmitAssign (ec, source, leave_copy, prepare_for_load);
                                return;
                        }
 
-                       if (IsRef)
-                               Variable.Emit (ec);
-
-                       source.Emit (ec);
-
-                       // HACK: variable is already emitted when source is an initializer 
-                       if (source is NewInitialize) {
-                               if (leave_copy) {
-                                       Variable.Emit (ec);
+                       New n_source = source as New;
+                       if (n_source != null) {
+                               if (!n_source.Emit (ec, this)) {
+                                       if (leave_copy)
+                                               EmitLoad (ec);
+                                       return;
                                }
-                               return;
+                       } else {
+                               if (IsRef)
+                                       EmitLoad (ec);
+
+                               source.Emit (ec);
                        }
 
                        if (leave_copy) {
@@ -4126,15 +4154,7 @@ namespace Mono.CSharp {
                }
 
                public bool IsHoisted {
-                       get { return HoistedVariable != null; }
-               }
-
-               protected virtual bool IsHoistedEmitRequired (EmitContext ec)
-               {
-                       //
-                       // Default implementation return true when there is a hosted variable
-                       //
-                       return HoistedVariable != null;
+                       get { return GetHoistedVariable (null) != null; }
                }
 
                public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
@@ -4176,14 +4196,15 @@ namespace Mono.CSharp {
                        get { return local_info.VariableInfo; }
                }
 
-               public override HoistedVariable HoistedVariable {
-                       get { return local_info.HoistedVariableReference; }
+               public override HoistedVariable GetHoistedVariable (EmitContext ec)
+               {
+                       return local_info.HoistedVariableReference;
                }
 
                //              
                // A local variable is always fixed
                //
-               public override bool IsFixedVariable {
+               public override bool IsFixed {
                        get { return true; }
                }
 
@@ -4346,12 +4367,10 @@ namespace Mono.CSharp {
        /// </summary>
        public class ParameterReference : VariableReference {
                readonly ToplevelParameterInfo pi;
-               readonly ToplevelBlock referenced;
 
-               public ParameterReference (ToplevelBlock referenced, ToplevelParameterInfo pi, Location loc)
+               public ParameterReference (ToplevelParameterInfo pi, Location loc)
                {
                        this.pi = pi;
-                       this.referenced = referenced;
                        this.loc = loc;
                }
 
@@ -4363,15 +4382,16 @@ namespace Mono.CSharp {
                        get { return pi.Parameter.ModFlags == Parameter.Modifier.OUT; }
                }
 
-               public override HoistedVariable HoistedVariable {
-                       get { return pi.Parameter.HoistedVariableReference; }
+               public override HoistedVariable GetHoistedVariable (EmitContext ec)
+               {
+                       return pi.Parameter.HoistedVariableReference;
                }
 
                //
                // A ref or out parameter is classified as a moveable variable, even 
                // if the argument given for the parameter is a fixed variable
                //              
-               public override bool IsFixedVariable {
+               public override bool IsFixed {
                        get { return !IsRef; }
                }
 
@@ -4424,24 +4444,38 @@ namespace Mono.CSharp {
                        if (am == null)
                                return true;
 
-                       ToplevelBlock declared = pi.Block;
-                       if (declared != referenced) {
-                               if (IsRef) {
-                                       Report.Error (1628, loc,
-                                               "Parameter `{0}' cannot be used inside `{1}' when using `ref' or `out' modifier",
-                                               Name, am.ContainerType);
-                                       return false;
+                       Block b = ec.CurrentBlock;
+                       while (b != null) {
+                               IParameterData[] p = b.Toplevel.Parameters.FixedParameters;
+                               for (int i = 0; i < p.Length; ++i) {
+                                       if (p [i] != Parameter)
+                                               continue;
+
+                                       //
+                                       // Skip closest anonymous method parameters
+                                       //
+                                       if (b == ec.CurrentBlock && !am.IsIterator)
+                                               return true;
+
+                                       if (IsRef) {
+                                               Report.Error (1628, loc,
+                                                       "Parameter `{0}' cannot be used inside `{1}' when using `ref' or `out' modifier",
+                                                       Name, am.ContainerType);
+                                       }
+
+                                       b = null;
+                                       break;
                                }
-                       } else {
-                               if (!am.IsIterator)
-                                       return true;
+
+                               if (b != null)
+                                       b = b.Toplevel.Parent;
                        }
 
-                       if (ec.IsVariableCapturingRequired) {
-                               if (pi.Parameter.HasAddressTaken)
-                                       AnonymousMethodExpression.Error_AddressOfCapturedVar (this, loc);
+                       if (pi.Parameter.HasAddressTaken)
+                               AnonymousMethodExpression.Error_AddressOfCapturedVar (this, loc);
 
-                               AnonymousMethodStorey storey = declared.CreateAnonymousMethodStorey (ec);
+                       if (ec.IsVariableCapturingRequired) {
+                               AnonymousMethodStorey storey = pi.Block.CreateAnonymousMethodStorey (ec);
                                storey.CaptureParameter (ec, this);
                        }
 
@@ -4459,7 +4493,7 @@ namespace Mono.CSharp {
                        if (pr == null)
                                return false;
 
-                       return Name == pr.Name && referenced == pr.referenced;
+                       return Name == pr.Name;
                }
                
                protected override void CloneTo (CloneContext clonectx, Expression target)
@@ -4469,8 +4503,9 @@ namespace Mono.CSharp {
 
                public override Expression CreateExpressionTree (EmitContext ec)
                {
-                       if (IsHoistedEmitRequired (ec))
-                               return HoistedVariable.CreateExpressionTree (ec);
+                       HoistedVariable hv = GetHoistedVariable (ec);
+                       if (hv != null)
+                               return hv.CreateExpressionTree (ec);
 
                        return Parameter.ExpressionTreeVariableReference ();
                }
@@ -4562,14 +4597,14 @@ namespace Mono.CSharp {
                {
                        get {
                                switch (ArgType) {
-                                       case AType.Out:
-                                               return Parameter.Modifier.OUT;
-
-                                       case AType.Ref:
-                                               return Parameter.Modifier.REF;
-
-                                       default:
-                                               return Parameter.Modifier.NONE;
+                               case AType.Out:
+                                       return Parameter.Modifier.OUT;
+                                       
+                               case AType.Ref:
+                                       return Parameter.Modifier.REF;
+                                       
+                               default:
+                                       return Parameter.Modifier.NONE;
                                }
                        }
                }
@@ -4792,6 +4827,10 @@ namespace Mono.CSharp {
                                                MemberExpr.error176 (loc, mg.GetSignatureForError ());
                                                return null;
                                        }
+                               } else {
+                                       if (iexpr == null) {
+                                               SimpleName.Error_ObjectRefRequired (ec, loc, mg.GetSignatureForError ());
+                                       }
                                }
                        }
 
@@ -4810,7 +4849,7 @@ namespace Mono.CSharp {
                                return null;
                        }
 
-                       if (Arguments == null && method.DeclaringType == TypeManager.object_type && method.Name == "Finalize") {
+                       if (Arguments == null && method.DeclaringType == TypeManager.object_type && method.Name == Destructor.MetadataName) {
                                if (mg.IsBase)
                                        Report.Error (250, loc, "Do not directly call your base class Finalize method. It is called automatically from your destructor");
                                else
@@ -4963,32 +5002,13 @@ namespace Mono.CSharp {
 
                        Type decl_type = method.DeclaringType;
 
-                       if (!ec.IsInObsoleteScope) {
-                               //
-                               // This checks ObsoleteAttribute on the method and on the declaring type
-                               //
-                               ObsoleteAttribute oa = AttributeTester.GetMethodObsoleteAttribute (method);
-                               if (oa != null)
-                                       AttributeTester.Report_ObsoleteMessage (oa, TypeManager.CSharpSignature (method), loc);
-
-                               oa = AttributeTester.GetObsoleteAttribute (method.DeclaringType);
-                               if (oa != null) {
-                                       AttributeTester.Report_ObsoleteMessage (oa, method.DeclaringType.FullName, loc);
-                               }
-                       }
-
                        if (IsMethodExcluded (method, loc))
                                return;
                        
                        bool is_static = method.IsStatic;
                        if (!is_static){
-                               if (instance_expr == EmptyExpression.Null) {
-                                       SimpleName.Error_ObjectRefRequired (ec, loc, TypeManager.CSharpSignature (method));
-                                       return;
-                               }
-
                                this_call = instance_expr is This;
-                               if (decl_type.IsValueType || (!this_call && instance_expr.Type.IsValueType))
+                               if (TypeManager.IsStruct (decl_type) || TypeManager.IsEnumType (decl_type) || (!this_call && TypeManager.IsStruct (instance_expr.Type)))
                                        struct_call = true;
 
                                //
@@ -5001,12 +5021,12 @@ namespace Mono.CSharp {
                                        //
                                        // Push the instance expression
                                        //
-                                       if (TypeManager.IsValueType (iexpr_type)) {
+                                       if (TypeManager.IsValueType (iexpr_type) || TypeManager.IsGenericParameter (iexpr_type)) {
                                                //
                                                // Special case: calls to a function declared in a 
                                                // reference-type with a value-type argument need
                                                // to have their value boxed.
-                                               if (decl_type.IsValueType ||
+                                               if (TypeManager.IsStruct (decl_type) ||
                                                    TypeManager.IsGenericParameter (iexpr_type)) {
                                                        //
                                                        // If the expression implements IMemoryLocation, then
@@ -5051,16 +5071,17 @@ namespace Mono.CSharp {
                        if (!omit_args)
                                EmitArguments (ec, Arguments, dup_args, this_arg);
 
-#if GMCS_SOURCE
-                       if ((instance_expr != null) && (instance_expr.Type.IsGenericParameter))
-                               ig.Emit (OpCodes.Constrained, instance_expr.Type);
-#endif
-
                        OpCode call_op;
-                       if (is_static || struct_call || is_base || (this_call && !method.IsVirtual))
+                       if (is_static || struct_call || is_base || (this_call && !method.IsVirtual)) {
                                call_op = OpCodes.Call;
-                       else
+                       } else {
                                call_op = OpCodes.Callvirt;
+                               
+#if GMCS_SOURCE
+                               if ((instance_expr != null) && (instance_expr.Type.IsGenericParameter))
+                                       ig.Emit (OpCodes.Constrained, instance_expr.Type);
+#endif
+                       }
 
                        if ((method.CallingConvention & CallingConventions.VarArgs) != 0) {
                                Type[] varargs_types = GetVarargsTypes (method, Arguments);
@@ -5118,7 +5139,7 @@ namespace Mono.CSharp {
                        }
                }
        }
-
+/*
        //
        // It's either a cast or delegate invocation
        //
@@ -5224,18 +5245,8 @@ namespace Mono.CSharp {
                        target.argument = argument.Clone (clonectx);
                }
        }
+*/
 
-       //
-       // This class is used to "disable" the code generation for the
-       // temporary variable when initializing value types.
-       //
-       sealed class EmptyAddressOf : EmptyExpression, IMemoryLocation {
-               public void AddressOf (EmitContext ec, AddressOp Mode)
-               {
-                       // nothing
-               }
-       }
-       
        /// <summary>
        ///    Implements the new expression 
        /// </summary>
@@ -5247,17 +5258,11 @@ namespace Mono.CSharp {
                // but if `type' is not null, it *might* contain a NewDelegate
                // (because of field multi-initialization)
                //
-               public Expression RequestedType;
+               Expression RequestedType;
 
                MethodGroupExpr method;
 
-               //
-               // If set, the new expression is for a value_target, and
-               // we will not leave anything on the stack.
-               //
-               protected Expression value_target;
-               protected bool value_target_set;
-               bool is_type_parameter = false;
+               bool is_type_parameter;
                
                public New (Expression requested_type, ArrayList arguments, Location l)
                {
@@ -5266,45 +5271,6 @@ namespace Mono.CSharp {
                        loc = l;
                }
 
-               public bool SetTargetVariable (Expression value)
-               {
-                       value_target = value;
-                       value_target_set = true;
-                       if (!(value_target is IMemoryLocation)){
-                               Error_UnexpectedKind (null, "variable", loc);
-                               return false;
-                       }
-                       return true;
-               }
-
-               //
-               // This function is used to disable the following code sequence for
-               // value type initialization:
-               //
-               // AddressOf (temporary)
-               // Construct/Init
-               // LoadTemporary
-               //
-               // Instead the provide will have provided us with the address on the
-               // stack to store the results.
-               //
-               static Expression MyEmptyExpression;
-               
-               public void DisableTemporaryValueType ()
-               {
-                       if (MyEmptyExpression == null)
-                               MyEmptyExpression = new EmptyAddressOf ();
-
-                       //
-                       // To enable this, look into:
-                       // test-34 and test-89 and self bootstrapping.
-                       //
-                       // For instance, we can avoid a copy by using `newobj'
-                       // instead of Call + Push-temp on value types.
-//                     value_target = MyEmptyExpression;
-               }
-
-
                /// <summary>
                /// Converts complex core type syntax like 'new int ()' to simple constant
                /// </summary>
@@ -5409,11 +5375,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));
@@ -5421,9 +5382,9 @@ namespace Mono.CSharp {
                        }
 
                        if (Arguments == null) {
-                               Expression c = Constantify (type);
+                               Constant c = Constantify (type);
                                if (c != null)
-                                       return c;
+                                       return ReducedExpression.Create (c, this);
                        }
 
                        if (TypeManager.IsDelegateType (type)) {
@@ -5483,7 +5444,7 @@ namespace Mono.CSharp {
                                return null;
                        }
 
-                       bool is_struct = type.IsValueType;
+                       bool is_struct = TypeManager.IsStruct (type);
                        eclass = ExprClass.Value;
 
                        //
@@ -5566,14 +5527,10 @@ namespace Mono.CSharp {
                }
 
                //
-               // This DoEmit can be invoked in two contexts:
+               // This Emit can be invoked in two contexts:
                //    * As a mechanism that will leave a value on the stack (new object)
                //    * As one that wont (init struct)
                //
-               // You can control whether a value is required on the stack by passing
-               // need_value_on_stack.  The code *might* leave a value on the stack
-               // so it must be popped manually
-               //
                // If we are dealing with a ValueType, we have a few
                // situations to deal with:
                //
@@ -5589,68 +5546,75 @@ namespace Mono.CSharp {
                //
                // Returns whether a value is left on the stack
                //
-               bool DoEmit (EmitContext ec, bool need_value_on_stack)
+               // *** Implementation note ***
+               //
+               // To benefit from this optimization, each assignable expression
+               // has to manually cast to New and call this Emit.
+               //
+               // TODO: It's worth to implement it for arrays and fields
+               //
+               public virtual bool Emit (EmitContext ec, IMemoryLocation target)
                {
+                       if (is_type_parameter)
+                               return DoEmitTypeParameter (ec);
+
                        bool is_value_type = TypeManager.IsValueType (type);
                        ILGenerator ig = ec.ig;
+                       VariableReference vr = target as VariableReference;
 
-                       if (is_value_type){
-                               IMemoryLocation ml;
-
-                               // Allow DoEmit() to be called multiple times.
-                               // We need to create a new LocalTemporary each time since
-                               // you can't share LocalBuilders among ILGeneators.
-                               if (!value_target_set)
-                                       value_target = new LocalTemporary (type);
-
-                               ml = (IMemoryLocation) value_target;
-                               ml.AddressOf (ec, AddressOp.Store);
+                       if (target != null && is_value_type && (vr != null || method == null)) {
+                               target.AddressOf (ec, AddressOp.Store);
+                       } else if (vr != null && vr.IsRef) {
+                               vr.EmitLoad (ec);
                        }
 
                        if (method != null)
                                method.EmitArguments (ec, Arguments);
 
-                       if (is_value_type){
-                               if (method == null)
+                       if (is_value_type) {
+                               if (method == null) {
                                        ig.Emit (OpCodes.Initobj, type);
-                               else
+                                       return false;
+                               }
+
+                               if (vr != null) {
                                        ig.Emit (OpCodes.Call, (ConstructorInfo) method);
-                                if (need_value_on_stack){
-                                        value_target.Emit (ec);
-                                        return true;
-                                }
-                                return false;
-                       } else {
-                               ConstructorInfo ci = (ConstructorInfo) method;
+                                       return false;
+                               }
+                       }
+
+                       ConstructorInfo ci = (ConstructorInfo) method;
 #if MS_COMPATIBLE
-                               if (TypeManager.IsGenericType (type))
-                                       ci = TypeBuilder.GetConstructor (type, ci);
+                       if (TypeManager.IsGenericType (type))
+                               ci = TypeBuilder.GetConstructor (type, ci);
 #endif
-                               ig.Emit (OpCodes.Newobj, ci);
-                               return true;
-                       }
+
+                       ig.Emit (OpCodes.Newobj, ci);
+                       return true;
                }
 
                public override void Emit (EmitContext ec)
                {
-                       if (is_type_parameter)
-                               DoEmitTypeParameter (ec);
-                       else
-                               DoEmit (ec, true);
+                       LocalTemporary v = null;
+                       if (method == null && TypeManager.IsValueType (type)) {
+                               // TODO: Use temporary variable from pool
+                               v = new LocalTemporary (type);
+                       }
+
+                       if (!Emit (ec, v))
+                               v.Emit (ec);
                }
                
                public override void EmitStatement (EmitContext ec)
                {
-                       bool value_on_stack;
-
-                       if (is_type_parameter)
-                               value_on_stack = DoEmitTypeParameter (ec);
-                       else
-                               value_on_stack = DoEmit (ec, false);
+                       LocalTemporary v = null;
+                       if (method == null && TypeManager.IsValueType (type)) {
+                               // TODO: Use temporary variable from pool
+                               v = new LocalTemporary (type);
+                       }
 
-                       if (value_on_stack)
+                       if (Emit (ec, v))
                                ec.ig.Emit (OpCodes.Pop);
-
                }
 
                public virtual bool HasInitializer {
@@ -5669,7 +5633,7 @@ namespace Mono.CSharp {
                                return;
                        }
 
-                       if (!type.IsValueType){
+                       if (!TypeManager.IsStruct (type)){
                                //
                                // We throw an exception.  So far, I believe we only need to support
                                // value types:
@@ -5679,8 +5643,7 @@ namespace Mono.CSharp {
                                throw new Exception ("AddressOf should not be used for classes");
                        }
 
-                       if (!value_target_set)
-                               value_target = new LocalTemporary (type);
+                       LocalTemporary  value_target = new LocalTemporary (type);
                        IMemoryLocation ml = (IMemoryLocation) value_target;
 
                        ml.AddressOf (ec, AddressOp.Store);
@@ -5785,9 +5748,9 @@ namespace Mono.CSharp {
                        expect_initializers = true;
                }
 
-               void Error_IncorrectArrayInitializer ()
+               public static void Error_IncorrectArrayInitializer (Location loc)
                {
-                       Error (178, "Invalid rank specifier: expected `,' or `]'");
+                       Report.Error (178, loc, "Invalid rank specifier: expected `,' or `]'");
                }
 
                protected override void Error_NegativeArrayIndex (Location loc)
@@ -5816,7 +5779,7 @@ namespace Mono.CSharp {
                                int value = (int) c.GetValue ();
                                
                                if (value != probe.Count) {
-                                       Error_IncorrectArrayInitializer ();
+                                       Error_IncorrectArrayInitializer (loc);
                                        return false;
                                }
                                
@@ -5835,7 +5798,7 @@ namespace Mono.CSharp {
                                                child_bounds = current_bounds;
 
                                        else if (child_bounds != current_bounds){
-                                               Error_IncorrectArrayInitializer ();
+                                               Error_IncorrectArrayInitializer (loc);
                                                return false;
                                        }
                                        if (idx + 1 >= dimensions){
@@ -5848,7 +5811,7 @@ namespace Mono.CSharp {
                                                return false;
                                } else {
                                        if (child_bounds != -1){
-                                               Error_IncorrectArrayInitializer ();
+                                               Error_IncorrectArrayInitializer (loc);
                                                return false;
                                        }
                                        
@@ -5947,7 +5910,7 @@ namespace Mono.CSharp {
                        if (element == null)
                                return null;
 
-                       if (element is CompoundAssign.Helper) {
+                       if (element is CompoundAssign.TargetExpression) {
                                if (first_emit != null)
                                        throw new InternalErrorException ("Can only handle one mutator at a time");
                                first_emit = element;
@@ -6044,7 +6007,7 @@ namespace Mono.CSharp {
                                return null;
 
                        if (arguments.Count != dimensions) {
-                               Error_IncorrectArrayInitializer ();
+                               Error_IncorrectArrayInitializer (loc);
                        }
 
                        foreach (Argument a in arguments){
@@ -6317,18 +6280,9 @@ namespace Mono.CSharp {
                                        // If we are dealing with a struct, get the
                                        // address of it, so we can store it.
                                        //
-                                       if ((dims == 1) && etype.IsValueType &&
+                                       if ((dims == 1) && TypeManager.IsStruct (etype) &&
                                            (!TypeManager.IsBuiltinOrEnum (etype) ||
                                             etype == TypeManager.decimal_type)) {
-                                               if (e is New){
-                                                       New n = (New) e;
-
-                                                       //
-                                                       // Let new know that we are providing
-                                                       // the address where to store the results
-                                                       //
-                                                       n.DisableTemporaryValueType ();
-                                               }
 
                                                ig.Emit (OpCodes.Ldelema, etype);
                                        }
@@ -6524,7 +6478,7 @@ namespace Mono.CSharp {
                        for (int i = 0; i < array_data.Count; ++i) {
                                Expression e = (Expression)array_data[i];
                                if (e != null)
-                                       array_data [i] = Convert.ImplicitConversionStandard (ec, e, array_element_type, Location.Null);
+                                       array_data [i] = Convert.ImplicitConversion (ec, e, array_element_type, Location.Null);
                        }
                }
 
@@ -6539,11 +6493,11 @@ namespace Mono.CSharp {
                                return element;
                        }
 
-                       if (Convert.ImplicitStandardConversionExists (element, array_element_type)) {
+                       if (Convert.ImplicitConversionExists (ec, element, array_element_type)) {
                                return element;
                        }
 
-                       if (Convert.ImplicitStandardConversionExists (new TypeExpression (array_element_type, loc), element.Type)) {
+                       if (Convert.ImplicitConversionExists (ec, new TypeExpression (array_element_type, loc), element.Type)) {
                                array_element_type = element.Type;
                                return element;
                        }
@@ -6576,8 +6530,9 @@ namespace Mono.CSharp {
                        return this;
                }
 
-               public override HoistedVariable HoistedVariable {
-                       get { return null; }
+               public override HoistedVariable GetHoistedVariable (EmitContext ec)
+               {
+                       return null;
                }
        }
        
@@ -6626,21 +6581,29 @@ namespace Mono.CSharp {
                        get { return variable_info; }
                }
 
-               public override bool IsFixedVariable {
-                       get { return !TypeManager.IsValueType (type); }
+               public override bool IsFixed {
+                       get { return false; }
                }
 
-               protected override bool IsHoistedEmitRequired (EmitContext ec)
+               public override HoistedVariable GetHoistedVariable (EmitContext ec)
                {
-                       //
-                       // Handle 'this' differently, it cannot be assigned hence
-                       // when we are not inside anonymous method we can emit direct access 
-                       //
-                       return ec.CurrentAnonymousMethod != null && base.IsHoistedEmitRequired (ec);
-               }
+                       // Is null when probing IsHoisted
+                       if (ec == null)
+                               return null;
+
+                       if (ec.CurrentAnonymousMethod == null)
+                               return null;
+
+                       AnonymousMethodStorey storey = ec.CurrentAnonymousMethod.Storey;
+                       while (storey != null) {
+                               AnonymousMethodStorey temp = storey.Parent as AnonymousMethodStorey;
+                               if (temp == null)
+                                       return storey.HoistedThis;
 
-               public override HoistedVariable HoistedVariable {
-                       get { return TopToplevelBlock.HoistedThisVariable; }
+                               storey = temp;
+                       }
+
+                       return null;
                }
 
                public override bool IsRef {
@@ -6651,15 +6614,6 @@ namespace Mono.CSharp {
                        get { return ThisVariable.Instance; }
                }
 
-               // TODO: Move to ToplevelBlock
-               ToplevelBlock TopToplevelBlock {
-                       get {
-                               ToplevelBlock tl = block.Toplevel;
-                               while (tl.Parent != null) tl = tl.Parent.Toplevel;
-                               return tl;
-                       }
-               }
-
                public static bool IsThisAvailable (EmitContext ec)
                {
                        if (ec.IsStatic || ec.IsInFieldInitializer)
@@ -6703,17 +6657,8 @@ namespace Mono.CSharp {
                                        variable_info = block.Toplevel.ThisVariable.VariableInfo;
 
                                AnonymousExpression am = ec.CurrentAnonymousMethod;
-                               if (am != null) {
-                                       //
-                                       // this is hoisted to very top level block
-                                       //
-                                       if (ec.IsVariableCapturingRequired) {
-                                               // TODO: it could be optimized
-                                               AnonymousMethodStorey scope = TopToplevelBlock.Explicit.CreateAnonymousMethodStorey (ec);
-                                               if (HoistedVariable == null) {
-                                                       TopToplevelBlock.HoistedThisVariable = scope.CaptureThis (ec, this);
-                                               }
-                                       }
+                               if (am != null && ec.IsVariableCapturingRequired) {
+                                       am.SetHasThisAccess ();
                                }
                        }
                        
@@ -6725,7 +6670,7 @@ namespace Mono.CSharp {
                //
                public override void CheckMarshalByRefAccess (EmitContext ec)
                {
-                       if ((variable_info != null) && !(type.IsValueType && ec.OmitStructFlowAnalysis) &&
+                       if ((variable_info != null) && !(TypeManager.IsStruct (type) && ec.OmitStructFlowAnalysis) &&
                            !variable_info.IsAssigned (ec)) {
                                Error (188, "The `this' object cannot be used before all of its " +
                                       "fields are assigned to");
@@ -6735,9 +6680,11 @@ namespace Mono.CSharp {
 
                public override Expression CreateExpressionTree (EmitContext ec)
                {
-                       ArrayList args = new ArrayList (2);
+                       ArrayList args = new ArrayList (1);
                        args.Add (new Argument (this));
-                       args.Add (new Argument (new TypeOf (new TypeExpression (type, loc), loc)));
+                       
+                       // Use typeless constant for ldarg.0 to save some
+                       // space and avoid problems with anonymous stories
                        return CreateExpressionFactoryCall ("Constant", args);
                }
                
@@ -6800,11 +6747,6 @@ namespace Mono.CSharp {
                        target.block = clonectx.LookupBlock (block);
                }
 
-               public void RemoveHoisting ()
-               {
-                       TopToplevelBlock.HoistedThisVariable = null;
-               }
-
                public override void SetHasAddressTaken ()
                {
                        // Nothing
@@ -7213,11 +7155,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);
@@ -7356,8 +7293,6 @@ namespace Mono.CSharp {
                        this.expr = expr;
                }
 
-               // TODO: this method has very poor performace for Enum fields and
-               // probably for other constants as well
                Expression DoResolve (EmitContext ec, Expression right_side)
                {
                        if (type != null)
@@ -7380,16 +7315,15 @@ namespace Mono.CSharp {
 
                        string LookupIdentifier = MemberName.MakeName (Name, targs);
 
-                       if (expr_resolved is Namespace) {
-                               Namespace ns = (Namespace) expr_resolved;
+                       Namespace ns = expr_resolved as Namespace;
+                       if (ns != null) {
                                FullNamedExpression retval = ns.Lookup (ec.DeclContainer, LookupIdentifier, loc);
-#if GMCS_SOURCE
-                               if ((retval != null) && (targs != null))
-                                       retval = new ConstructedType (retval, targs, loc).ResolveAsTypeStep (ec, false);
-#endif
 
                                if (retval == null)
-                                       ns.Error_NamespaceDoesNotExist (ec.DeclContainer, loc, Name);
+                                       ns.Error_NamespaceDoesNotExist (ec.DeclContainer, loc, LookupIdentifier);
+                               else if (targs != null)
+                                       retval = new GenericTypeExpr (retval.Type, targs, loc).ResolveAsTypeStep (ec, false);
+
                                return retval;
                        }
 
@@ -7442,10 +7376,11 @@ namespace Mono.CSharp {
                                }
 
                                expr = expr_resolved;
-                               Error_MemberLookupFailed (
+                               member_lookup = Error_MemberLookupFailed (
                                        ec.ContainerType, expr_type, expr_type, Name, null,
                                        AllMemberTypes, AllBindingFlags);
-                               return null;
+                               if (member_lookup == null)
+                                       return null;
                        }
 
                        TypeExpr texpr = member_lookup as TypeExpr;
@@ -7464,7 +7399,7 @@ namespace Mono.CSharp {
                                }
 
 #if GMCS_SOURCE
-                               ConstructedType ct = expr_resolved as ConstructedType;
+                               GenericTypeExpr ct = expr_resolved as GenericTypeExpr;
                                if (ct != null) {
                                        //
                                        // When looking up a nested type in a generic instance
@@ -7473,7 +7408,7 @@ namespace Mono.CSharp {
                                        //
                                        // See gtest-172-lib.cs and gtest-172.cs for an example.
                                        //
-                                       ct = new ConstructedType (
+                                       ct = new GenericTypeExpr (
                                                member_lookup.Type, ct.TypeArguments, loc);
 
                                        return ct.ResolveAsTypeStep (ec, false);
@@ -7525,37 +7460,36 @@ namespace Mono.CSharp {
 
                public FullNamedExpression ResolveNamespaceOrType (IResolveContext rc, bool silent)
                {
-                       FullNamedExpression new_expr = expr.ResolveAsTypeStep (rc, silent);
+                       FullNamedExpression expr_resolved = expr.ResolveAsTypeStep (rc, silent);
 
-                       if (new_expr == null)
+                       if (expr_resolved == null)
                                return null;
 
                        string LookupIdentifier = MemberName.MakeName (Name, targs);
 
-                       if (new_expr is Namespace) {
-                               Namespace ns = (Namespace) new_expr;
+                       Namespace ns = expr_resolved as Namespace;
+                       if (ns != null) {
                                FullNamedExpression retval = ns.Lookup (rc.DeclContainer, LookupIdentifier, loc);
-#if GMCS_SOURCE
-                               if ((retval != null) && (targs != null))
-                                       retval = new ConstructedType (retval, targs, loc).ResolveAsTypeStep (rc, false);
-#endif
-                               if (!silent && retval == null)
+
+                               if (retval == null && !silent)
                                        ns.Error_NamespaceDoesNotExist (rc.DeclContainer, loc, LookupIdentifier);
+                               else if (targs != null)
+                                       retval = new GenericTypeExpr (retval.Type, targs, loc).ResolveAsTypeStep (rc, silent);
+
                                return retval;
                        }
 
-                       TypeExpr tnew_expr = new_expr.ResolveAsTypeTerminal (rc, false);
+                       TypeExpr tnew_expr = expr_resolved.ResolveAsTypeTerminal (rc, false);
                        if (tnew_expr == null)
                                return null;
 
-                       Type expr_type = tnew_expr.Type;
-
-                       if (expr_type.IsPointer){
-                               Error (23, "The `.' operator can not be applied to pointer operands (" +
-                                      TypeManager.CSharpName (expr_type) + ")");
+                       if (tnew_expr is TypeParameterExpr) {
+                               Report.Error (704, loc, "A nested type cannot be specified through a type parameter `{0}'",
+                                       tnew_expr.GetSignatureForError ());
                                return null;
                        }
 
+                       Type expr_type = tnew_expr.Type;
                        Expression member_lookup = MemberLookup (
                                rc.DeclContainer.TypeBuilder, expr_type, expr_type, LookupIdentifier,
                                MemberTypes.NestedType, BindingFlags.Public | BindingFlags.NonPublic, loc);
@@ -7563,7 +7497,7 @@ namespace Mono.CSharp {
                                if (silent)
                                        return null;
 
-                               Error_IdentifierNotFound (rc, new_expr, LookupIdentifier);
+                               Error_IdentifierNotFound (rc, expr_resolved, LookupIdentifier);
                                return null;
                        }
 
@@ -7574,12 +7508,12 @@ namespace Mono.CSharp {
 #if GMCS_SOURCE
                        TypeArguments the_args = targs;
                        Type declaring_type = texpr.Type.DeclaringType;
-                       if (TypeManager.HasGenericArguments (declaring_type)) {
+                       if (TypeManager.HasGenericArguments (declaring_type) && !TypeManager.IsGenericTypeDefinition (expr_type)) {
                                while (!TypeManager.IsEqual (TypeManager.DropGenericTypeArguments (expr_type), declaring_type)) {
                                        expr_type = expr_type.BaseType;
                                }
                                
-                               TypeArguments new_args = new TypeArguments (loc);
+                               TypeArguments new_args = new TypeArguments ();
                                foreach (Type decl in TypeManager.GetTypeArguments (expr_type))
                                        new_args.Add (new TypeExpression (decl, loc));
 
@@ -7590,7 +7524,7 @@ namespace Mono.CSharp {
                        }
 
                        if (the_args != null) {
-                               ConstructedType ctype = new ConstructedType (texpr.Type, the_args, loc);
+                               GenericTypeExpr ctype = new GenericTypeExpr (texpr.Type, the_args, loc);
                                return ctype.ResolveAsTypeStep (rc, false);
                        }
 #endif
@@ -7609,7 +7543,7 @@ namespace Mono.CSharp {
                                if (expr_type == null)
                                        return;
 
-                               Namespace.Error_TypeArgumentsCannotBeUsed (expr_type.Type, loc);
+                               Namespace.Error_TypeArgumentsCannotBeUsed (expr_type, loc);
                                return;
                        }
 
@@ -7879,7 +7813,7 @@ namespace Mono.CSharp {
                        if (type.IsPointer)
                                return MakePointerAccess (ec, type);
 
-                       if (Expr.eclass != ExprClass.Variable && type.IsValueType)
+                       if (Expr.eclass != ExprClass.Variable && TypeManager.IsStruct (type))
                                Error_CannotModifyIntermediateExpressionValue (ec);
 
                        return (new IndexerAccess (this, loc)).DoResolveLValue (ec, right_side);
@@ -8010,7 +7944,7 @@ namespace Mono.CSharp {
                                ig.Emit (OpCodes.Ldelem_I);
                        else if (TypeManager.IsEnumType (type)){
                                EmitLoadOpcode (ig, TypeManager.GetEnumUnderlyingType (type), rank);
-                       } else if (type.IsValueType){
+                       } else if (TypeManager.IsStruct (type)){
                                ig.Emit (OpCodes.Ldelema, type);
                                ig.Emit (OpCodes.Ldobj, type);
 #if GMCS_SOURCE
@@ -8057,7 +7991,7 @@ namespace Mono.CSharp {
                                 has_type_arg = true;
                                is_stobj = true;
                                 return OpCodes.Stobj;
-                       } else if (t.IsValueType) {
+                       } else if (TypeManager.IsStruct (t)) {
                                has_type_arg = true;
                                is_stobj = true;
                                return OpCodes.Stobj;
@@ -8232,6 +8166,18 @@ namespace Mono.CSharp {
                        }
                }
 
+               public void EmitNew (EmitContext ec, New source, bool leave_copy)
+               {
+                       if (!source.Emit (ec, this)) {
+                               if (leave_copy)
+                                       throw new NotImplementedException ();
+
+                               return;
+                       }
+
+                       throw new NotImplementedException ();
+               }
+
                public void AddressOf (EmitContext ec, AddressOp mode)
                {
                        int rank = ea.Expr.Type.GetArrayRank ();
@@ -8250,6 +8196,7 @@ namespace Mono.CSharp {
                public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
                {
                        type = storey.MutateType (type);
+                       ea.Expr.Type = storey.MutateType (ea.Expr.Type);
                }
        }
 
@@ -8864,7 +8811,6 @@ namespace Mono.CSharp {
 
                private EmptyExpressionStatement ()
                {
-                       type = TypeManager.object_type;
                        eclass = ExprClass.Value;
                        loc = Location.Null;
                }
@@ -8881,6 +8827,7 @@ namespace Mono.CSharp {
 
                public override Expression DoResolve (EmitContext ec)
                {
+                       type = TypeManager.object_type;
                        return this;
                }
 
@@ -8899,7 +8846,6 @@ namespace Mono.CSharp {
                        this.method = method;
                        this.source = source;
                        type = TypeManager.TypeToCoreType (method.ReturnType);
-                       eclass = ExprClass.Value;
                        loc = l;
                }
 
@@ -8920,9 +8866,11 @@ namespace Mono.CSharp {
                        
                public override Expression DoResolve (EmitContext ec)
                {
-                       //
-                       // We are born fully resolved
-                       //
+                       ObsoleteAttribute oa = AttributeTester.GetMethodObsoleteAttribute (method);
+                       if (oa != null)
+                               AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc);
+
+                       eclass = ExprClass.Value;
                        return this;
                }
 
@@ -8932,6 +8880,11 @@ namespace Mono.CSharp {
                        ec.ig.Emit (OpCodes.Call, method);
                }
 
+               public override string GetSignatureForError ()
+               {
+                       return TypeManager.CSharpSignature (method);
+               }
+
                public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
                {
                        source.MutateHoistedGenericType (storey);
@@ -8968,14 +8921,9 @@ 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);
+                               TypeExpr nullable = new Nullable.NullableType (lexpr, loc);
                                if (dim.Length > 1)
                                        nullable = new ComposedCast (nullable, dim.Substring (1), loc);
                                return nullable.ResolveAsTypeTerminal (ec, false);
@@ -9019,12 +8967,10 @@ namespace Mono.CSharp {
                        return left.GetSignatureForError () + dim;
                }
 
-               protected override void CloneTo (CloneContext clonectx, Expression t)
+               public override TypeExpr ResolveAsTypeTerminal (IResolveContext ec, bool silent)
                {
-                       ComposedCast target = (ComposedCast) t;
-
-                       target.left = (FullNamedExpression)left.Clone (clonectx);
-               }
+                       return ResolveAsBaseTerminal (ec, silent);
+               }               
        }
 
        public class FixedBufferPtr : Expression {
@@ -9272,12 +9218,12 @@ namespace Mono.CSharp {
                        //
                        Constant c = source as Constant;
                        if (c != null && c.IsDefaultInitializer (type) && target.eclass == ExprClass.Variable)
-                               return EmptyExpressionStatement.Instance;
+                               return EmptyExpressionStatement.Instance.DoResolve (ec);
 
                        return expr;
                }
 
-               protected override Expression Error_MemberLookupFailed (MemberInfo[] members)
+               protected override Expression Error_MemberLookupFailed (Type type, MemberInfo[] members)
                {
                        MemberInfo member = members [0];
                        if (member.MemberType != MemberTypes.Property && member.MemberType != MemberTypes.Field)
@@ -9312,6 +9258,22 @@ namespace Mono.CSharp {
                        }
                }
 
+               sealed class AddMemberAccess : MemberAccess
+               {
+                       public AddMemberAccess (Expression expr, Location loc)
+                               : base (expr, "Add", loc)
+                       {
+                       }
+
+                       protected override void Error_TypeDoesNotContainDefinition (Type type, string name)
+                       {
+                               if (TypeManager.HasElementType (type))
+                                       return;
+
+                               base.Error_TypeDoesNotContainDefinition (type, name);
+                       }
+               }
+
                public CollectionElementInitializer (Expression argument)
                        : base (null, new ArrayList (1), true)
                {
@@ -9368,7 +9330,7 @@ namespace Mono.CSharp {
                                Arguments [i] = new ElementInitializerArgument (expr);
                        }
 
-                       base.expr = new MemberAccess (ec.CurrentInitializerVariable, "Add", loc);
+                       base.expr = new AddMemberAccess (ec.CurrentInitializerVariable, loc);
 
                        return base.DoResolve (ec);
                }
@@ -9428,7 +9390,7 @@ namespace Mono.CSharp {
                        if (eclass != ExprClass.Invalid)
                                return this;
 
-                       bool is_elements_initialization = false;
+                       bool is_collection_initialization = false;
                        ArrayList element_names = null;
                        for (int i = 0; i < initializers.Count; ++i) {
                                Expression initializer = (Expression) initializers [i];
@@ -9436,7 +9398,6 @@ namespace Mono.CSharp {
 
                                if (i == 0) {
                                        if (element_initializer != null) {
-                                               is_elements_initialization = true;
                                                element_names = new ArrayList (initializers.Count);
                                                element_names.Add (element_initializer.Name);
                                        } else {
@@ -9449,15 +9410,16 @@ namespace Mono.CSharp {
                                                                TypeManager.CSharpName (TypeManager.ienumerable_type));
                                                        return null;
                                                }
+                                               is_collection_initialization = true;
                                        }
                                } else {
-                                       if (is_elements_initialization == (element_initializer == null)) {
+                                       if (is_collection_initialization != (element_initializer == null)) {
                                                Report.Error (747, initializer.Location, "Inconsistent `{0}' member declaration",
-                                                       is_elements_initialization ? "object initializer" : "collection initializer");
+                                                       is_collection_initialization ? "collection initializer" : "object initializer");
                                                continue;
                                        }
-                                       
-                                       if (is_elements_initialization) {
+
+                                       if (!is_collection_initialization) {
                                                if (element_names.Contains (element_initializer.Name)) {
                                                        Report.Error (1912, element_initializer.Location,
                                                                "An object initializer includes more than one member `{0}' initialization",
@@ -9475,7 +9437,17 @@ namespace Mono.CSharp {
                                        initializers [i] = e;
                        }
 
-                       type = is_elements_initialization ? typeof (ElementInitializer) : typeof (CollectionOrObjectInitializers);
+                       if (is_collection_initialization) {
+                               if (TypeManager.HasElementType (ec.CurrentInitializerVariable.Type)) {
+                                       Report.Error (1925, loc, "Cannot initialize object of type `{0}' with a collection initializer",
+                                               TypeManager.CSharpName (ec.CurrentInitializerVariable.Type));
+                               }
+
+                               type = typeof (CollectionOrObjectInitializers);
+                       } else {
+                               type = typeof (ElementInitializer);
+                       }
+
                        eclass = ExprClass.Variable;
                        return this;
                }
@@ -9538,20 +9510,22 @@ namespace Mono.CSharp {
 
                        public override void Emit (EmitContext ec)
                        {
-                               new_instance.value_target.Emit (ec);
+                               Expression e = (Expression) new_instance.instance;
+                               e.Emit (ec);
                        }
 
                        #region IMemoryLocation Members
 
                        public void AddressOf (EmitContext ec, AddressOp mode)
                        {
-                               ((IMemoryLocation)new_instance.value_target).AddressOf (ec, mode);
+                               new_instance.instance.AddressOf (ec, mode);
                        }
 
                        #endregion
                }
 
                CollectionOrObjectInitializers initializers;
+               IMemoryLocation instance;
 
                public NewInitialize (Expression requested_type, ArrayList arguments, CollectionOrObjectInitializers initializers, Location l)
                        : base (requested_type, arguments, l)
@@ -9571,7 +9545,8 @@ namespace Mono.CSharp {
                {
                        ArrayList args = new ArrayList (2);
                        args.Add (new Argument (base.CreateExpressionTree (ec)));
-                       args.Add (new Argument (initializers.CreateExpressionTree (ec)));
+                       if (!initializers.IsEmpty)
+                               args.Add (new Argument (initializers.CreateExpressionTree (ec)));
 
                        return CreateExpressionFactoryCall (
                                initializers.IsCollectionInitializer ? "ListInit" : "MemberInit",
@@ -9588,8 +9563,10 @@ namespace Mono.CSharp {
                                return null;
 
                        // Empty initializer can be optimized to simple new
-                       if (initializers.IsEmpty)
-                               return e;
+                       if (initializers.IsEmpty) {
+                               initializers.Resolve (ec);
+                               return ReducedExpression.Create (e, this).Resolve (ec);
+                       }
 
                        Expression previous = ec.CurrentInitializerVariable;
                        ec.CurrentInitializerVariable = new InitializerTargetExpression (this);
@@ -9598,51 +9575,52 @@ namespace Mono.CSharp {
                        return e;
                }
 
-               public override void Emit (EmitContext ec)
+               public override bool Emit (EmitContext ec, IMemoryLocation target)
                {
-                       base.Emit (ec);
+                       bool left_on_stack = base.Emit (ec, target);
+
+                       if (initializers.IsEmpty)
+                               return left_on_stack;
+
+                       LocalTemporary temp = null;
 
                        //
                        // If target is non-hoisted variable, let's use it
                        //
-                       VariableReference variable = value_target as VariableReference;
-                       if (variable != null && variable.HoistedVariable == null) {
-                               if (variable.IsRef)
-                                       StoreFromPtr (ec.ig, type);
-                               else
-                                       variable.EmitAssign (ec, EmptyExpression.Null, false, false);
-                       } else {
-                               variable = null;
-                               if (value_target == null || value_target_set)
-                                       value_target = new LocalTemporary (type);
+                       VariableReference variable = target as VariableReference;
+                       if (variable != null) {
+                               instance = target;
 
-                               ((LocalTemporary) value_target).Store (ec);
-                       }
+                               if (left_on_stack) {
+                                       if (variable.IsRef)
+                                               StoreFromPtr (ec.ig, type);
+                                       else
+                                               variable.EmitAssign (ec, EmptyExpression.Null, false, false);
 
-                       initializers.Emit (ec);
+                                       left_on_stack = false;
+                               }
+                       } else {
+                               temp = target as LocalTemporary;
+                               if (temp == null) {
+                                       if (!left_on_stack)
+                                               throw new NotImplementedException ();
 
-                       if (variable == null) {
-                               value_target.Emit (ec);
-                               value_target = null;
-                       }
-               }
+                                       temp = new LocalTemporary (type);
+                               }
 
-               public override void EmitStatement (EmitContext ec)
-               {
-                       if (initializers.IsEmpty) {
-                               base.EmitStatement (ec);
-                               return;
+                               instance = temp;
+                               if (left_on_stack)
+                                       temp.Store (ec);
                        }
 
-                       base.Emit (ec);
+                       initializers.Emit (ec);
 
-                       if (value_target == null) {
-                               LocalTemporary variable = new LocalTemporary (type);
-                               variable.Store (ec);
-                               value_target = variable;
+                       if (left_on_stack) {
+                               temp.Emit (ec);
+                               temp.Release (ec);
                        }
 
-                       initializers.EmitStatement (ec);
+                       return left_on_stack;
                }
 
                public override bool HasInitializer {
@@ -9693,10 +9671,10 @@ namespace Mono.CSharp {
                                return null;
 
                        type.DefineType ();
-                       type.DefineMembers ();
                        type.Define ();
                        type.EmitType ();
-                       type.CloseType ();
+                       if (Report.Errors == 0)
+                               type.CloseType ();
 
                        RootContext.ToplevelTypes.AddAnonymousType (type);
                        return type;
@@ -9711,6 +9689,11 @@ namespace Mono.CSharp {
                {
                        AnonymousTypeClass anonymous_type;
 
+                       if (!ec.IsAnonymousMethodAllowed) {
+                               Report.Error (836, loc, "Anonymous types cannot be used in this expression");
+                               return null;
+                       }
+
                        if (parameters == null) {
                                anonymous_type = CreateAnonymousType (EmptyParameters);
                                return new New (new TypeExpression (anonymous_type.TypeBuilder, loc),
@@ -9738,8 +9721,8 @@ namespace Mono.CSharp {
                        if (anonymous_type == null)
                                return null;
 
-                       ConstructedType te = new ConstructedType (anonymous_type.TypeBuilder,
-                               new TypeArguments (loc, t_args), loc);
+                       GenericTypeExpr te = new GenericTypeExpr (anonymous_type.TypeBuilder,
+                               new TypeArguments (t_args), loc);
 
                        return new New (te, arguments, loc).Resolve (ec);
                }