2008-06-11 Marek Safar <marek.safar@gmail.com>
[mono.git] / mcs / mcs / ecore.cs
index fda2952b618821dd0839fdd83d5d8ea2c0eb95e5..9470b01ac6fc4efaa1107081a56d21971bbb060b 100644 (file)
@@ -5,7 +5,8 @@
 //   Miguel de Icaza (miguel@ximian.com)
 //   Marek Safar (marek.safar@seznam.cz)
 //
-// (C) 2001, 2002, 2003 Ximian, Inc.
+// Copyright 2001, 2002, 2003 Ximian, Inc.
+// Copyright 2003-2008 Novell, Inc.
 //
 //
 
@@ -96,15 +97,10 @@ namespace Mono.CSharp {
                void AddressOf (EmitContext ec, AddressOp mode);
        }
 
-       /// <summary>
-       ///   This interface is implemented by variables
-       /// </summary>
+       // TODO: Rename to something meaningful, this is flow-analysis interface only
        public interface IVariable {
-               VariableInfo VariableInfo {
-                       get;
-               }
-
-               bool VerifyFixed ();
+               VariableInfo VariableInfo { get; }
+               bool IsFixed { get; }
        }
 
        /// <remarks>
@@ -392,12 +388,6 @@ namespace Mono.CSharp {
                                return;
                        }
 
-                       if (Type != TypeManager.string_type && this is Constant && !(this is EmptyConstantCast)) {
-                               Report.Error (31, loc, "Constant value `{0}' cannot be converted to a `{1}'",
-                                       ((Constant)(this)).GetValue ().ToString (), TypeManager.CSharpName (target));
-                               return;
-                       }
-
                        Report.Error (29, loc, "Cannot implicitly convert type `{0}' to `{1}'",
                                TypeManager.CSharpName (type),
                                TypeManager.CSharpName (target));
