2009-01-23 Marek Safar <marek.safar@gmail.com>
[mono.git] / mcs / mcs / expression.cs
index 2baec49d196916728c4d78a9c083eee94c5b162f..93e4db14fc4def3eaea94eb2b4a143ddf83868b1 100644 (file)
@@ -243,20 +243,17 @@ namespace Mono.CSharp {
                                if (expr_type == TypeManager.float_type) {
                                        FloatLiteral fl = e as FloatLiteral;
                                        // For better error reporting
-                                       if (fl != null) {
-                                               fl.Value = -fl.Value;
-                                               return fl;
-                                       }
+                                       if (fl != null)
+                                               return new FloatLiteral (-fl.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) {
-                                               dl.Value = -dl.Value;
-                                               return dl;
-                                       }
-                                       
+                                       if (dl != null)
+                                               return new DoubleLiteral (-dl.Value, e.Location);
+
                                        return new DoubleConstant (-((DoubleConstant)e).Value, e.Location);
                                }
                                if (expr_type == TypeManager.decimal_type)
@@ -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,10 +1372,10 @@ 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
                }
@@ -1448,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)
                {
@@ -2535,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) {
@@ -2581,9 +2580,9 @@ namespace Mono.CSharp {
 
                        if (RootContext.Version >= LanguageVersion.ISO_2 &&
                                ((TypeManager.IsNullableType (left.Type) && (right is NullLiteral || TypeManager.IsNullableType (right.Type) || TypeManager.IsValueType (right.Type))) ||
-                               (left.Type.IsValueType && right is NullLiteral) ||
+                               (TypeManager.IsValueType (left.Type) && right is NullLiteral) ||
                                (TypeManager.IsNullableType (right.Type) && (left is NullLiteral || TypeManager.IsNullableType (left.Type) || TypeManager.IsValueType (left.Type))) ||
-                               (right.Type.IsValueType && left is NullLiteral)))
+                               (TypeManager.IsValueType (right.Type) && left is NullLiteral)))
                                return new Nullable.LiftedBinaryOperator (oper, left, right, loc).Resolve (ec);
 
                        return DoResolveCore (ec, left, right);
@@ -2895,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;
                        }
 
@@ -2905,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;
                        }
 
@@ -4033,7 +4032,7 @@ namespace Mono.CSharp {
                LocalTemporary temp;
 
                #region Abstract
-               public abstract HoistedVariable HoistedVariable { get; }
+               public abstract HoistedVariable GetHoistedVariable (EmitContext ec);
                public abstract bool IsFixed { get; }
                public abstract bool IsRef { get; }
                public abstract string Name { get; }
@@ -4052,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;
                        }
 
@@ -4085,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;
                        }
 
@@ -4113,8 +4114,9 @@ namespace Mono.CSharp {
                public void EmitAssign (EmitContext ec, Expression source, bool leave_copy,
                                        bool prepare_for_load)
                {
-                       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;
                        }
 
@@ -4152,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)
@@ -4202,8 +4196,9 @@ 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;
                }
 
                //              
@@ -4372,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;
                }
 
@@ -4389,8 +4382,9 @@ 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;
                }
 
                //
@@ -4450,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);
                        }
 
@@ -4485,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)
@@ -4495,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 ();
                }
@@ -4840,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
@@ -4999,7 +5008,7 @@ namespace Mono.CSharp {
                        bool is_static = method.IsStatic;
                        if (!is_static){
                                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;
 
                                //
@@ -5012,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
@@ -5062,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);
@@ -5434,7 +5444,7 @@ namespace Mono.CSharp {
                                return null;
                        }
 
-                       bool is_struct = type.IsValueType;
+                       bool is_struct = TypeManager.IsStruct (type);
                        eclass = ExprClass.Value;
 
                        //
@@ -5623,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:
@@ -6270,7 +6280,7 @@ 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)) {
 
@@ -6520,8 +6530,9 @@ namespace Mono.CSharp {
                        return this;
                }
 
-               public override HoistedVariable HoistedVariable {
-                       get { return null; }
+               public override HoistedVariable GetHoistedVariable (EmitContext ec)
+               {
+                       return null;
                }
        }
        
@@ -6574,17 +6585,25 @@ namespace Mono.CSharp {
                        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;
+
+                               storey = temp;
+                       }
 
-               public override HoistedVariable HoistedVariable {
-                       get { return TopToplevelBlock.HoistedThisVariable; }
+                       return null;
                }
 
                public override bool IsRef {
@@ -6595,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)
@@ -6647,24 +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 should be optimized, see test-anon-75.cs
-                                               //
-                                               // `this' variable has its own scope which is mostly empty
-                                               // and causes creation of extraneous storey references.
-                                               // Also it's hard to remove `this' dependencies when we Undo
-                                               // this access.
-                                               //
-                                               AnonymousMethodStorey scope = TopToplevelBlock.Explicit.CreateAnonymousMethodStorey (ec);
-                                               if (HoistedVariable == null) {
-                                                       TopToplevelBlock.HoistedThisVariable = scope.CaptureThis (ec, this);
-                                               }
-                                       }
+                               if (am != null && ec.IsVariableCapturingRequired) {
+                                       am.SetHasThisAccess ();
                                }
                        }
                        
@@ -6676,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");
@@ -6753,11 +6747,6 @@ namespace Mono.CSharp {
                        target.block = clonectx.LookupBlock (block);
                }
 
-               public void RemoveHoisting ()
-               {
-                       TopToplevelBlock.HoistedThisVariable = null;
-               }
-
                public override void SetHasAddressTaken ()
                {
                        // Nothing
@@ -7304,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)
@@ -7328,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;
                        }
 
@@ -7413,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
@@ -7422,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);
@@ -7474,26 +7460,26 @@ 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;
 
@@ -7511,7 +7497,7 @@ namespace Mono.CSharp {
                                if (silent)
                                        return null;
 
-                               Error_IdentifierNotFound (rc, new_expr, LookupIdentifier);
+                               Error_IdentifierNotFound (rc, expr_resolved, LookupIdentifier);
                                return null;
                        }
 
@@ -7522,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));
 
@@ -7538,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
@@ -7557,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;
                        }
 
@@ -7827,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);
@@ -7958,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
@@ -8005,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;
@@ -8825,7 +8811,6 @@ namespace Mono.CSharp {
 
                private EmptyExpressionStatement ()
                {
-                       type = TypeManager.object_type;
                        eclass = ExprClass.Value;
                        loc = Location.Null;
                }
@@ -8842,6 +8827,7 @@ namespace Mono.CSharp {
 
                public override Expression DoResolve (EmitContext ec)
                {
+                       type = TypeManager.object_type;
                        return this;
                }
 
@@ -8937,7 +8923,7 @@ namespace Mono.CSharp {
                        Type ltype = lexpr.Type;
 #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);
@@ -9232,7 +9218,7 @@ 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;
                }
@@ -9735,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);
                }