2008-07-14 Marek Safar <marek.safar@gmail.com>
[mono.git] / mcs / mcs / ecore.cs
index f78a76b22983096d0c2e1a556ebb84081c3b88b4..e8e0e6f3b86a32a5505d15ec3cdf75e2060dc7dd 100644 (file)
@@ -97,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>
@@ -393,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));
@@ -1257,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)
                {
@@ -1291,6 +1279,11 @@ namespace Mono.CSharp {
 
                        return texpr;
                }
+
+               public virtual void MutateHoistedGenericType (AnonymousMethodStorey storey)
+               {
+                       // TODO: It should probably be type = storey.MutateType (type);
+               }
        }
 
        /// <summary>
@@ -1343,7 +1336,7 @@ namespace Mono.CSharp {
        /// </summary>
        public abstract class TypeCast : Expression
        {
-               protected Expression child;
+               protected readonly Expression child;
 
                protected TypeCast (Expression child, Type return_type)
                {
@@ -1383,17 +1376,18 @@ namespace Mono.CSharp {
                        return child.GetAttributableValue (value_type, out value);
                }
 
-               protected override void CloneTo (CloneContext clonectx, Expression t)
+               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
                {
-                       TypeCast target = (TypeCast) t;
+                       child.MutateHoistedGenericType (storey);
+               }
 
-                       target.child = child.Clone (clonectx);
+               protected override void CloneTo (CloneContext clonectx, Expression t)
+               {
+                       // Nothing to clone
                }
 
                public override bool IsNull {
-                       get     {
-                               return child.IsNull;
-                       }
+                       get { return child.IsNull; }
                }
        }
 
@@ -1409,6 +1403,10 @@ namespace Mono.CSharp {
                        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);
                }
 
@@ -1421,7 +1419,6 @@ namespace Mono.CSharp {
                {
                        child.EmitSideEffect (ec);
                }
-
        }
 
        /// <summary>
@@ -1864,6 +1861,11 @@ namespace Mono.CSharp {
                                LoadFromPtr (ig, t);
                        }
                }
+
+               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
+               {
+                       type = storey.MutateType (type);
+               }
        }
        
        /// <summary>