@@ -584,12 +574,19 @@ namespace Mono.CSharp {
                /// </remarks>
                public abstract void Emit (EmitContext ec);
 
+               // Emit code to branch to @target if this expression is equivalent to @on_true.
+               // The default implementation is to emit the value, and then emit a brtrue or brfalse.
+               // Subclasses can provide more efficient implementations, but those MUST be equivalent,
+               // including the use of conditional branches.  Note also that a branch MUST be emitted
                public virtual void EmitBranchable (EmitContext ec, Label target, bool on_true)
                {
                        Emit (ec);
                        ec.ig.Emit (on_true ? OpCodes.Brtrue : OpCodes.Brfalse, target);
                }
 
+               // Emit this expression for its side effects, not for its value.
+               // The default implementation is to emit the value, and then throw it away.
+               // Subclasses can provide more efficient implementations, but those MUST be equivalent
                public virtual void EmitSideEffect (EmitContext ec)
                {
                        Emit (ec);
@@ -906,6 +903,11 @@ namespace Mono.CSharp {
                        throw new NotImplementedException ();
                }
 
+               protected void Error_PointerInsideExpressionTree ()
+               {
+                       Report.Error (1944, loc, "An expression tree cannot contain an unsafe pointer operation");
+               }
+
                /// <summary>
                ///   Returns an expression that can be used to invoke operator true
                ///   on the expression if it exists.
@@ -927,7 +929,8 @@ namespace Mono.CSharp {
                static Expression GetOperatorTrueOrFalse (EmitContext ec, Expression e, bool is_true, Location loc)
                {
                        MethodGroupExpr operator_group;
-                       operator_group = MethodLookup (ec.ContainerType, e.Type, is_true ? "op_True" : "op_False", loc) as MethodGroupExpr;
+                       string mname = Operator.GetMetadataName (is_true ? Operator.OpType.True : Operator.OpType.False);
+                       operator_group = MethodLookup (ec.ContainerType, e.Type, mname, loc) as MethodGroupExpr;
                        if (operator_group == null)
                                return null;
 
@@ -1243,11 +1246,10 @@ namespace Mono.CSharp {
                        return cloned;
                }
 
-               public virtual Expression CreateExpressionTree (EmitContext ec)
-               {
-                       throw new NotImplementedException (
-                               "Expression tree conversion not implemented for " + GetType ());
-               }
+               //
+               // Implementation of expression to expression tree conversion
+               //
+               public abstract Expression CreateExpressionTree (EmitContext ec);
 
                protected Expression CreateExpressionFactoryCall (string name, ArrayList args)
                {
@@ -1344,6 +1346,10 @@ namespace Mono.CSharp {
                        ArrayList args = new ArrayList (2);
                        args.Add (new Argument (child.CreateExpressionTree (ec)));
                        args.Add (new Argument (new TypeOf (new TypeExpression (type, loc), loc)));
+
+                       if (type.IsPointer || child.Type.IsPointer)
+                               Error_PointerInsideExpressionTree ();
+
                        return CreateExpressionFactoryCall (ec.CheckState ? "ConvertChecked" : "Convert", args);
                }
 
@@ -1371,6 +1377,10 @@ namespace Mono.CSharp {
 
                        target.child = child.Clone (clonectx);
                }
+
+               public override bool IsNull {
+                       get { return child.IsNull; }
+               }
        }
 
        public class EmptyCast : TypeCast {
@@ -1378,13 +1388,17 @@ namespace Mono.CSharp {
                        : base (child, target_type)
                {
                }
-               
+
                public static Expression Create (Expression child, Type type)
                {
                        Constant c = child as Constant;
                        if (c != null)
                                return new EmptyConstantCast (c, type);
 
+                       EmptyCast e = child as EmptyCast;
+                       if (e != null)
+                               return new EmptyCast (e.child, type);
+
                        return new EmptyCast (child, type);
                }
 
@@ -1397,7 +1411,6 @@ namespace Mono.CSharp {
                {
                        child.EmitSideEffect (ec);
                }
-
        }
 
        /// <summary>
@@ -1587,6 +1600,9 @@ namespace Mono.CSharp {
                        ArrayList args = new ArrayList (2);
                        args.Add (new Argument (child.CreateExpressionTree (ec)));
                        args.Add (new Argument (new TypeOf (new TypeExpression (type, loc), loc)));
+                       if (type.IsPointer)
+                               Error_PointerInsideExpressionTree ();
+
                        return CreateExpressionFactoryCall ("Convert", args);
                }
 
@@ -2249,7 +2265,7 @@ namespace Mono.CSharp {
        //
        // Unresolved type name expressions
        //
-       public abstract class ATypeNameExpression : Expression
+       public abstract class ATypeNameExpression : FullNamedExpression
        {
                public readonly string Name;
                protected TypeArguments targs;
@@ -2267,9 +2283,10 @@ namespace Mono.CSharp {
                        loc = l;
                }
 
-               public override void Emit (EmitContext ec)
-               {
-                       throw new InternalErrorException ("ATypeNameExpression found in resolved tree");
+               public bool HasTypeArguments {
+                       get {
+                               return targs != null;
+                       }
                }
 
                public override string GetSignatureForError ()
@@ -2664,7 +2681,7 @@ namespace Mono.CSharp {
                                        return e;
 
                                ConstructedType ct = new ConstructedType (
-                                       (FullNamedExpression) e, targs, loc);
+                                       e.Type, targs, loc);
                                return ct.ResolveAsTypeStep (ec, false);
                        }
 
@@ -2736,13 +2753,21 @@ namespace Mono.CSharp {
        ///   section 10.8.1 (Fully Qualified Names).
        /// </summary>
        public abstract class FullNamedExpression : Expression {
+
+               public override Expression CreateExpressionTree (EmitContext ec)
+               {
+                       throw new NotSupportedException ("ET");
+               }
+
                public override FullNamedExpression ResolveAsTypeStep (IResolveContext ec, bool silent)
                {
                        return this;
                }
 
-               public abstract string FullName {
-                       get;
+               public override void Emit (EmitContext ec)
+               {
+                       throw new InternalErrorException ("FullNamedExpression `{0}' found in resolved tree",
+                               GetSignatureForError ());
                }
        }
        
@@ -2765,11 +2790,6 @@ namespace Mono.CSharp {
                        return ResolveAsTypeTerminal (ec, false);
                }
 
-               override public void Emit (EmitContext ec)
-               {
-                       throw new Exception ("Should never be called");
-               }
-
                public virtual bool CheckAccessLevel (DeclSpace ds)
                {
                        return ds.CheckAccessLevel (Type);
@@ -2810,10 +2830,6 @@ namespace Mono.CSharp {
 
                protected abstract TypeExpr DoResolveAsTypeStep (IResolveContext ec);
 
-               public abstract string Name {
-                       get;
-               }
-
                public override bool Equals (object obj)
                {
                        TypeExpr tobj = obj as TypeExpr;
@@ -2827,11 +2843,6 @@ namespace Mono.CSharp {
                {
                        return Type.GetHashCode ();
                }
-               
-               public override string ToString ()
-               {
-                       return Name;
-               }
        }
 
        /// <summary>
@@ -2854,14 +2865,6 @@ namespace Mono.CSharp {
                {
                        return this;
                }
-
-               public override string Name {
-                       get { return Type.ToString (); }
-               }
-
-               public override string FullName {
-                       get { return Type.FullName; }
-               }
        }
 
        /// <summary>
@@ -2995,14 +2998,6 @@ namespace Mono.CSharp {
                        return this;
                }
 
-               public override string Name {
-                       get { return name; }
-               }
-
-               public override string FullName {
-                       get { return name; }
-               }
-
                protected override void CloneTo (CloneContext clonectx, Expression target)
                {
                        // CloneTo: Nothing, we do not keep any state on this expression
@@ -3031,6 +3026,11 @@ namespace Mono.CSharp {
                        loc = l;
                }
 
+               protected override void CloneTo (CloneContext clonectx, Expression target)
+               {
+                       // Nothing to clone
+               }
+
                protected override TypeExpr DoResolveAsTypeStep (IResolveContext ec)
                {
                        Expression expr;
@@ -3048,99 +3048,6 @@ namespace Mono.CSharp {
                        type = fne.Type;
                        return new TypeExpression (type, loc);
                }
-
-               public override string Name {
-                       get { return name.PrettyName; }
-               }
-
-               public override string FullName {
-                       get { return name.FullyQualifiedName; }
-               }
-       }
-
-       public class TypeAliasExpression : TypeExpr {
-               FullNamedExpression alias;
-               TypeExpr texpr;
-               TypeArguments args;
-               string name;
-
-               public TypeAliasExpression (FullNamedExpression alias, TypeArguments args, Location l)
-               {
-                       this.alias = alias;
-                       this.args = args;
-                       loc = l;
-
-                       eclass = ExprClass.Type;
-                       if (args != null)
-                               name = alias.FullName + "<" + args.ToString () + ">";
-                       else
-                               name = alias.FullName;
-               }
-
-               public override string Name {
-                       get { return alias.FullName; }
-               }
-
-               public override string FullName {
-                       get { return name; }
-               }
-
-               protected override TypeExpr DoResolveAsTypeStep (IResolveContext ec)
-               {
-                       texpr = alias.ResolveAsTypeTerminal (ec, false);
-                       if (texpr == null)
-                               return null;
-
-                       Type type = texpr.Type;
-                       int num_args = TypeManager.GetNumberOfTypeArguments (type);
-
-                       if (args != null) {
-                               if (num_args == 0) {
-                                       Report.Error (308, loc,
-                                                     "The non-generic type `{0}' cannot " +
-                                                     "be used with type arguments.",
-                                                     TypeManager.CSharpName (type));
-                                       return null;
-                               }
-
-                               ConstructedType ctype = new ConstructedType (type, args, loc);
-                               return ctype.ResolveAsTypeTerminal (ec, false);
-                       } else if (num_args > 0) {
-                               Report.Error (305, loc,
-                                             "Using the generic type `{0}' " +
-                                             "requires {1} type arguments",
-                                             TypeManager.CSharpName (type), num_args.ToString ());
-                               return null;
-                       }
-
-                       return texpr;
-               }
-
-               public override bool CheckAccessLevel (DeclSpace ds)
-               {
-                       return texpr.CheckAccessLevel (ds);
-               }
-
-               public override bool AsAccessible (DeclSpace ds)
-               {
-                       return texpr.AsAccessible (ds);
-               }
-
-               public override bool IsClass {
-                       get { return texpr.IsClass; }
-               }
-
-               public override bool IsValueType {
-                       get { return texpr.IsValueType; }
-               }
-
-               public override bool IsInterface {
-                       get { return texpr.IsInterface; }
-               }
-
-               public override bool IsSealed {
-                       get { return texpr.IsSealed; }
-               }
        }
 
        /// <summary>
@@ -3199,6 +3106,11 @@ namespace Mono.CSharp {
                                      "with an instance reference, qualify it with a type name instead", name);
                }
 
+               public static void Error_BaseAccessInExpressionTree (Location loc)
+               {
+                       Report.Error (831, loc, "An expression tree may not contain a base access");
+               }
+
                // TODO: possible optimalization
                // Cache resolved constant result in FieldBuilder <-> expression map
                public virtual MemberExpr ResolveMemberAccess (EmitContext ec, Expression left, Location loc,
@@ -3490,8 +3402,11 @@ namespace Mono.CSharp {
                                //
                                if (TypeManager.DropGenericTypeArguments (p) == TypeManager.expression_type) {
                                        p = TypeManager.GetTypeArguments (p) [0];
+                               }
+                               if (TypeManager.DropGenericTypeArguments (q) == TypeManager.expression_type) {
                                        q = TypeManager.GetTypeArguments (q) [0];
                                }
+                               
                                p = Delegate.GetInvokeMethod (null, p).ReturnType;
                                q = Delegate.GetInvokeMethod (null, q).ReturnType;
                        } else {
@@ -3717,10 +3632,20 @@ namespace Mono.CSharp {
 
                public override Expression CreateExpressionTree (EmitContext ec)
                {
-                       Type t = best_candidate.IsConstructor ?
-                               typeof (ConstructorInfo) : typeof (MethodInfo);
+                       if (best_candidate == null) {
+                               Report.Error (1953, loc, "An expression tree cannot contain an expression with method group");
+                               return null;
+                       }
+
+                       if (best_candidate.IsConstructor)
+                               return new TypeOfConstructorInfo (best_candidate, loc);
 
-                       return new Cast (new TypeExpression (t, loc), new TypeOfMethod (best_candidate, loc));
+                       IMethodData md = TypeManager.GetMethod (best_candidate);
+                       if (md != null && md.IsExcluded ())
+                               Report.Error (765, loc,
+                                       "Partial methods with only a defining declaration or removed conditional methods cannot be used in an expression tree");
+                       
+                       return new TypeOfMethodInfo (best_candidate, loc);
                }
                
                override public Expression DoResolve (EmitContext ec)
@@ -3938,21 +3863,13 @@ namespace Mono.CSharp {
                                return 0;
                        }
 
-                       // FIXME: Kill this abomination (EmitContext.TempEc)
-                       EmitContext prevec = EmitContext.TempEc;
-                       EmitContext.TempEc = ec;
-                       try {
-                               if (delegate_type != null ?
-                                       !Delegate.IsTypeCovariant (argument.Expr, parameter) :
-                                       !Convert.ImplicitConversionExists (ec, argument.Expr, parameter))
-                                       return 2;
-
-                               if (arg_mod != param_mod)
-                                       return 1;
+                       if (delegate_type != null ?
+                               !Delegate.IsTypeCovariant (argument.Expr, parameter) :
+                               !Convert.ImplicitConversionExists (ec, argument.Expr, parameter))
+                               return 2;
 
-                       } finally {
-                               EmitContext.TempEc = prevec;
-                       }
+                       if (arg_mod != param_mod)
+                               return 1;
 
                        return 0;
                }
@@ -4515,7 +4432,7 @@ namespace Mono.CSharp {
 
                                        continue;
                                }
-               
+
                                Expression conv;
                                if (TypeManager.IsEqual (a.Type, pt)) {
                                        conv = a.Expr;
@@ -4529,12 +4446,14 @@ namespace Mono.CSharp {
                                // Convert params arguments to an array initializer
                                //
                                if (params_initializers != null) {
-                                       params_initializers.Add (conv);
+                                       // we choose to use 'a.Expr' rather than 'conv' so that
+                                       // we don't hide the kind of expression we have (esp. CompoundAssign.Helper)
+                                       params_initializers.Add (a.Expr);
                                        arguments.RemoveAt (a_idx--);
                                        --arg_count;
                                        continue;
                                }
-                               
+
                                // Update the argument with the implicit conversion
                                a.Expr = conv;
                        }
@@ -4621,7 +4540,7 @@ namespace Mono.CSharp {
 
                public override Expression CreateExpressionTree (EmitContext ec)
                {
-                       throw new NotSupportedException ();
+                       throw new NotSupportedException ("ET");
                }
 
                public override Expression DoResolve (EmitContext ec)
@@ -4823,7 +4742,7 @@ namespace Mono.CSharp {
 
                        // If the instance expression is a local variable or parameter.
                        IVariable var = InstanceExpression as IVariable;
-                       if ((var == null) || (var.VariableInfo == null))
+                       if (var == null || var.VariableInfo == null)
                                return this;
 
                        VariableInfo vi = var.VariableInfo;
@@ -4874,7 +4793,7 @@ namespace Mono.CSharp {
                override public Expression DoResolveLValue (EmitContext ec, Expression right_side)
                {
                        IVariable var = InstanceExpression as IVariable;
-                       if ((var != null) && (var.VariableInfo != null))
+                       if (var != null && var.VariableInfo != null)
                                var.VariableInfo.SetFieldAssigned (ec, FieldInfo.Name);
 
                        bool lvalue_instance = !FieldInfo.IsStatic && FieldInfo.DeclaringType.IsValueType;
@@ -4936,19 +4855,20 @@ namespace Mono.CSharp {
                        }
                }
 
-               public bool VerifyFixed ()
-               {
-                       IVariable variable = InstanceExpression as IVariable;
-                       // A variable of the form V.I is fixed when V is a fixed variable of a struct type.
-                       // We defer the InstanceExpression check after the variable check to avoid a 
-                       // separate null check on InstanceExpression.
-                       return variable != null && InstanceExpression.Type.IsValueType && variable.VerifyFixed ();
-               }
-
                public override int GetHashCode ()
                {
                        return FieldInfo.GetHashCode ();
                }
+               
+               public bool IsFixed {
+                       get {
+                               IVariable variable = InstanceExpression as IVariable;
+                               // A variable of the form V.I is fixed when V is a fixed variable of a struct type.
+                               // We defer the InstanceExpression check after the variable check to avoid a 
+                               // separate null check on InstanceExpression.
+                               return variable != null && InstanceExpression.Type.IsValueType && variable.IsFixed;
+                       }
+               }               
 
                public override bool Equals (object obj)
                {
@@ -5020,10 +4940,7 @@ namespace Mono.CSharp {
                                return;
                        }
 
-                       //
-                       // String concatenation creates a new string instance 
-                       //
-                       prepared = prepare_for_load && !(source is StringConcat);
+                       prepared = prepare_for_load;
                        EmitInstance (ec, prepared);
 
                        source.Emit (ec);                       
@@ -5172,23 +5089,30 @@ namespace Mono.CSharp {
 
                public override Expression CreateExpressionTree (EmitContext ec)
                {
+                       ArrayList args;
                        if (IsSingleDimensionalArrayLength ()) {
-                               ArrayList args = new ArrayList (1);
+                               args = new ArrayList (1);
                                args.Add (new Argument (InstanceExpression.CreateExpressionTree (ec)));
                                return CreateExpressionFactoryCall ("ArrayLength", args);
                        }
 
-                       // TODO: it's waiting for PropertyExpr refactoring
-                       //ArrayList args = new ArrayList (2);
-                       //args.Add (new Argument (InstanceExpression.CreateExpressionTree (ec)));
-                       //args.Add (getter expression);
-                       //return CreateExpressionFactoryCall ("Property", args);
-                       return base.CreateExpressionTree (ec);
+                       if (is_base) {
+                               Error_BaseAccessInExpressionTree (loc);
+                               return null;
+                       }
+
+                       args = new ArrayList (2);
+                       if (InstanceExpression == null)
+                               args.Add (new Argument (new NullLiteral (loc)));
+                       else
+                               args.Add (new Argument (InstanceExpression.CreateExpressionTree (ec)));
+                       args.Add (new Argument (new TypeOfMethodInfo (getter, loc)));
+                       return CreateExpressionFactoryCall ("Property", args);
                }
 
                public Expression CreateSetterTypeOfExpression ()
                {
-                       return new Cast (new TypeExpression (typeof (MethodInfo), loc), new TypeOfMethod (setter, loc));
+                       return new TypeOfMethodInfo (setter, loc);
                }
 
                public override Type DeclaringType {
@@ -5333,7 +5257,7 @@ namespace Mono.CSharp {
 
                        string t_name = InstanceExpression.Type.Name;
                        int t_name_len = t_name.Length;
-                       return t_name_len > 2 && t_name [t_name_len - 2] == '[' && t_name [t_name_len - 3] != ']';
+                       return t_name_len > 2 && t_name [t_name_len - 2] == '[';
                }
 
                override public Expression DoResolve (EmitContext ec)
@@ -5504,14 +5428,9 @@ namespace Mono.CSharp {
                        Expression my_source = source;
 
                        if (prepare_for_load) {
-                               if (source is StringConcat)
-                                       EmitInstance (ec, false);
-                               else
-                                       prepared = true;                                        
-
+                               prepared = true;
                                source.Emit (ec);
                                
-                               prepared = true;
                                if (leave_copy) {
                                        ec.ig.Emit (OpCodes.Dup);
                                        if (!is_static) {
@@ -5628,7 +5547,6 @@ namespace Mono.CSharp {
                        return base.ResolveMemberAccess (ec, left, loc, original);
                }
 
-
                bool InstanceResolve (EmitContext ec, bool must_do_cs1540_check)
                {
                        if (is_static) {
@@ -5674,12 +5592,14 @@ namespace Mono.CSharp {
 
                public override Expression CreateExpressionTree (EmitContext ec)
                {
-                       throw new NotSupportedException ();
+                       throw new NotSupportedException ("ET");
                }
 
                public override Expression DoResolveLValue (EmitContext ec, Expression right_side)
                {
-                       return DoResolve (ec);
+                       // contexts where an LValue is valid have already devolved to FieldExprs
+                       Error_CannotAssign ();
+                       return null;
                }
 
                public override Expression DoResolve (EmitContext ec)
@@ -5694,14 +5614,25 @@ namespace Mono.CSharp {
 
                        if (!InstanceResolve (ec, must_do_cs1540_check))
                                return null;
+
+                       if (!ec.IsInCompoundAssignment) {
+                               Error_CannotAssign ();
+                               return null;
+                       }
                        
                        return this;
                }               
 
                public override void Emit (EmitContext ec)
                {
-                       Report.Error (70, loc, "The event `{0}' can only appear on the left hand side of += or -= "+
-                                     "(except on the defining type)", GetSignatureForError ());
+                       Error_CannotAssign ();
+               }
+
+               public void Error_CannotAssign ()
+               {
+                       Report.Error (70, loc,
+                               "The event `{0}' can only appear on the left hand side of += or -= when used outside of the type `{1}'",
+                               GetSignatureForError (), TypeManager.CSharpName (EventInfo.DeclaringType));
                }
 
                public override string GetSignatureForError ()
@@ -5709,46 +5640,36 @@ namespace Mono.CSharp {
                        return TypeManager.CSharpSignature (EventInfo);
                }
 
-               public void EmitAddOrRemove (EmitContext ec, Expression source)
+               public void EmitAddOrRemove (EmitContext ec, bool is_add, Expression source)
                {
-                       BinaryDelegate source_del = source as BinaryDelegate;
-                       if (source_del == null) {
-                               Emit (ec);
-                               return;
-                       }
-                       Expression handler = source_del.Right;
-                       
-                       Argument arg = new Argument (handler, Argument.AType.Expression);
-                       ArrayList args = new ArrayList ();
-                               
-                       args.Add (arg);
-                       
-                       if (source_del.IsAddition)
-                               Invocation.EmitCall (
-                                       ec, IsBase, InstanceExpression, add_accessor, args, loc);
-                       else
-                               Invocation.EmitCall (
-                                       ec, IsBase, InstanceExpression, remove_accessor, args, loc);
+                       ArrayList args = new ArrayList (1);
+                       args.Add (new Argument (source, Argument.AType.Expression));
+                       Invocation.EmitCall (ec, IsBase, InstanceExpression, is_add ? add_accessor : remove_accessor, args, loc);
                }
        }
 
-       public class TemporaryVariable : Expression, IMemoryLocation
+       public class TemporaryVariable : VariableReference
        {
                LocalInfo li;
                Variable var;
-               
+
                public TemporaryVariable (Type type, Location loc)
                {
                        this.type = type;
                        this.loc = loc;
-                       eclass = ExprClass.Value;
+                       eclass = ExprClass.Variable;
                }
-               
+
+               public override Expression CreateExpressionTree (EmitContext ec)
+               {
+                       throw new NotSupportedException ("ET");
+               }
+
                public override Expression DoResolve (EmitContext ec)
                {
                        if (li != null)
                                return this;
-                       
+
                        TypeExpr te = new TypeExpression (type, loc);
                        li = ec.CurrentBlock.AddTemporaryVariable (te, loc);
                        if (!li.Resolve (ec))
@@ -5759,46 +5680,34 @@ namespace Mono.CSharp {
                                var = scope.AddLocal (li);
                                type = var.Type;
                        }
-                       
+
                        return this;
                }
 
-               public Variable Variable {
-                       get { return var != null ? var : li.Variable; }
-               }
-               
                public override void Emit (EmitContext ec)
                {
-                       Variable.EmitInstance (ec);
-                       Variable.Emit (ec);
+                       Emit (ec, false);
                }
-               
-               public void EmitLoadAddress (EmitContext ec)
+
+               public void EmitAssign (EmitContext ec, Expression source)
                {
-                       Variable.EmitInstance (ec);
-                       Variable.EmitAddressOf (ec);
+                       EmitAssign (ec, source, false, false);
                }
-               
-               public void Store (EmitContext ec, Expression right_side)
-               {
-                       Variable.EmitInstance (ec);
-                       right_side.Emit (ec);
-                       Variable.EmitAssign (ec);
+
+               public override bool IsFixed {
+                       get { return true; }
                }
-               
-               public void EmitThis (EmitContext ec)
-               {
-                       Variable.EmitInstance (ec);
+
+               public override bool IsRef {
+                       get { return false; }
                }
-               
-               public void EmitStore (EmitContext ec)
-               {
-                       Variable.EmitAssign (ec);
+
+               public override Variable Variable {
+                       get { return var != null ? var : li.Variable; }
                }
-               
-               public void AddressOf (EmitContext ec, AddressOp mode)
-               {
-                       EmitLoadAddress (ec);
+
+               public override VariableInfo VariableInfo {
+                       get { throw new NotImplementedException (); }
                }
        }
 
@@ -5822,7 +5731,7 @@ namespace Mono.CSharp {
                        }
                }
 
-               public override Expression DoResolveLValue (EmitContext ec, Expression right_side)
+               public bool InferType (EmitContext ec, Expression right_side)
                {
                        if (type != null)
                                throw new InternalErrorException ("An implicitly typed local variable could not be redefined");
@@ -5831,11 +5740,11 @@ namespace Mono.CSharp {
                        if (type == TypeManager.null_type || type == TypeManager.void_type || type == TypeManager.anonymous_method_type) {
                                Report.Error (815, loc, "An implicitly typed local variable declaration cannot be initialized with `{0}'",
                                              right_side.GetSignatureForError ());
-                               return null;
+                               return false;
                        }
 
                        eclass = ExprClass.Variable;
-                       return this;
+                       return true;
                }
 
                protected override void Error_TypeOrNamespaceNotFound (IResolveContext ec)