2004-08-02 Martin Baulig <martin@ximian.com>
[mono.git] / mcs / gmcs / ecore.cs
index 8a8ac18cd3d83bf168654004bd9dc94ba9c4065a..30968d5e035125cd83b17422b22963b43f08021e 100755 (executable)
@@ -61,7 +61,10 @@ namespace Mono.CSharp {
 
                // Disable control flow analysis while resolving the expression.
                // This is used when resolving the instance expression of a field expression.
-               DisableFlowAnalysis     = 16
+               DisableFlowAnalysis     = 16,
+
+               // Set if this is resolving the first part of a MemberAccess.
+               Intermediate            = 32
        }
 
        //
@@ -92,6 +95,25 @@ namespace Mono.CSharp {
                void AddressOf (EmitContext ec, AddressOp mode);
        }
 
+       /// <summary>
+       ///   We are either a namespace or a type.
+       ///   If we're a type, `IsType' is true and we may use `Type' to get
+       ///   a TypeExpr representing that type.
+       /// </summary>
+       public interface IAlias {
+               bool IsType {
+                       get;
+               }
+
+               string Name {
+                       get;
+               }
+
+               TypeExpr Type {
+                       get;
+               }
+       }
+
        /// <summary>
        ///   This interface is implemented by variables
        /// </summary>
@@ -202,6 +224,18 @@ namespace Mono.CSharp {
                                Warning (warning, s);
                }
 
+               /// <summary>
+               /// Tests presence of ObsoleteAttribute and report proper error
+               /// </summary>
+               protected void CheckObsoleteAttribute (Type type)
+               {
+                       ObsoleteAttribute obsolete_attr = AttributeTester.GetObsoleteAttribute (type);
+                       if (obsolete_attr == null)
+                               return;
+
+                       AttributeTester.Report_ObsoleteMessage (obsolete_attr, type.FullName, loc);
+               }
+
                /// <summary>
                ///   Performs semantic analysis on the Expression
                /// </summary>
@@ -274,8 +308,10 @@ namespace Mono.CSharp {
                                ec.DoFlowAnalysis = false;
 
                        Expression e;
+                       bool intermediate = (flags & ResolveFlags.Intermediate) == ResolveFlags.Intermediate;
                        if (this is SimpleName)
-                               e = ((SimpleName) this).DoResolveAllowStatic (ec);
+                               e = ((SimpleName) this).DoResolveAllowStatic (ec, intermediate);
+
                        else 
                                e = DoResolve (ec);
 
@@ -289,7 +325,7 @@ namespace Mono.CSharp {
 
                                if ((flags & ResolveFlags.SimpleName) == 0) {
                                        MemberLookupFailed (ec, null, ec.ContainerType, s.Name,
-                                                           0, ec.DeclSpace.Name, loc);
+                                                           ec.DeclSpace.Name, loc);
                                        return null;
                                }
 
@@ -376,7 +412,7 @@ namespace Mono.CSharp {
                                if (e is SimpleName){
                                        SimpleName s = (SimpleName) e;
                                        MemberLookupFailed (ec, null, ec.ContainerType, s.Name,
-                                                           0, ec.DeclSpace.Name, loc);
+                                                           ec.DeclSpace.Name, loc);
                                        return null;
                                }
 
@@ -466,7 +502,11 @@ namespace Mono.CSharp {
                        else if (t == TypeManager.bool_type)
                                return new BoolConstant ((bool) v);
                        else if (TypeManager.IsEnumType (t)){
-                               Constant e = Constantify (v, TypeManager.TypeToCoreType (v.GetType ()));
+                               Type real_type = TypeManager.TypeToCoreType (v.GetType ());
+                               if (real_type == t)
+                                       real_type = real_type.UnderlyingSystemType;
+
+                               Constant e = Constantify (v, real_type);
 
                                return new EnumConstant (e, t);
                        } else
@@ -492,6 +532,9 @@ namespace Mono.CSharp {
                        return null;
                }
 
+
+               private static ArrayList almostMatchedMembers = new ArrayList (4);
+
                //
                // FIXME: Probably implement a cache for (t,name,current_access_set)?
                //
@@ -523,7 +566,7 @@ namespace Mono.CSharp {
                public static Expression MemberLookup (EmitContext ec, Type queried_type, string name,
                                                       MemberTypes mt, BindingFlags bf, Location loc)
                {
-                       return MemberLookup (ec, ec.ContainerType, null, queried_type, name, 0, mt, bf, loc);
+                       return MemberLookup (ec, ec.ContainerType, null, queried_type, name, mt, bf, loc);
                }
 
                //
@@ -533,13 +576,14 @@ namespace Mono.CSharp {
 
                public static Expression MemberLookup (EmitContext ec, Type container_type,
                                                       Type qualifier_type, Type queried_type,
-                                                      string name, int num_type_arguments,
-                                                      MemberTypes mt, BindingFlags bf,
-                                                      Location loc)
+                                                      string name, MemberTypes mt,
+                                                      BindingFlags bf, Location loc)
                {
-                       MemberInfo [] mi = TypeManager.MemberLookup (container_type, qualifier_type,
-                                                                    queried_type, num_type_arguments,
-                                                                    mt, bf, name);
+                       almostMatchedMembers.Clear ();
+
+                       MemberInfo [] mi = TypeManager.MemberLookup (
+                               container_type, qualifier_type,queried_type, mt, bf, name,
+                               almostMatchedMembers);
 
                        if (mi == null)
                                return null;
@@ -568,34 +612,25 @@ namespace Mono.CSharp {
                        BindingFlags.Static |
                        BindingFlags.Instance;
 
-               public static Expression MemberLookup (EmitContext ec, Type queried_type,
-                                                      string name, int num_type_arguments,
-                                                      Location loc)
-               {
-                       return MemberLookup (ec, ec.ContainerType, null, queried_type, name,
-                                            num_type_arguments, AllMemberTypes, AllBindingFlags,
-                                            loc);
-               }
-
                public static Expression MemberLookup (EmitContext ec, Type queried_type,
                                                       string name, Location loc)
                {
                        return MemberLookup (ec, ec.ContainerType, null, queried_type, name,
-                                            0, AllMemberTypes, AllBindingFlags, loc);
+                                            AllMemberTypes, AllBindingFlags, loc);
                }
 
                public static Expression MemberLookup (EmitContext ec, Type qualifier_type,
                                                       Type queried_type, string name, Location loc)
                {
                        return MemberLookup (ec, ec.ContainerType, qualifier_type, queried_type,
-                                            name, 0, AllMemberTypes, AllBindingFlags, loc);
+                                            name, AllMemberTypes, AllBindingFlags, loc);
                }
 
                public static Expression MethodLookup (EmitContext ec, Type queried_type,
                                                       string name, Location loc)
                {
                        return MemberLookup (ec, ec.ContainerType, null, queried_type, name,
-                                            0, MemberTypes.Method, AllBindingFlags, loc);
+                                            MemberTypes.Method, AllBindingFlags, loc);
                }
 
                /// <summary>
@@ -606,45 +641,68 @@ namespace Mono.CSharp {
                /// </summary>
                public static Expression MemberLookupFinal (EmitContext ec, Type qualifier_type,
                                                            Type queried_type, string name,
-                                                           int num_type_arguments, Location loc)
+                                                           Location loc)
                {
                        return MemberLookupFinal (ec, qualifier_type, queried_type, name,
-                                                 num_type_arguments, AllMemberTypes,
-                                                 AllBindingFlags, loc);
+                                                 AllMemberTypes, AllBindingFlags, loc);
                }
 
                public static Expression MemberLookupFinal (EmitContext ec, Type qualifier_type,
                                                            Type queried_type, string name,
-                                                           int num_type_arguments, MemberTypes mt,
-                                                           BindingFlags bf, Location loc)
+                                                           MemberTypes mt, BindingFlags bf,
+                                                           Location loc)
                {
                        Expression e;
 
                        int errors = Report.Errors;
 
                        e = MemberLookup (ec, ec.ContainerType, qualifier_type, queried_type,
-                                         name, num_type_arguments, mt, bf, loc);
+                                         name, mt, bf, loc);
 