@@ -2082,24 +2084,12 @@ namespace Mono.CSharp {
        }
        
        public class OpcodeCast : TypeCast {
-               OpCode op, op2;
-               bool second_valid;
+               readonly OpCode op;
                
                public OpcodeCast (Expression child, Type return_type, OpCode op)
                        : base (child, return_type)
-                       
-               {
-                       this.op = op;
-                       second_valid = false;
-               }
-
-               public OpcodeCast (Expression child, Type return_type, OpCode op, OpCode op2)
-                       : base (child, return_type)
-                       
                {
                        this.op = op;
-                       this.op2 = op2;
-                       second_valid = true;
                }
 
                public override Expression DoResolve (EmitContext ec)
@@ -2114,9 +2104,6 @@ namespace Mono.CSharp {
                {
                        base.Emit (ec);
                        ec.ig.Emit (op);
-
-                       if (second_valid)
-                               ec.ig.Emit (op2);
                }
 
                public Type UnderlyingType {
@@ -2128,11 +2115,15 @@ namespace Mono.CSharp {
        ///   This kind of cast is used to encapsulate a child and cast it
        ///   to the class requested
        /// </summary>
-       public class ClassCast : TypeCast {
+       public sealed class ClassCast : TypeCast {
+               Type child_generic_parameter;
+
                public ClassCast (Expression child, Type return_type)
                        : base (child, return_type)
                        
                {
+                       if (TypeManager.IsGenericParameter (child.Type))
+                               child_generic_parameter = child.Type;
                }
 
                public override Expression DoResolve (EmitContext ec)
@@ -2147,8 +2138,8 @@ namespace Mono.CSharp {
                {
                        base.Emit (ec);
 
-                       if (TypeManager.IsGenericParameter (child.Type))
-                               ec.ig.Emit (OpCodes.Box, child.Type);
+                       if (child_generic_parameter != null)
+                               ec.ig.Emit (OpCodes.Box, child_generic_parameter);
 
 #if GMCS_SOURCE
                        if (type.IsGenericParameter)
@@ -2157,6 +2148,15 @@ namespace Mono.CSharp {
 #endif
                                ec.ig.Emit (OpCodes.Castclass, type);
                }
+
+               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
+               {
+                       type = storey.MutateType (type);
+                       if (child_generic_parameter != null)
+                               child_generic_parameter = storey.MutateGenericArgument (child_generic_parameter);
+
+                       base.MutateHoistedGenericType (storey);
+               }
        }
 
        //
@@ -2854,6 +2854,11 @@ namespace Mono.CSharp {
                {
                        return Type.GetHashCode ();
                }
+
+               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
+               {
+                       type = storey.MutateType (type);
+               }
        }
 
        /// <summary>
@@ -3117,6 +3122,17 @@ 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");
+               }
+
+               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
+               {
+                       if (InstanceExpression != null)
+                               InstanceExpression.MutateHoistedGenericType (storey);
+               }
+
                // TODO: possible optimalization
                // Cache resolved constant result in FieldBuilder <-> expression map
                public virtual MemberExpr ResolveMemberAccess (EmitContext ec, Expression left, Location loc,
@@ -3262,6 +3278,7 @@ namespace Mono.CSharp {
                                return base.OverloadResolve (ec, ref arguments, false, loc);
 
                        e.ExtensionExpression = ExtensionExpression;
+                       e.SetTypeArguments (type_arguments);                    
                        return e.ResolveOverloadExtensions (ec, arguments, e.namespace_entry, loc);
                }               
        }
@@ -3408,10 +3425,17 @@ 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;
+                               if (p == TypeManager.void_type && q != TypeManager.void_type)
+                                       return 2;
+                               if (q == TypeManager.void_type && p != TypeManager.void_type)
+                                       return 1;
                        } else {
                                if (argument_type == p)
                                        return 1;
@@ -3635,8 +3659,18 @@ namespace Mono.CSharp {
 
                public override Expression CreateExpressionTree (EmitContext ec)
                {
+                       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);
+
+                       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);
                }
@@ -3676,6 +3710,8 @@ namespace Mono.CSharp {
                protected virtual void Error_InvalidArguments (EmitContext ec, Location loc, int idx, MethodBase method,
                                                                                                        Argument a, ParameterData expected_par, Type paramType)
                {
+                       ExtensionMethodGroupExpr emg = this as ExtensionMethodGroupExpr;
+
                        if (a is CollectionElementInitializer.ElementInitializerArgument) {
                                Report.SymbolRelatedToPreviousError (method);
                                if ((expected_par.ParameterModifier (idx) & Parameter.Modifier.ISBYREF) != 0) {
@@ -3687,8 +3723,15 @@ namespace Mono.CSharp {
                                          TypeManager.CSharpSignature (method));
                        } else if (delegate_type == null) {
                                Report.SymbolRelatedToPreviousError (method);
-                               Report.Error (1502, loc, "The best overloaded method match for `{0}' has some invalid arguments",
-                                                 TypeManager.CSharpSignature (method));
+                               if (emg != null) {
+                                       Report.Error (1928, loc,
+                                               "Type `{0}' does not contain a member `{1}' and the best extension method overload `{2}' has some invalid arguments",
+                                               emg.ExtensionExpression.GetSignatureForError (),
+                                               emg.Name, TypeManager.CSharpSignature (method));
+                               } else {
+                                       Report.Error (1502, loc, "The best overloaded method match for `{0}' has some invalid arguments",
+                                               TypeManager.CSharpSignature (method));
+                               }
                        } else
                                Report.Error (1594, loc, "Delegate `{0}' has some invalid arguments",
                                        TypeManager.CSharpName (delegate_type));
@@ -3699,10 +3742,10 @@ namespace Mono.CSharp {
                        if (((mod & (Parameter.Modifier.REF | Parameter.Modifier.OUT)) ^
                                (a.Modifier & (Parameter.Modifier.REF | Parameter.Modifier.OUT))) != 0) {
                                if ((mod & Parameter.Modifier.ISBYREF) == 0)
-                                       Report.Error (1615, loc, "Argument `{0}' should not be passed with the `{1}' keyword",
+                                       Report.Error (1615, loc, "Argument `#{0}' does not require `{1}' modifier. Consider removing `{1}' modifier",
                                                index, Parameter.GetModifierSignature (a.Modifier));
                                else
-                                       Report.Error (1620, loc, "Argument `{0}' must be passed with the `{1}' keyword",
+                                       Report.Error (1620, loc, "Argument `#{0}' is missing `{1}' modifier",
                                                index, Parameter.GetModifierSignature (mod));
                        } else {
                                string p1 = a.GetSignatureForError ();
@@ -3713,7 +3756,14 @@ namespace Mono.CSharp {
                                        Report.SymbolRelatedToPreviousError (a.Expr.Type);
                                        Report.SymbolRelatedToPreviousError (paramType);
                                }
-                               Report.Error (1503, loc, "Argument {0}: Cannot convert type `{1}' to `{2}'", index, p1, p2);
+
+                               if (idx == 0 && emg != null) {
+                                       Report.Error (1929, loc,
+                                               "Extension method instance type `{0}' cannot be converted to `{1}'", p1, p2);
+                               } else {
+                                       Report.Error (1503, loc,
+                                               "Argument `#{0}' cannot convert `{1}' expression to type `{2}'", index, p1, p2);
+                               }
                        }
                }
 
@@ -3852,26 +3902,16 @@ namespace Mono.CSharp {
 
                                if (a_type != parameter)
                                        return 2;
-
-                               return 0;
-                       }
-
-                       // FIXME: Kill this abomination (EmitContext.TempEc)
-                       EmitContext prevec = EmitContext.TempEc;
-                       EmitContext.TempEc = ec;
-                       try {
+                       } else {
                                if (delegate_type != null ?
                                        !Delegate.IsTypeCovariant (argument.Expr, parameter) :
                                        !Convert.ImplicitConversionExists (ec, argument.Expr, parameter))
                                        return 2;
-
-                               if (arg_mod != param_mod)
-                                       return 1;
-
-                       } finally {
-                               EmitContext.TempEc = prevec;
                        }
 
+                       if (arg_mod != param_mod)
+                               return 1;
+
                        return 0;
                }
 
@@ -3988,6 +4028,19 @@ namespace Mono.CSharp {
                        return null;
                }
 
+               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
+               {
+                       base.MutateHoistedGenericType (storey);
+
+                       MethodInfo mi = best_candidate as MethodInfo;
+                       if (mi != null) {
+                               best_candidate = storey.MutateGenericMethod (mi);
+                               return;
+                       }
+
+                       best_candidate = storey.MutateConstructor ((ConstructorInfo) this);
+               }
+
                /// <summary>
                ///   Find the Applicable Function Members (7.4.2.1)
                ///
@@ -4117,8 +4170,12 @@ namespace Mono.CSharp {
                        }
 
                        Report.SetMessageRecorder (prev_recorder);
-                       if (msg_recorder != null && msg_recorder.PrintMessages ())
+                       if (msg_recorder != null && !msg_recorder.IsEmpty) {
+                               if (!may_fail)
+                                       msg_recorder.PrintMessages ();
+
                                return null;
+                       }
                        
                        int candidate_top = candidates.Count;
 
@@ -4570,7 +4627,8 @@ namespace Mono.CSharp {
        ///   Fully resolved expression that evaluates to a Field
        /// </summary>
        public class FieldExpr : MemberExpr, IAssignMethod, IMemoryLocation, IVariable {
-               public readonly FieldInfo FieldInfo;
+               public FieldInfo FieldInfo;
+               readonly Type constructed_generic_type;
                VariableInfo variable_info;
                
                LocalTemporary temp;
@@ -4591,6 +4649,12 @@ namespace Mono.CSharp {
                        loc = l;
                }
 
+               public FieldExpr (FieldInfo fi, Type genericType, Location l)
+                       : this (fi, l)
+               {
+                       this.constructed_generic_type = genericType;
+               }
+
                public override string Name {
                        get {
                                return FieldInfo.Name;
@@ -4714,18 +4778,6 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       AnonymousContainer am = ec.CurrentAnonymousMethod;
-                       if (am != null){
-                               if (!FieldInfo.IsStatic){
-                                       if (!am.IsIterator && (ec.TypeContainer is Struct)){
-                                               Report.Error (1673, loc,
-                                               "Anonymous methods inside structs cannot access instance members of `{0}'. Consider copying `{0}' to a local variable outside the anonymous method and using the local instead",
-                                                       "this");
-                                               return null;
-                                       }
-                               }
-                       }
-
                        IFixedBuffer fb = AttributeTester.GetFixedBuffer (FieldInfo);
                        if (fb != null) {
                                if (!ec.InFixedInitializer && ec.ContainerType.IsValueType) {
@@ -4743,7 +4795,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;
@@ -4794,7 +4846,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;
@@ -4856,19 +4908,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)
                {
@@ -4901,21 +4954,21 @@ namespace Mono.CSharp {
                        if (FieldInfo.IsStatic){
                                if (is_volatile)
                                        ig.Emit (OpCodes.Volatile);
-                               
-                               ig.Emit (OpCodes.Ldsfld, FieldInfo);
+
+                               ig.Emit (OpCodes.Ldsfld, GetConstructedFieldInfo ());
                        } else {
                                if (!prepared)
                                        EmitInstance (ec, false);
 
                                IFixedBuffer ff = AttributeTester.GetFixedBuffer (FieldInfo);
                                if (ff != null) {
-                                       ig.Emit (OpCodes.Ldflda, FieldInfo);
+                                       ig.Emit (OpCodes.Ldflda, GetConstructedFieldInfo ());
                                        ig.Emit (OpCodes.Ldflda, ff.Element);
                                } else {
                                        if (is_volatile)
                                                ig.Emit (OpCodes.Volatile);
 
-                                       ig.Emit (OpCodes.Ldfld, FieldInfo);
+                                       ig.Emit (OpCodes.Ldfld, GetConstructedFieldInfo ());
                                }
                        }
 
@@ -4961,13 +5014,14 @@ namespace Mono.CSharp {
                        }
 
                        if (is_static)
-                               ig.Emit (OpCodes.Stsfld, FieldInfo);
-                       else 
-                               ig.Emit (OpCodes.Stfld, FieldInfo);
+                               ig.Emit (OpCodes.Stsfld, GetConstructedFieldInfo ());
+                       else
+                               ig.Emit (OpCodes.Stfld, GetConstructedFieldInfo ());
                        
                        if (temp != null) {
                                temp.Emit (ec);
                                temp.Release (ec);
+                               temp = null;
                        }
                }
 
@@ -5030,13 +5084,30 @@ namespace Mono.CSharp {
 
 
                        if (FieldInfo.IsStatic){
-                               ig.Emit (OpCodes.Ldsflda, FieldInfo);
+                               ig.Emit (OpCodes.Ldsflda, GetConstructedFieldInfo ());
                        } else {
                                if (!prepared)
                                        EmitInstance (ec, false);
-                               ig.Emit (OpCodes.Ldflda, FieldInfo);
+                               ig.Emit (OpCodes.Ldflda, GetConstructedFieldInfo ());
                        }
                }
+
+               FieldInfo GetConstructedFieldInfo ()
+               {
+                       if (constructed_generic_type == null)
+                               return FieldInfo;
+#if GMCS_SOURCE
+                       return TypeBuilder.GetField (constructed_generic_type, FieldInfo);
+#else
+                       throw new NotSupportedException ();
+#endif                 
+               }
+               
+               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
+               {
+                       FieldInfo = storey.MutateField (FieldInfo);
+                       base.MutateHoistedGenericType (storey);
+               }               
        }
 
        
@@ -5089,18 +5160,25 @@ 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 ()
@@ -5181,6 +5259,15 @@ namespace Mono.CSharp {
                        }
                }
 
+               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
+               {
+                       if (InstanceExpression != null)
+                               InstanceExpression.MutateHoistedGenericType (storey);
+
+                       type = storey.MutateType (type);
+                       getter = storey.MutateGenericMethod (getter);
+               }
+
                bool InstanceResolve (EmitContext ec, bool lvalue_instance, bool must_do_cs1540_check)
                {
                        if (is_static) {
@@ -5250,7 +5337,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)
@@ -5641,73 +5728,68 @@ namespace Mono.CSharp {
                }
        }
 
-       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))
                                return null;
 
-                       if (ec.MustCaptureVariable (li)) {
-                               ScopeInfo scope = li.Block.CreateScopeInfo ();
-                               var = scope.AddLocal (li);
-                               type = var.Type;
+                       if (ec.MustCaptureVariable (li) && !ec.IsInProbingMode) {
+                               AnonymousMethodStorey storey = li.Block.Explicit.CreateAnonymousMethodStorey (ec);
+                               storey.CaptureLocalVariable (ec, li);
                        }
-                       
-                       return this;
-               }
 
-               public Variable Variable {
-                       get { return var != null ? var : li.Variable; }
+                       return this;
                }
                
                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 HoistedVariable HoistedVariable {
+                       get { return li.HoistedVariableReference; }
                }
-               
-               public void EmitThis (EmitContext ec)
-               {
-                       Variable.EmitInstance (ec);
+
+               public override bool IsFixed {
+                       get { return true; }
                }
-               
-               public void EmitStore (EmitContext ec)
-               {
-                       Variable.EmitAssign (ec);
+
+               public override bool IsRef {
+                       get { return false; }
                }
-               
-               public void AddressOf (EmitContext ec, AddressOp mode)
-               {
-                       EmitLoadAddress (ec);
+
+               protected override ILocalVariable Variable {
+                       get { return li; }
+               }
+
+               public override VariableInfo VariableInfo {
+                       get { throw new NotImplementedException (); }
                }
        }