-                       if (e != null)
-                               return e;
+                       if (e == null && errors == Report.Errors)
+                               // No errors were reported by MemberLookup, but there was an error.
+                               MemberLookupFailed (ec, qualifier_type, queried_type, name,
+                                                   null, loc);
 
-                       // Error has already been reported.
-                       if (errors < Report.Errors)
-                               return null;
-
-                       MemberLookupFailed (ec, qualifier_type, queried_type, name,
-                                           num_type_arguments, null, loc);
-                       return null;
+                       return e;
                }
 
                public static void MemberLookupFailed (EmitContext ec, Type qualifier_type,
                                                       Type queried_type, string name,
-                                                      int num_type_arguments, string class_name,
-                                                      Location loc)
-               {
+                                                      string class_name, Location loc)
+               {
+                       if (almostMatchedMembers.Count != 0) {
+                               if (qualifier_type == null) {
+                                       foreach (MemberInfo m in almostMatchedMembers)
+                                               Report.Error (38, loc, 
+                                                             "Cannot access non-static member `{0}' via nested type `{1}'", 
+                                                             TypeManager.GetFullNameSignature (m),
+                                                             TypeManager.CSharpName (ec.ContainerType));
+                                       return;
+                               }
+
+
+                               if (qualifier_type != ec.ContainerType) {
+                                       // Although a derived class can access protected members of
+                                       // its base class it cannot do so through an instance of the
+                                       // base class (CS1540).  If the qualifier_type is a parent of the
+                                       // ec.ContainerType and the lookup succeeds with the latter one,
+                                       // then we are in this situation.
+                                       foreach (MemberInfo m in almostMatchedMembers)
+                                               Report.Error (1540, loc, 
+                                                             "Cannot access protected member `{0}' via a qualifier of type `{1}';"
+                                                             + " the qualifier must be of type `{2}' (or derived from it)", 
+                                                             TypeManager.GetFullNameSignature (m),
+                                                             TypeManager.CSharpName (qualifier_type),
+                                                             TypeManager.CSharpName (ec.ContainerType));
+                                       return;
+                               }
+                               almostMatchedMembers.Clear ();
+                       }
+
                        MemberInfo[] mi = TypeManager.MemberLookup (queried_type, null, queried_type,
-                                                                   -1, AllMemberTypes, AllBindingFlags |
-                                                                   BindingFlags.NonPublic, name);
+                                                                   AllMemberTypes, AllBindingFlags |
+                                                                   BindingFlags.NonPublic, name, null);
 
                        if (mi == null) {
                                if (class_name != null)
@@ -658,8 +716,8 @@ namespace Mono.CSharp {
                        }
 
                        if (TypeManager.MemberLookup (queried_type, null, queried_type,
-                                                     0, AllMemberTypes, AllBindingFlags |
-                                                     BindingFlags.NonPublic, name) == null) {
+                                                     AllMemberTypes, AllBindingFlags |
+                                                     BindingFlags.NonPublic, name, null) == null) {
                                if ((mi.Length == 1) && (mi [0] is Type)) {
                                        Type t = (Type) mi [0];
 
@@ -672,42 +730,15 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       if ((qualifier_type != null) && (qualifier_type != ec.ContainerType) &&
-                           ec.ContainerType.IsSubclassOf (qualifier_type)) {
-                               // Although a derived class can access protected members of
-                               // its base class it cannot do so through an instance of the
-                               // base class (CS1540).  If the qualifier_type is a parent of the
-                               // ec.ContainerType and the lookup succeeds with the latter one,
-                               // then we are in this situation.
 
-                               mi = TypeManager.MemberLookup (
-                                       ec.ContainerType, ec.ContainerType, ec.ContainerType,
-                                       0, AllMemberTypes, AllBindingFlags, name);
-
-                               if (mi != null) {
-                                       Report.Error (
-                                               1540, loc, "Cannot access protected member `" +
-                                               TypeManager.CSharpName (qualifier_type) + "." +
-                                               name + "' " + "via a qualifier of type `" +
-                                               TypeManager.CSharpName (qualifier_type) + "'; the " +
-                                               "qualifier must be of type `" +
-                                               TypeManager.CSharpName (ec.ContainerType) + "' " +
-                                               "(or derived from it)");
-                                       return;
-                               }
-                       }
 
                        if (qualifier_type != null)
-                               Report.Error (
-                                       122, loc, "`" + TypeManager.CSharpName (qualifier_type) + "." +
-                                       name + "' is inaccessible due to its protection level");
+                               Report.Error_T (122, loc, TypeManager.CSharpName (qualifier_type) + "." + name);
                        else if (name == ".ctor") {
                                Report.Error (143, loc, String.Format ("The type {0} has no constructors defined",
                                                                       TypeManager.CSharpName (queried_type)));
                        } else {
-                               Report.Error (
-                                       122, loc, "`" + name + "' is inaccessible due to its " +
-                                       "protection level");
+                               Report.Error_T (122, loc, name);
                }
                }
 
@@ -747,7 +778,8 @@ namespace Mono.CSharp {
 
                        ArrayList arguments = new ArrayList ();
                        arguments.Add (new Argument (e, Argument.AType.Expression));
-                       method = Invocation.OverloadResolve (ec, (MethodGroupExpr) operator_group, arguments, loc);
+                       method = Invocation.OverloadResolve (
+                               ec, (MethodGroupExpr) operator_group, arguments, false, loc);
 
                        if (method == null)
                                return null;
@@ -1248,13 +1280,6 @@ namespace Mono.CSharp {
                                return 0;
                }
 
-               //
-               // Default implementation of IAssignMethod.CacheTemporaries
-               //
-               public void CacheTemporaries (EmitContext ec)
-               {
-               }
-
                static void Error_NegativeArrayIndex (Location loc)
                {
                        Report.Error (284, loc, "Can not create array with a negative size");
@@ -1545,6 +1570,10 @@ namespace Mono.CSharp {
                {
                        return Child.ConvertToInt ();
                }
+               
+               public override bool IsZeroInteger {
+                       get { return Child.IsZeroInteger; }
+               }
        }
 
        /// <summary>
@@ -1558,11 +1587,13 @@ namespace Mono.CSharp {
                public BoxedCast (Expression expr)
                        : base (expr, TypeManager.object_type) 
                {
+                       eclass = ExprClass.Value;
                }
 
                public BoxedCast (Expression expr, Type target_type)
                        : base (expr, target_type)
                {
+                       eclass = ExprClass.Value;
                }
                
                public override Expression DoResolve (EmitContext ec)
@@ -1601,9 +1632,13 @@ namespace Mono.CSharp {
                        ILGenerator ig = ec.ig;
                        
                        base.Emit (ec);
-                       ig.Emit (OpCodes.Unbox, t);
+                       if (t.IsGenericParameter)
+                               ig.Emit (OpCodes.Unbox_Any, t);
+                       else {
+                               ig.Emit (OpCodes.Unbox, t);
 
-                       LoadFromPtr (ig, t);
+                               LoadFromPtr (ig, t);
+                       }
                }
        }
        
@@ -1886,9 +1921,14 @@ namespace Mono.CSharp {
                {
                        base.Emit (ec);
 
-                       ec.ig.Emit (OpCodes.Castclass, type);
-               }                       
-               
+                       if (child.Type.IsGenericParameter)
+                               ec.ig.Emit (OpCodes.Box, child.Type);
+
+                       if (type.IsGenericParameter)
+                               ec.ig.Emit (OpCodes.Unbox_Any, type);
+                       else
+                               ec.ig.Emit (OpCodes.Castclass, type);
+               }
        }
        
        /// <summary>
@@ -1921,7 +1961,7 @@ namespace Mono.CSharp {
        /// </remarks>
        public class SimpleName : Expression {
                public string Name;
-               public int NumTypeArguments;
+               public readonly TypeArguments Arguments;
 
                //
                // If true, then we are a simple name, not composed with a ".
@@ -1942,10 +1982,10 @@ namespace Mono.CSharp {
                        is_base = true;
                }
 
-               public SimpleName (string name, int num_type_arguments, Location l)
+               public SimpleName (string name, TypeArguments args, Location l)
                {
                        Name = name;
-                       NumTypeArguments = num_type_arguments;
+                       Arguments = args;
                        loc = l;
                        is_base = true;
                }
@@ -1984,26 +2024,26 @@ namespace Mono.CSharp {
                
                public override Expression DoResolve (EmitContext ec)
                {
-                       return SimpleNameResolve (ec, null, false);
+                       return SimpleNameResolve (ec, null, false, false);
                }
 
                public override Expression DoResolveLValue (EmitContext ec, Expression right_side)
                {
-                       return SimpleNameResolve (ec, right_side, false);
+                       return SimpleNameResolve (ec, right_side, false, false);
                }
                
 
-               public Expression DoResolveAllowStatic (EmitContext ec)
+               public Expression DoResolveAllowStatic (EmitContext ec, bool intermediate)
                {
-                       return SimpleNameResolve (ec, null, true);
+                       return SimpleNameResolve (ec, null, true, intermediate);
                }
 
                public override Expression ResolveAsTypeStep (EmitContext ec)
                {
                        DeclSpace ds = ec.DeclSpace;
                        NamespaceEntry ns = ds.NamespaceEntry;
-                       Type t;
-                       string alias_value;
+                       TypeExpr t;
+                       IAlias alias_value;
 
                        //
                        // Since we are cheating: we only do the Alias lookup for
@@ -2020,7 +2060,7 @@ namespace Mono.CSharp {
 
                        if (ec.ResolvingTypeTree){
                                int errors = Report.Errors;
-                               Type dt = ds.FindType (loc, Name, NumTypeArguments);
+                               Type dt = ds.FindType (loc, Name);
                                
                                if (Report.Errors != errors)
                                        return null;
@@ -2029,8 +2069,10 @@ namespace Mono.CSharp {
                                        return new TypeExpression (dt, loc);
 
                                if (alias_value != null){
-                                       if ((t = RootContext.LookupType (ds, alias_value, true, NumTypeArguments, loc)) != null)
-                                               return new TypeExpression (t, loc);
+                                       if (alias_value.IsType)
+                                               return alias_value.Type;
+                                       if ((t = RootContext.LookupType (ds, alias_value.Name, true, loc)) != null)
+                                               return t;
                                }
                        }
 
@@ -2038,11 +2080,13 @@ namespace Mono.CSharp {
                        // First, the using aliases
                        //
                        if (alias_value != null){
-                               if ((t = RootContext.LookupType (ds, alias_value, true, loc)) != null)
-                                       return new TypeExpression (t, loc);
+                               if (alias_value.IsType)
+                                       return alias_value.Type;
+                               if ((t = RootContext.LookupType (ds, alias_value.Name, true, loc)) != null)
+                                       return t;
                                
                                // we have alias value, but it isn't Type, so try if it's namespace
-                               return new SimpleName (alias_value, loc);
+                               return new SimpleName (alias_value.Name, loc);
                        }
 
                        //
@@ -2050,14 +2094,41 @@ namespace Mono.CSharp {
                        // or a namespace.
                        //
 
-                       if ((t = RootContext.LookupType (ds, Name, true, NumTypeArguments, loc)) != null)
-                               return new TypeExpression (t, loc);
+                       if ((t = RootContext.LookupType (ds, Name, true, loc)) != null)
+                               return t;
                                
                        // No match, maybe our parent can compose us
                        // into something meaningful.
                        return this;
                }
 
+               Expression SimpleNameResolve (EmitContext ec, Expression right_side,
+                                             bool allow_static, bool intermediate)
+               {
+                       Expression e = DoSimpleNameResolve (ec, right_side, allow_static, intermediate);
+                       if (e == null)
+                               return null;
+
+                       Block current_block = ec.CurrentBlock;
+                       if (current_block != null){
+                               LocalInfo vi = current_block.GetLocalInfo (Name);
+                               if (is_base &&
+                                   current_block.IsVariableNameUsedInChildBlock(Name)) {
+                                       Report.Error (135, Location,
+                                                     "'{0}' has a different meaning in a " +
+                                                     "child block", Name);
+                                       return null;
+                               }
+                       }
+
+                       if (e.Type != null && e.Type.IsPointer && !ec.InUnsafe) {
+                               UnsafeError (loc);
+                               return null;
+                       }
+
+                       return e;
+               }
+
                /// <remarks>
                ///   7.5.2: Simple Names. 
                ///
@@ -2075,7 +2146,7 @@ namespace Mono.CSharp {
                ///   Type is both an instance variable and a Type;  Type.GetType
                ///   is the static method not an instance method of type.
                /// </remarks>
-               Expression SimpleNameResolve (EmitContext ec, Expression right_side, bool allow_static)
+               Expression DoSimpleNameResolve (EmitContext ec, Expression right_side, bool allow_static, bool intermediate)
                {
                        Expression e = null;
 
@@ -2123,8 +2194,7 @@ namespace Mono.CSharp {
                                if (lookup_ds.TypeBuilder == null)
                                        break;
 
-                               e = MemberLookup (ec, lookup_ds.TypeBuilder,
-                                                 Name, NumTypeArguments, loc);
+                               e = MemberLookup (ec, lookup_ds.TypeBuilder, Name, loc);
                                if (e != null)
                                        break;
 
@@ -2132,8 +2202,7 @@ namespace Mono.CSharp {
                        } while (lookup_ds != null);
 
                        if (e == null && ec.ContainerType != null)
-                               e = MemberLookup (ec, ec.ContainerType,
-                                                 Name, NumTypeArguments, loc);
+                               e = MemberLookup (ec, ec.ContainerType, Name, loc);
 
                        if (e == null) {
                                //
@@ -2144,9 +2213,12 @@ namespace Mono.CSharp {
                                //
                                NamespaceEntry ns = ec.DeclSpace.NamespaceEntry;
                                if (is_base && ns != null){
-                                       string alias_value = ns.LookupAlias (Name);
+                                       IAlias alias_value = ns.LookupAlias (Name);
                                        if (alias_value != null){
-                                               Name = alias_value;
+                                               if (alias_value.IsType)
+                                                       return alias_value.Type;
+
+                                               Name = alias_value.Name;
                                                Type t;
 
                                                if ((t = TypeManager.LookupType (Name)) != null)
@@ -2173,26 +2245,34 @@ namespace Mono.CSharp {
                                if (me == null)
                                        return e;
 
+                               if (Arguments != null) {
+                                       MethodGroupExpr mg = me as MethodGroupExpr;
+                                       if (mg == null)
+                                               return null;
+
+                                       return mg.ResolveGeneric (ec, Arguments);
+                               }
+
                                // This fails if ResolveMemberAccess() was unable to decide whether
                                // it's a field or a type of the same name.
+                               
                                if (!me.IsStatic && (me.InstanceExpression == null))
                                        return e;
 
                                if (!me.IsStatic &&
-                                   TypeManager.IsNestedChildOf (me.InstanceExpression.Type, me.DeclaringType) &&
-                                   !me.InstanceExpression.Type.IsSubclassOf (me.DeclaringType)) {
+                                   TypeManager.IsSubclassOrNestedChildOf (me.InstanceExpression.Type, me.DeclaringType) &&
+                                   me.InstanceExpression.Type != me.DeclaringType &&
+                                   !me.InstanceExpression.Type.IsSubclassOf (me.DeclaringType) &&
+                                   (!intermediate || !MemberAccess.IdenticalNameAndTypeName (ec, this, e, loc))) {
                                        Error (38, "Cannot access nonstatic member `" + me.Name + "' of " +
                                               "outer type `" + me.DeclaringType + "' via nested type `" +
                                               me.InstanceExpression.Type + "'");
                                        return null;
                                }
 
-                               if (right_side != null)
-                                       e = e.DoResolveLValue (ec, right_side);
-                               else
-                                       e = e.DoResolve (ec);
-
-                               return e;                               
+                               return (right_side != null)
+                                       ? e.DoResolveLValue (ec, right_side)
+                                       : e.DoResolve (ec);
                        }
 
                        if (ec.IsStatic || ec.IsFieldInitializer){
@@ -2225,7 +2305,7 @@ namespace Mono.CSharp {
        /// <summary>
        ///   Fully resolved expression that evaluates to a type
        /// </summary>
-       public abstract class TypeExpr : Expression {
+       public abstract class TypeExpr : Expression, IAlias {
                override public Expression ResolveAsTypeStep (EmitContext ec)
                {
                        TypeExpr t = DoResolveAsTypeStep (ec);
@@ -2276,6 +2356,7 @@ namespace Mono.CSharp {
                {
                        if (Type == TypeManager.enum_type ||
                            (Type == TypeManager.value_type && RootContext.StdLib) ||
+                           Type == TypeManager.multicast_delegate_type ||
                            Type == TypeManager.delegate_type ||
                            Type == TypeManager.array_type)
                                return false;
@@ -2290,11 +2371,6 @@ namespace Mono.CSharp {
                        }
                }
 
-               public virtual TypeExpr[] GetInterfaces ()
-               {
-                       return TypeManager.GetInterfaces (Type);
-               }
-
                public abstract TypeExpr DoResolveAsTypeStep (EmitContext ec);
 
                public virtual Type ResolveType (EmitContext ec)
@@ -2319,13 +2395,28 @@ namespace Mono.CSharp {
                        return Type == tobj.Type;
                }
 
+               public override int GetHashCode ()
+               {
+                       return Type.GetHashCode ();
+               }
+               
                public override string ToString ()
                {
                        return Name;
                }
+
+               bool IAlias.IsType {
+                       get { return true; }
+               }
+
+               TypeExpr IAlias.Type {
+                       get {
+                               return this;
+                       }
+               }
        }
 
-       public class TypeExpression : TypeExpr {
+       public class TypeExpression : TypeExpr, IAlias {
                public TypeExpression (Type t, Location l)
                {
                        Type = t;
@@ -2343,6 +2434,12 @@ namespace Mono.CSharp {
                                return Type.ToString ();
                        }
                }
+
+               string IAlias.Name {
+                       get {
+                               return Type.FullName != null ? Type.FullName : Type.Name;
+                       }
+               }
        }
 
        /// <summary>
@@ -2360,8 +2457,17 @@ namespace Mono.CSharp {
 
                public override TypeExpr DoResolveAsTypeStep (EmitContext ec)
                {
-                       if (type == null)
-                               type = RootContext.LookupType (ec.DeclSpace, name, false, Location.Null);
+                       if (type == null) {
+                               TypeExpr texpr = RootContext.LookupType (
+                                       ec.DeclSpace, name, false, Location.Null);
+                               if (texpr == null)
+                                       return null;
+
+                               type = texpr.ResolveType (ec);
+                               if (type == null)
+                                       return null;
+                       }
+
                        return this;
                }
 
@@ -2372,6 +2478,99 @@ namespace Mono.CSharp {
                }
        }
 
+       public class TypeAliasExpression : TypeExpr, IAlias {
+               TypeExpr texpr;
+               TypeArguments args;
+               string name;
+
+               public TypeAliasExpression (TypeExpr texpr, TypeArguments args, Location l)
+               {
+                       this.texpr = texpr;
+                       this.args = args;
+                       loc = texpr.Location;
+
+                       eclass = ExprClass.Type;
+                       if (args != null)
+                               name = texpr.Name + "<" + args.ToString () + ">";
+                       else
+                               name = texpr.Name;
+               }
+
+               public override string Name {
+                       get { return name; }
+               }
+
+               public override TypeExpr DoResolveAsTypeStep (EmitContext ec)
+               {
+                       Type type = texpr.ResolveType (ec);
+                       if (type == null)
+                               return null;
+
+                       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);
+                       } else if (num_args > 0) {
+                               Report.Error (305, loc,
+                                             "Using the generic type `{0}' " +
+                                             "requires {1} type arguments",
+                                             TypeManager.GetFullName (type), num_args);
+                               return null;
+                       }
+
+                       return new TypeExpression (type, loc);
+               }
+
+               public override Type ResolveType (EmitContext ec)
+               {
+                       TypeExpr t = ResolveAsTypeTerminal (ec);
+                       if (t == null)
+                               return null;
+
+                       type = t.ResolveType (ec);
+                       return type;
+               }
+
+               public override bool CheckAccessLevel (DeclSpace ds)
+               {
+                       return texpr.CheckAccessLevel (ds);
+               }
+
+               public override bool AsAccessible (DeclSpace ds, int flags)
+               {
+                       return texpr.AsAccessible (ds, flags);
+               }
+
+               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; }
+               }
+
+               public override bool IsAttribute {
+                       get { return texpr.IsAttribute; }
+               }
+       }
+
        /// <summary>
        ///   MethodGroup Expression.
        ///  
@@ -2382,6 +2581,7 @@ namespace Mono.CSharp {
                Expression instance_expression = null;
                bool is_explicit_impl = false;
                bool has_type_arguments = false;
+               bool identical_type_name = false;
                
                public MethodGroupExpr (MemberInfo [] mi, Location l)
                {
@@ -2456,10 +2656,20 @@ namespace Mono.CSharp {
                        }
                }
 
+               public bool IdenticalTypeName {
+                       get {
+                               return identical_type_name;
+                       }
+
+                       set {
+                               identical_type_name = value;
+                       }
+               }
+
                public string Name {
                        get {
-                                return TypeManager.CSharpSignature (
-                                       Methods [Methods.Length - 1]);
+                               //return Methods [0].Name;
+                                return Methods [Methods.Length - 1].Name;
                        }
                }
 
@@ -2543,6 +2753,55 @@ namespace Mono.CSharp {
                {
                        return RemoveMethods (false);
                }
+
+               public Expression ResolveGeneric (EmitContext ec, TypeArguments args)
+               {
+                       if (args.Resolve (ec) == false)
+                               return null;
+
+                       Type[] atypes = args.Arguments;
+
+                       int first_count = 0;
+                       MethodInfo first = null;
+
+                       ArrayList list = new ArrayList ();
+                       foreach (MethodBase mb in Methods) {
+                               MethodInfo mi = mb as MethodInfo;
+                               if ((mi == null) || !mi.HasGenericParameters)
+                                       continue;
+
+                               Type[] gen_params = mi.GetGenericArguments ();
+
+                               if (first == null) {
+                                       first = mi;
+                                       first_count = gen_params.Length;
+                               }
+
+                               if (gen_params.Length != atypes.Length)
+                                       continue;
+
+                               list.Add (mi.BindGenericParameters (atypes));
+                       }
+
+                       if (list.Count > 0) {
+                               MethodGroupExpr new_mg = new MethodGroupExpr (list, Location);
+                               new_mg.InstanceExpression = InstanceExpression;
+                               new_mg.HasTypeArguments = true;
+                               return new_mg;
+                       }
+
+                       if (first != null)
+                               Report.Error (
+                                       305, loc, "Using the generic method `{0}' " +
+                                       "requires {1} type arguments", Name,
+                                       first_count);
+                       else
+                               Report.Error (
+                                       308, loc, "The non-generic method `{0}' " +
+                                       "cannot be used with type arguments", Name);
+
+                       return null;
+               }
        }
 
        /// <summary>
@@ -2553,6 +2812,9 @@ namespace Mono.CSharp {
                Expression instance_expr;
                VariableInfo variable_info;
                
+               LocalTemporary temp;
+               bool prepared;
+               
                public FieldExpr (FieldInfo fi, Location l)
                {
                        FieldInfo = fi;
@@ -2622,6 +2884,19 @@ namespace Mono.CSharp {
                                        return null;
                        }
 
+                       ObsoleteAttribute oa;
+                       FieldBase f = TypeManager.GetField (FieldInfo);
+                       if (f != null) {
+                               oa = f.GetObsoleteAttribute (ec.DeclSpace);
+                               if (oa != null)
+                                       AttributeTester.Report_ObsoleteMessage (oa, f.GetSignatureForError (), loc);
+                               // To be sure that type is external because we do not register generated fields
+                        } else if (!(FieldInfo.DeclaringType is TypeBuilder)) {                                
+                               oa = AttributeTester.GetMemberObsoleteAttribute (FieldInfo);
+                               if (oa != null)
+                                       AttributeTester.Report_ObsoleteMessage (oa, TypeManager.GetFullNameSignature (FieldInfo), loc);
+                       }
+
                        // If the instance expression is a local variable or parameter.
                        IVariable var = instance_expr as IVariable;
                        if ((var == null) || (var.VariableInfo == null))
@@ -2704,8 +2979,8 @@ namespace Mono.CSharp {
 
                        return true;
                }
-
-               override public void Emit (EmitContext ec)
+               
+               public void Emit (EmitContext ec, bool leave_copy)
                {
                        ILGenerator ig = ec.ig;
                        bool is_volatile = false;
@@ -2725,66 +3000,52 @@ namespace Mono.CSharp {
                                        ig.Emit (OpCodes.Volatile);
                                
                                ig.Emit (OpCodes.Ldsfld, FieldInfo);
-                               return;
-                       }
-                       
-                       if (instance_expr.Type.IsValueType){
-                               IMemoryLocation ml;
-                               LocalTemporary tempo = null;
-                               
-                               if (!(instance_expr is IMemoryLocation)){
-                                       tempo = new LocalTemporary (ec, instance_expr.Type);
-                                       
-                                       if (ec.RemapToProxy)
-                                               ec.EmitThis ();
-                       
-                                       InstanceExpression.Emit (ec);
-                                       tempo.Store (ec);
-                                       ml = tempo;
-                               } else
-                                       ml = (IMemoryLocation) instance_expr;
-                               
-                               ml.AddressOf (ec, AddressOp.Load);
                        } else {
-                               if (ec.RemapToProxy)
-                                       ec.EmitThis ();
-                               else
-                                       instance_expr.Emit (ec);
+                               if (!prepared)
+                                       EmitInstance (ec);
+
+                               if (is_volatile)
+                                       ig.Emit (OpCodes.Volatile);
+
+                               ig.Emit (OpCodes.Ldfld, FieldInfo);
+                       }
+
+                       if (leave_copy) {
+                               ec.ig.Emit (OpCodes.Dup);
+                               if (!FieldInfo.IsStatic) {
+                                       temp = new LocalTemporary (ec, this.Type);
+                                       temp.Store (ec);
+                               }
                        }
-                       if (is_volatile)
-                               ig.Emit (OpCodes.Volatile);
-                       
-                       ig.Emit (OpCodes.Ldfld, FieldInfo);
                }
 
-               public void EmitAssign (EmitContext ec, Expression source)
+               public void EmitAssign (EmitContext ec, Expression source, bool leave_copy, bool prepare_for_load)
                {
                        FieldAttributes fa = FieldInfo.Attributes;
                        bool is_static = (fa & FieldAttributes.Static) != 0;
                        bool is_readonly = (fa & FieldAttributes.InitOnly) != 0;
                        ILGenerator ig = ec.ig;
+                       prepared = prepare_for_load;
 
                        if (is_readonly && !ec.IsConstructor){
                                Report_AssignToReadonly (!is_static);
                                return;
                        }
 
-                       if (!is_static){
-                               Expression instance = instance_expr;
-
-                               if (instance.Type.IsValueType){
-                                       IMemoryLocation ml = (IMemoryLocation) instance;
-
-                                       ml.AddressOf (ec, AddressOp.Store);
-                               } else {
-                                       if (ec.RemapToProxy)
-                                               ec.EmitThis ();
-                                       else
-                                               instance.Emit (ec);
-                               }
+                       if (!is_static) {
+                               EmitInstance (ec);
+                               if (prepare_for_load)
+                                       ig.Emit (OpCodes.Dup);
                        }
 
                        source.Emit (ec);
+                       if (leave_copy) {
+                               ec.ig.Emit (OpCodes.Dup);
+                               if (!FieldInfo.IsStatic) {
+                                       temp = new LocalTemporary (ec, this.Type);
+                                       temp.Store (ec);
+                               }
+                       }
 
                        if (FieldInfo is FieldBuilder){
                                FieldBase f = TypeManager.GetField (FieldInfo);
@@ -2800,6 +3061,29 @@ namespace Mono.CSharp {
                                ig.Emit (OpCodes.Stsfld, FieldInfo);
                        else 
                                ig.Emit (OpCodes.Stfld, FieldInfo);
+                       
+                       if (temp != null)
+                               temp.Emit (ec);
+               }
+
+               void EmitInstance (EmitContext ec)
+               {
+                       if (instance_expr.Type.IsValueType) {
+                               if (instance_expr is IMemoryLocation) {
+                                       ((IMemoryLocation) instance_expr).AddressOf (ec, AddressOp.LoadStore);
+                               } else {
+                                       LocalTemporary t = new LocalTemporary (ec, instance_expr.Type);
+                                       instance_expr.Emit (ec);
+                                       t.Store (ec);
+                                       t.AddressOf (ec, AddressOp.Store);
+                               }
+                       } else
+                               instance_expr.Emit (ec);
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       Emit (ec, false);
                }
                
                public void AddressOf (EmitContext ec, AddressOp mode)
@@ -2851,19 +3135,7 @@ namespace Mono.CSharp {
                        if (FieldInfo.IsStatic){
                                ig.Emit (OpCodes.Ldsflda, FieldInfo);
                        } else {
-                               //
-                               // In the case of `This', we call the AddressOf method, which will
-                               // only load the pointer, and not perform an Ldobj immediately after
-                               // the value has been loaded into the stack.
-                               //
-                               if (instance_expr is This)
-                                       ((This)instance_expr).AddressOf (ec, AddressOp.LoadStore);
-                               else if (instance_expr.Type.IsValueType && instance_expr is IMemoryLocation){
-                                       IMemoryLocation ml = (IMemoryLocation) instance_expr;
-
-                                       ml.AddressOf (ec, AddressOp.LoadStore);
-                               } else
-                                       instance_expr.Emit (ec);
+                               EmitInstance (ec);
                                ig.Emit (OpCodes.Ldflda, FieldInfo);
                        }
                }
@@ -2902,6 +3174,8 @@ namespace Mono.CSharp {
                bool must_do_cs1540_check;
                
                Expression instance_expr;
+               LocalTemporary temp;
+               bool prepared;
 
                public PropertyExpr (EmitContext ec, PropertyInfo pi, Location l)
                {
@@ -2964,75 +3238,104 @@ namespace Mono.CSharp {
                        return true;
                }
 
-               MethodInfo GetAccessor (Type invocation_type, string accessor_name)
+               MethodInfo FindAccessor (Type invocation_type, bool is_set)
                {
                        BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic |
-                               BindingFlags.Static | BindingFlags.Instance;
-                       MemberInfo[] group;
+                               BindingFlags.Static | BindingFlags.Instance |
+                               BindingFlags.DeclaredOnly;
 
-                       group = TypeManager.MemberLookup (
-                               invocation_type, invocation_type, PropertyInfo.DeclaringType,
-                               0, MemberTypes.Method, flags, accessor_name + "_" + PropertyInfo.Name);
+                       Type current = PropertyInfo.DeclaringType;
+                       for (; current != null; current = current.BaseType) {
+                               MemberInfo[] group = TypeManager.MemberLookup (
+                                       invocation_type, invocation_type, current,
+                                       MemberTypes.Property, flags, PropertyInfo.Name, null);
 
-                       //
-                       // The first method is the closest to us
-                       //
-                       if (group == null)
+                               if (group == null)
+                                       continue;
+
+                               if (group.Length != 1)
+                                       // Oooops, can this ever happen ?
+                                       return null;
+
+                               PropertyInfo pi = (PropertyInfo) group [0];
+
+                               MethodInfo get = pi.GetGetMethod (true);
+                               MethodInfo set = pi.GetSetMethod (true);
+
+                               if (is_set) {
+                                       if (set != null)
+                                               return set;
+                               } else {
+                                       if (get != null)
+                                               return get;
+                               }
+
+                               MethodInfo accessor = get != null ? get : set;
+                               if (accessor == null)
+                                       continue;
+                               if ((accessor.Attributes & MethodAttributes.NewSlot) != 0)
+                                       break;
+                       }
+
+                       return null;
+               }
+
+               MethodInfo GetAccessor (Type invocation_type, bool is_set)
+               {
+                       MethodInfo mi = FindAccessor (invocation_type, is_set);
+                       if (mi == null)
                                return null;
 
-                       foreach (MethodInfo mi in group) {
-                               MethodAttributes ma = mi.Attributes & MethodAttributes.MemberAccessMask;
+                       MethodAttributes ma = mi.Attributes & MethodAttributes.MemberAccessMask;
 
-                               //
-                               // If only accessible to the current class or children
-                               //
-                               if (ma == MethodAttributes.Private) {
-                                       Type declaring_type = mi.DeclaringType;
+                       //
+                       // If only accessible to the current class or children
+                       //
+                       if (ma == MethodAttributes.Private) {
+                               Type declaring_type = mi.DeclaringType;
                                        
-                                       if (invocation_type != declaring_type){
-                                               if (TypeManager.IsSubclassOrNestedChildOf (invocation_type, mi.DeclaringType))
-                                                       return mi;
-                                               else
-                                                       continue;
-                                       } else
+                               if (invocation_type != declaring_type){
+                                       if (TypeManager.IsSubclassOrNestedChildOf (invocation_type, mi.DeclaringType))
                                                return mi;
-                               }
-                               //
-                               // FamAndAssem requires that we not only derivate, but we are on the
-                               // same assembly.  
-                               //
-                               if (ma == MethodAttributes.FamANDAssem){
-                                       if (mi.DeclaringType.Assembly != invocation_type.Assembly)
-                                               continue;
                                        else
-                                               return mi;
-                               }
+                                               return null;
+                               } else
+                                       return mi;
+                       }
+                       //
+                       // FamAndAssem requires that we not only derivate, but we are on the
+                       // same assembly.  
+                       //
+                       if (ma == MethodAttributes.FamANDAssem){
+                               if (mi.DeclaringType.Assembly != invocation_type.Assembly)
+                                       return null;
+                               else
+                                       return mi;
+                       }
 
-                               // Assembly and FamORAssem succeed if we're in the same assembly.
-                               if ((ma == MethodAttributes.Assembly) || (ma == MethodAttributes.FamORAssem)){
-                                       if (mi.DeclaringType.Assembly == invocation_type.Assembly)
-                                               return mi;
-                               }
+                       // Assembly and FamORAssem succeed if we're in the same assembly.
+                       if ((ma == MethodAttributes.Assembly) || (ma == MethodAttributes.FamORAssem)){
+                               if (mi.DeclaringType.Assembly == invocation_type.Assembly)
+                                       return mi;
+                       }
 
-                               // We already know that we aren't in the same assembly.
-                               if (ma == MethodAttributes.Assembly)
-                                       continue;
+                       // We already know that we aren't in the same assembly.
+                       if (ma == MethodAttributes.Assembly)
+                               return null;
 
-                               // Family and FamANDAssem require that we derive.
-                               if ((ma == MethodAttributes.Family) || (ma == MethodAttributes.FamANDAssem) || (ma == MethodAttributes.FamORAssem)){
-                                       if (!TypeManager.IsSubclassOrNestedChildOf (invocation_type, mi.DeclaringType))
-                                               continue;
-                                       else {
+                       // Family and FamANDAssem require that we derive.
+                       if ((ma == MethodAttributes.Family) || (ma == MethodAttributes.FamANDAssem) || (ma == MethodAttributes.FamORAssem)){
+                               if (!TypeManager.IsSubclassOrNestedChildOf (invocation_type, mi.DeclaringType))
+                                       return null;
+                               else {
+                                       if (!TypeManager.IsNestedChildOf (invocation_type, mi.DeclaringType))
                                                must_do_cs1540_check = true;
 
-                                               return mi;
-                                       }
+                                       return mi;
                                }
-
-                               return mi;
                        }
 
-                       return null;
+                       return mi;
                }
 
                //
@@ -3041,18 +3344,16 @@ namespace Mono.CSharp {
                //
                void ResolveAccessors (EmitContext ec)
                {
-                       getter = GetAccessor (ec.ContainerType, "get");
+                       getter = GetAccessor (ec.ContainerType, false);
                        if ((getter != null) && getter.IsStatic)
                                is_static = true;
 
-                       setter = GetAccessor (ec.ContainerType, "set");
+                       setter = GetAccessor (ec.ContainerType, true);
                        if ((setter != null) && setter.IsStatic)
                                is_static = true;
 
                        if (setter == null && getter == null){
-                               Error (122, "`" + PropertyInfo.Name + "' " +
-                                      "is inaccessible because of its protection level");
-                               
+                               Report.Error_T (122, loc, PropertyInfo.Name);
                        }
                }
 
@@ -3088,6 +3389,16 @@ namespace Mono.CSharp {
                
                override public Expression DoResolve (EmitContext ec)
                {
+                       if (getter != null){
+                               if (TypeManager.GetArgumentTypes (getter).Length != 0){
+                                       Report.Error (
+                                               117, loc, "`{0}' does not contain a " +
+                                               "definition for `{1}'.", getter.DeclaringType,
+                                               Name);
+                                       return null;
+                               }
+                       }
+
                        if (getter == null){
                                //
                                // The following condition happens if the PropertyExpr was
@@ -3139,6 +3450,14 @@ namespace Mono.CSharp {
                                return null;
                        }
 
+                       if (TypeManager.GetArgumentTypes (setter).Length != 1){
+                               Report.Error (
+                                       117, loc, "`{0}' does not contain a " +
+                                       "definition for `{1}'.", getter.DeclaringType,
+                                       Name);
+                               return null;
+                       }
+
                        if (!InstanceResolve (ec))
                                return null;
                        
@@ -3150,11 +3469,53 @@ namespace Mono.CSharp {
                                              PropertyInfo.DeclaringType + "." +PropertyInfo.Name);
                                return null;
                        }
+
+                       //
+                       // Check that we are not making changes to a temporary memory location
+                       //
+                       if (instance_expr != null && instance_expr.Type.IsValueType && !(instance_expr is IMemoryLocation)) {
+                               // FIXME: Provide better error reporting.
+                               Error (1612, "Cannot modify expression because it is not a variable.");
+                               return null;
+                       }
+
                        return this;
                }
 
-               override public void Emit (EmitContext ec)
+
+               
+               public override void Emit (EmitContext ec)
+               {
+                       Emit (ec, false);
+               }
+               
+               void EmitInstance (EmitContext ec)
+               {
+                       if (is_static)
+                               return;
+
+                       if (instance_expr.Type.IsValueType) {
+                               if (instance_expr is IMemoryLocation) {
+                                       ((IMemoryLocation) instance_expr).AddressOf (ec, AddressOp.LoadStore);
+                               } else {
+                                       LocalTemporary t = new LocalTemporary (ec, instance_expr.Type);
+                                       instance_expr.Emit (ec);
+                                       t.Store (ec);
+                                       t.AddressOf (ec, AddressOp.Store);
+                               }
+                       } else
+                               instance_expr.Emit (ec);
+                       
+                       if (prepared)
+                               ec.ig.Emit (OpCodes.Dup);
+               }
+
+               
+               public void Emit (EmitContext ec, bool leave_copy)
                {
+                       if (!prepared)
+                               EmitInstance (ec);
+                       
                        //
                        // Special case: length of single dimension array property is turned into ldlen
                        //
@@ -3166,28 +3527,50 @@ namespace Mono.CSharp {
                                // System.Array.Length can be called, but the Type does not
                                // support invoking GetArrayRank, so test for that case first
                                //
-                               if (iet != TypeManager.array_type && (iet.GetArrayRank () == 1)){
-                                       instance_expr.Emit (ec);
+                               if (iet != TypeManager.array_type && (iet.GetArrayRank () == 1)) {
                                        ec.ig.Emit (OpCodes.Ldlen);
                                        ec.ig.Emit (OpCodes.Conv_I4);
                                        return;
                                }
                        }
 
-                       Invocation.EmitCall (ec, IsBase, IsStatic, instance_expr, getter, null, loc);
+                       Invocation.EmitCall (ec, IsBase, IsStatic, new EmptyAddressOf (), getter, null, loc);
                        
+                       if (!leave_copy)
+                               return;
+                       
+                       ec.ig.Emit (OpCodes.Dup);
+                       if (!is_static) {
+                               temp = new LocalTemporary (ec, this.Type);
+                               temp.Store (ec);
+                       }
                }
 
                //
                // Implements the IAssignMethod interface for assignments
                //
-               public void EmitAssign (EmitContext ec, Expression source)
+               public void EmitAssign (EmitContext ec, Expression source, bool leave_copy, bool prepare_for_load)
                {
-                       Argument arg = new Argument (source, Argument.AType.Expression);
-                       ArrayList args = new ArrayList ();
+                       prepared = prepare_for_load;
+                       
+                       EmitInstance (ec);
 
-                       args.Add (arg);
-                       Invocation.EmitCall (ec, IsBase, IsStatic, instance_expr, setter, args, loc);
+                       source.Emit (ec);
+                       if (leave_copy) {
+                               ec.ig.Emit (OpCodes.Dup);
+                               if (!is_static) {
+                                       temp = new LocalTemporary (ec, this.Type);
+                                       temp.Store (ec);
+                               }
+                       }
+                       
+                       ArrayList args = new ArrayList (1);
+                       args.Add (new Argument (new EmptyAddressOf (), Argument.AType.Expression));
+                       
+                       Invocation.EmitCall (ec, IsBase, IsStatic, new EmptyAddressOf (), setter, args, loc);
+                       
+                       if (temp != null)
+                               temp.Emit (ec);
                }
 
                override public void EmitStatement (EmitContext ec)
@@ -3202,7 +3585,7 @@ namespace Mono.CSharp {
        /// </summary>
        public class EventExpr : Expression, IMemberExpr {
                public readonly EventInfo EventInfo;
-               public Expression instance_expr;
+               Expression instance_expr;
 
                bool is_static;
                MethodInfo add_accessor, remove_accessor;