Fix #65833, test-300.cs, cs0122-5.cs, cs0122-6.cs.
authorRaja R Harinath <harinath@hurrynot.org>
Fri, 1 Oct 2004 05:16:01 +0000 (05:16 -0000)
committerRaja R Harinath <harinath@hurrynot.org>
Fri, 1 Oct 2004 05:16:01 +0000 (05:16 -0000)
* class.c (TypeContainer.DefineType): Flag error if
base types aren't accessible due to access permissions.
* decl.cs (DeclSpace.ResolveType): Move logic to
Expression.ResolveAsTypeTerminal.
(DeclSpace.ResolveTypeExpr): Thin layer over
Expression.ResolveAsTypeTerminal.
(DeclSpace.CheckAccessLevel, DeclSpace.FamilyAccess):
Refactor code into NestedAccess.  Use it.
(DeclSpace.NestedAccess): New.
* ecore.cs (Expression.ResolveAsTypeTerminal): Add new
argument to silence errors.  Check access permissions.
(TypeExpr.DoResolve, TypeExpr.ResolveType): Update.
* expression.cs (ProbeExpr.DoResolve): Use ResolveAsTypeTerminal.
(Cast.DoResolve): Likewise.
(New.DoResolve): Likewise.
(InvocationOrCast.DoResolve,ResolveStatement): Likewise.
(TypeOf.DoResolve): Likewise.

* expression.cs (Invocation.BetterConversion): Return the Type of
the better conversion.  Implement section 14.4.2.3 more faithfully.
(Invocation.BetterFunction): Make boolean.  Make correspondence to
section 14.4.2.2 explicit.
(Invocation.OverloadResolve): Update.
(Invocation): Remove is_base field.
(Invocation.DoResolve): Don't use is_base.  Use mg.IsBase.
(Invocation.Emit): Likewise.

svn path=/trunk/mcs/; revision=34585

mcs/mcs/ChangeLog
mcs/mcs/class.cs
mcs/mcs/decl.cs
mcs/mcs/ecore.cs
mcs/mcs/expression.cs

index e1435a5c94872e50f5f006b2a0c2c5b2d431483f..78f8ba2324e1553b2dd88b970bd298b4114073fe 100755 (executable)
@@ -1,3 +1,33 @@
+2004-10-01  Raja R Harinath  <rharinath@novell.com>
+
+       Fix #65833, test-300.cs, cs0122-5.cs, cs0122-6.cs.
+       * class.c (TypeContainer.DefineType): Flag error if
+       base types aren't accessible due to access permissions.
+       * decl.cs (DeclSpace.ResolveType): Move logic to
+       Expression.ResolveAsTypeTerminal.
+       (DeclSpace.ResolveTypeExpr): Thin layer over
+       Expression.ResolveAsTypeTerminal.
+       (DeclSpace.CheckAccessLevel, DeclSpace.FamilyAccess):
+       Refactor code into NestedAccess.  Use it.
+       (DeclSpace.NestedAccess): New.
+       * ecore.cs (Expression.ResolveAsTypeTerminal): Add new
+       argument to silence errors.  Check access permissions.
+       (TypeExpr.DoResolve, TypeExpr.ResolveType): Update.
+       * expression.cs (ProbeExpr.DoResolve): Use ResolveAsTypeTerminal.
+       (Cast.DoResolve): Likewise.
+       (New.DoResolve): Likewise.
+       (InvocationOrCast.DoResolve,ResolveStatement): Likewise.
+       (TypeOf.DoResolve): Likewise.
+
+       * expression.cs (Invocation.BetterConversion): Return the Type of
+       the better conversion.  Implement section 14.4.2.3 more faithfully.
+       (Invocation.BetterFunction): Make boolean.  Make correspondence to
+       section 14.4.2.2 explicit.
+       (Invocation.OverloadResolve): Update.
+       (Invocation): Remove is_base field.
+       (Invocation.DoResolve): Don't use is_base.  Use mg.IsBase.
+       (Invocation.Emit): Likewise.
+
 2004-09-27  Raja R Harinath  <rharinath@novell.com>
 
        * README: Update to changes.
index 26fc785ca140852df61b90f4a55698b286699fe3..ed4bd84fa9b5d151efb462d7b375f9087c091a0b 100755 (executable)
@@ -1125,7 +1125,7 @@ namespace Mono.CSharp {
 
                        if (error)
                                return null;
-                       
+
                        if (InTransit) {
                                Report.Error (146, Location, "Class definition is circular: `{0}'", Name);
                                error = true;
@@ -1164,8 +1164,13 @@ namespace Mono.CSharp {
 
                        TypeAttributes type_attributes = TypeAttr;
 
-                       if (parent != null)
+                       if (parent != null) {
                                base_class_type = parent.ResolveType (ec);
+                               if (base_class_type == null) {
+                                       error = true;
+                                       return null;
+                               }
+                       }
 
                        try {
                                if (IsTopLevel){
@@ -1209,9 +1214,16 @@ namespace Mono.CSharp {
                                base_inteface_types = new Type[ifaces.Length];
                                for (int i = 0; i < ifaces.Length; ++i) {
                                        Type itype = ifaces [i].ResolveType (ec);
+                                       if (itype == null) {
+                                               error = true;
+                                               continue;
+                                       }
                                        TypeBuilder.AddInterfaceImplementation (itype);
                                        base_inteface_types [i] = itype;
                                }
+
+                               if (error)
+                                       return null;
                        }
 
                        //
index cf92cab163c8c43f4dfecb0b4d205ac301add8b1..39b706fb25b6f06e147ee5484e332ae30bb7e3e6 100755 (executable)
@@ -544,27 +544,8 @@ namespace Mono.CSharp {
                // </summary>
                public Type ResolveType (Expression e, bool silent, Location loc)
                {
-                       if (type_resolve_ec == null)
-                               type_resolve_ec = GetTypeResolveEmitContext (Parent, loc);
-                       type_resolve_ec.loc = loc;
-                       type_resolve_ec.ContainerType = TypeBuilder;
-
-                       int errors = Report.Errors;
-                       TypeExpr d = e.ResolveAsTypeTerminal (type_resolve_ec);
-                       
-                       if (d == null || d.eclass != ExprClass.Type){
-                               if (!silent && errors == Report.Errors){
-                                       Report.Error (246, loc, "Cannot find type `"+ e.ToString () +"'");
-                               }
-                               return null;
-                       }
-
-                       if (!d.CheckAccessLevel (this)) {
-                               Report.Error (122, loc, "'{0}' is inaccessible due to its protection level", d.Name);
-                               return null;
-                       }
-
-                       return d.Type;
+                       TypeExpr d = ResolveTypeExpr (e, silent, loc);
+                       return d == null ? null : d.Type;
                }
 
                // <summary>
@@ -578,25 +559,16 @@ namespace Mono.CSharp {
                        type_resolve_ec.loc = loc;
                        type_resolve_ec.ContainerType = TypeBuilder;
 
-                       TypeExpr d = e.ResolveAsTypeTerminal (type_resolve_ec);
-                        
-                       if (d == null || d.eclass != ExprClass.Type){
-                               if (!silent){
-                                       Report.Error (246, loc, "Cannot find type `"+ e +"'");
-                               }
-                               return null;
-                       }
-
-                       return d;
+                       return e.ResolveAsTypeTerminal (type_resolve_ec, silent);
                }
                
-               public bool CheckAccessLevel (Type check_type) 
+               public bool CheckAccessLevel (Type check_type)
                {
                        if (check_type == TypeBuilder)
                                return true;
                        
                        TypeAttributes check_attr = check_type.Attributes & TypeAttributes.VisibilityMask;
-                       
+
                        //
                        // Broken Microsoft runtime, return public for arrays, no matter what 
                        // the accessibility is for their underlying class, and they return 
@@ -605,16 +577,17 @@ namespace Mono.CSharp {
                        if (check_type.IsArray || check_type.IsPointer)
                                return CheckAccessLevel (TypeManager.GetElementType (check_type));
 
+                       if (TypeBuilder == null)
+                               // FIXME: TypeBuilder will be null when invoked by Class.GetNormalBases().
+                               //        However, this is invoked again later -- so safe to return true.
+                               //        May also be null when resolving top-level attributes.
+                               return true;
+
                        switch (check_attr){
                        case TypeAttributes.Public:
                                return true;
 
                        case TypeAttributes.NotPublic:
-
-                               // In same cases is null.
-                               if (TypeBuilder == null)
-                                       return true;
-
                                //
                                // This test should probably use the declaringtype.
                                //
@@ -624,29 +597,9 @@ namespace Mono.CSharp {
                                return true;
 
                        case TypeAttributes.NestedPrivate:
-                               string check_type_name = check_type.FullName;
-                               string type_name = TypeBuilder.FullName;
-                               
-                               int cio = check_type_name.LastIndexOf ('+');
-                               string container = check_type_name.Substring (0, cio);
-
-                               //
-                               // Check if the check_type is a nested class of the current type
-                               //
-                               if (check_type_name.StartsWith (type_name + "+")){
-                                       return true;
-                               }
-                               
-                               if (type_name.StartsWith (container)){
-                                       return true;
-                               }
-
-                               return false;
+                               return NestedAccessible (check_type);
 
                        case TypeAttributes.NestedFamily:
-                               //
-                               // Only accessible to methods in current type or any subtypes
-                               //
                                return FamilyAccessible (check_type);
 
                        case TypeAttributes.NestedFamANDAssem:
@@ -666,24 +619,32 @@ namespace Mono.CSharp {
 
                }
 
-               protected bool FamilyAccessible (Type check_type)
+               protected bool NestedAccessible (Type check_type)
                {
-                       Type declaring = check_type.DeclaringType;
-                       if (TypeBuilder.IsSubclassOf (declaring))
-                               return true;
-
                        string check_type_name = check_type.FullName;
-                       
+
+                       // At this point, we already know check_type is a nested class.
                        int cio = check_type_name.LastIndexOf ('+');
-                       string container = check_type_name.Substring (0, cio);
-                       
-                       //
-                       // Check if the check_type is a nested class of the current type
-                       //
-                       if (check_type_name.StartsWith (container + "+"))
+
+                       // Ensure that the string 'container' has a '+' in it to avoid false matches
+                       string container = check_type_name.Substring (0, cio + 1);
+
+                       // Ensure that type_name ends with a '+' so that it can match 'container', if necessary
+                       string type_name = TypeBuilder.FullName + "+";
+
+                       // If the current class is nested inside the container of check_type,
+                       // we can access check_type even if it is private or protected.
+                       return type_name.StartsWith (container);
+               }
+
+               protected bool FamilyAccessible (Type check_type)
+               {
+                       Type declaring = check_type.DeclaringType;
+                       if (TypeBuilder == declaring ||
+                           TypeBuilder.IsSubclassOf (declaring))
                                return true;
 
-                       return false;
+                       return NestedAccessible (check_type);
                }
 
                // Access level of a type.
index 3434f1ec045dddc19061abf1ccbd518bff9e3fc6..4bca8acf574c86f6f8aa55a71151d0eac12dd296 100755 (executable)
@@ -253,9 +253,24 @@ namespace Mono.CSharp {
                // value will be returned if the expression is not a type
                // reference
                //
-               public TypeExpr ResolveAsTypeTerminal (EmitContext ec)
+               public TypeExpr ResolveAsTypeTerminal (EmitContext ec, bool silent)
                {
-                       return ResolveAsTypeStep (ec) as TypeExpr;
+                       int errors = Report.Errors;
+
+                       TypeExpr te = ResolveAsTypeStep (ec) as TypeExpr;
+
+                       if (te == null || te.eclass != ExprClass.Type) {
+                               if (!silent && errors == Report.Errors)
+                                       Report.Error (246, Location, "Cannot find type '{0}'", ToString ());
+                               return null;
+                       }
+
+                       if (!te.CheckAccessLevel (ec.DeclSpace)) {
+                               Report.Error (122, Location, "'{0}' is inaccessible due to its protection level", te.Name);
+                               return null;
+                       }
+
+                       return te;
                }
               
                /// <summary>
@@ -2239,7 +2254,7 @@ namespace Mono.CSharp {
 
                override public Expression DoResolve (EmitContext ec)
                {
-                       return ResolveAsTypeTerminal (ec);
+                       return ResolveAsTypeTerminal (ec, true);
                }
 
                override public void Emit (EmitContext ec)
@@ -2301,7 +2316,7 @@ namespace Mono.CSharp {
 
                public virtual Type ResolveType (EmitContext ec)
                {
-                       TypeExpr t = ResolveAsTypeTerminal (ec);
+                       TypeExpr t = ResolveAsTypeTerminal (ec, false);
                        if (t == null)
                                return null;
 
index 76bc40692021232015160e9a0aeebf3e42ffe5b4..bb76e3a552f4b9d959f0da66acc4d7dd25b4dd40 100755 (executable)
@@ -1012,7 +1012,7 @@ namespace Mono.CSharp {
        ///   size. 
        /// </remarks>
        public abstract class Probe : Expression {
-               public readonly Expression ProbeType;
+               public Expression ProbeType;
                protected Expression expr;
                protected Type probe_type;
                
@@ -1031,10 +1031,10 @@ namespace Mono.CSharp {
 
                public override Expression DoResolve (EmitContext ec)
                {
-                       probe_type = ec.DeclSpace.ResolveType (ProbeType, false, loc);
-
-                       if (probe_type == null)
+                       ProbeType = ProbeType.ResolveAsTypeTerminal (ec, false);
+                       if (ProbeType == null)
                                return null;
+                       probe_type = ProbeType.Type;
 
                        CheckObsoleteAttribute (probe_type);
 
@@ -1768,11 +1768,12 @@ namespace Mono.CSharp {
                        if (expr == null)
                                return null;
 
-                       type = ec.DeclSpace.ResolveType (target_type, false, Location);
-                       
-                       if (type == null)
+                       TypeExpr target = target_type.ResolveAsTypeTerminal (ec, false);
+                       if (target == null)
                                return null;
 
+                       type = target.Type;
+
                        CheckObsoleteAttribute (type);
 
                        if (type.IsAbstract && type.IsSealed) {
@@ -4096,7 +4097,6 @@ namespace Mono.CSharp {
 
                Expression expr;
                MethodBase method = null;
-               bool is_base;
                
                static Hashtable method_parameter_cache;
 
@@ -4154,10 +4154,11 @@ namespace Mono.CSharp {
                /// <summary>
                ///   Determines "better conversion" as specified in 7.4.2.3
                ///
-                ///    Returns : 1 if a->p is better
-               ///              0 if a->q or neither is better 
+                ///    Returns : p    if a->p is better,
+               ///              q    if a->q is better,
+               ///              null if neither is better
                /// </summary>
-               static int BetterConversion (EmitContext ec, Argument a, Type p, Type q, Location loc)
+               static Type BetterConversion (EmitContext ec, Argument a, Type p, Type q, Location loc)
                {
                        Type argument_type = a.Type;
                        Expression argument_expr = a.Expr;
@@ -4169,71 +4170,82 @@ namespace Mono.CSharp {
                        if (p == null || q == null)
                                throw new InternalErrorException ("BetterConversion Got a null conversion");
 
-                       //
-                       // This is a special case since csc behaves this way.
-                       //
-                       if (argument_expr is NullLiteral &&
-                            p == TypeManager.string_type &&
-                            q == TypeManager.object_type)
-                               return 1;
-                       else if (argument_expr is NullLiteral &&
-                                 p == TypeManager.object_type &&
-                                 q == TypeManager.string_type)
-                               return 0;
-                       
-                        //
-                        // csc behaves this way so we emulate it. Basically, if the argument
-                        // is null and one of the types to compare is 'object' and the other
-                        // is a reference type, we prefer the other.
-                        //
-                        // I can't find this anywhere in the spec but we can interpret this
-                        // to mean that null can be of any type you wish in such a context
-                        //
-                       if (argument_expr is NullLiteral &&
-                           !p.IsValueType &&
-                           q == TypeManager.object_type)
-                               return 1;
-                       else if (argument_expr is NullLiteral &&
-                                !q.IsValueType &&
-                                p == TypeManager.object_type)
-                               return 0;
+                       if (p == q)
+                               return null;
 
+                       if (argument_expr is NullLiteral) {
+                               //
+                               // If the argument is null and one of the types to compare is 'object' and
+                               // the other is a reference type, we prefer the other.
+                               //
+                               // This follows from the usual rules:
+                               //   * There is an implicit conversion from 'null' to type 'object'
+                               //   * There is an implicit conversion from 'null' to any reference type
+                               //   * There is an implicit conversion from any reference type to type 'object'
+                               //   * There is no implicit conversion from type 'object' to other reference types
+                               //  => Conversion of 'null' to a reference type is better than conversion to 'object'
+                               //
+                               //  FIXME: This probably isn't necessary, since the type of a NullLiteral is 'System.Null'.
+                               //         I think it used to be 'object' and thus needed a special case to avoid the
+                               //         immediately following two checks.
+                               //
+                               if (!p.IsValueType && q == TypeManager.object_type)
+                                       return p;
+                               if (!q.IsValueType && p == TypeManager.object_type)
+                                       return q;
+                       }
                                 
-                       if (p == q)
-                               return 0;
-                       
                        if (argument_type == p)
-                               return 1;
+                               return p;
 
                        if (argument_type == q)
-                               return 0;
+                               return q;
 
                        Expression p_tmp = new EmptyExpression (p);
                        Expression q_tmp = new EmptyExpression (q);
-                       
-                       if (Convert.ImplicitConversionExists (ec, p_tmp, q) == true &&
-                           Convert.ImplicitConversionExists (ec, q_tmp, p) == false)
-                               return 1;
+
+                       bool p_to_q = Convert.ImplicitConversionExists (ec, p_tmp, q);
+                       bool q_to_p = Convert.ImplicitConversionExists (ec, q_tmp, p);
+
+                       if (p_to_q && !q_to_p)
+                               return p;
+
+                       if (q_to_p && !p_to_q)
+                               return q;
 
                        if (p == TypeManager.sbyte_type)
                                if (q == TypeManager.byte_type || q == TypeManager.ushort_type ||
                                    q == TypeManager.uint32_type || q == TypeManager.uint64_type)
-                                       return 1;
+                                       return p;
+                       if (q == TypeManager.sbyte_type)
+                               if (p == TypeManager.byte_type || p == TypeManager.ushort_type ||
+                                   p == TypeManager.uint32_type || p == TypeManager.uint64_type)
+                                       return q;
 
                        if (p == TypeManager.short_type)
                                if (q == TypeManager.ushort_type || q == TypeManager.uint32_type ||
                                    q == TypeManager.uint64_type)
-                                       return 1;
+                                       return p;
+                       if (q == TypeManager.short_type)
+                               if (p == TypeManager.ushort_type || p == TypeManager.uint32_type ||
+                                   p == TypeManager.uint64_type)
+                                       return q;
 
                        if (p == TypeManager.int32_type)
                                if (q == TypeManager.uint32_type || q == TypeManager.uint64_type)
-                                       return 1;
+                                       return p;
+                       if (q == TypeManager.int32_type)
+                               if (p == TypeManager.uint32_type || p == TypeManager.uint64_type)
+                                       return q;
 
                        if (p == TypeManager.int64_type)
                                if (q == TypeManager.uint64_type)
-                                       return 1;
+                                       return p;
+                       if (q == TypeManager.int64_type)
+                               if (p == TypeManager.uint64_type)
+                                       return q;
 
-                       return 0;
+                       return null;
                }
                
                /// <summary>
@@ -4242,12 +4254,12 @@ namespace Mono.CSharp {
                /// </summary>
                /// <remarks>
                ///    Returns an integer indicating :
-               ///     0 if candidate ain't better
-               ///     1 if candidate is better than the current best match
+               ///     false if candidate ain't better
+               ///     true if candidate is better than the current best match
                /// </remarks>
-               static int BetterFunction (EmitContext ec, ArrayList args, int argument_count,
-                                          MethodBase candidate, bool candidate_params,
-                                          MethodBase best, bool best_params, Location loc)
+               static bool BetterFunction (EmitContext ec, ArrayList args, int argument_count,
+                                           MethodBase candidate, bool candidate_params,
+                                           MethodBase best, bool best_params, Location loc)
                {
                        ParameterData candidate_pd = GetParameterData (candidate);
                        ParameterData best_pd = GetParameterData (best);
@@ -4276,19 +4288,15 @@ namespace Mono.CSharp {
                        // Trim (); is better than Trim (params char[] chars);
                         //
                        if (cand_count == 0 && argument_count == 0)
-                               return best_params ? 1 : 0;
+                               return !candidate_params && best_params;
 
                        if ((candidate_pd.ParameterModifier (cand_count - 1) != Parameter.Modifier.PARAMS) &&
                            (candidate_pd.ParameterModifier (cand_count - 1) != Parameter.Modifier.ARGLIST))
                                if (cand_count != argument_count)
-                                       return 0;
-
+                                       return false;
 
-                       int rating1 = 0, rating2 = 0;
-                       
+                       bool better_at_least_one = false;
                        for (int j = 0; j < argument_count; ++j) {
-                               int x, y;
-                               
                                Argument a = (Argument) args [j];
 
                                Type ct = candidate_pd.ParameterType (j);
@@ -4302,14 +4310,17 @@ namespace Mono.CSharp {
                                        if (best_params)
                                                bt = TypeManager.GetElementType (bt);
 
-                               x = BetterConversion (ec, a, ct, bt, loc);
-                               y = BetterConversion (ec, a, bt, ct, loc);
+                               Type better = BetterConversion (ec, a, ct, bt, loc);
 
-                               if (x < y)
-                                       return 0;
-                               
-                               rating1 += x;
-                               rating2 += y;
+                               // for each argument, the conversion to 'ct' should be no worse than 
+                               // the conversion to 'bt'.
+                               if (better == bt)
+                                       return false;
+
+                               // for at least one argument, the conversion to 'ct' should be better than 
+                               // the conversion to 'bt'.
+                               if (better == ct)
+                                       better_at_least_one = true;
                        }
 
                         //
@@ -4320,12 +4331,9 @@ namespace Mono.CSharp {
                         // force it to select the candidate
                         //
                         if (!candidate_params && best_params && cand_count == argument_count)
-                                return 1;
+                                return true;
 
-                       if (rating1 > rating2)
-                               return 1;
-                       else
-                               return 0;
+                       return better_at_least_one;
                }
 
                public static string FullMethodDesc (MethodBase mb)
@@ -4592,7 +4600,7 @@ namespace Mono.CSharp {
                ///
                /// </summary>
                public static MethodBase OverloadResolve (EmitContext ec, MethodGroupExpr me,
-                                                         ArrayList Arguments, bool may_fail,
+                                                         ArrayList Arguments, bool may_fail, 
                                                          Location loc)
                {
                        MethodBase method = null;
@@ -4762,7 +4770,7 @@ namespace Mono.CSharp {
                                 
                                if (BetterFunction (ec, Arguments, arg_count, 
                                                    candidate, cand_params,
-                                                   method, method_params, loc) != 0) {
+                                                   method, method_params, loc)) {
                                        method = candidate;
                                        method_params = cand_params;
                                }
@@ -4780,10 +4788,10 @@ namespace Mono.CSharp {
                                         continue;
 
                                 bool cand_params = candidate_to_form != null && candidate_to_form.Contains (candidate);
-                               if (BetterFunction (ec, Arguments, arg_count,
-                                                   method, method_params,
-                                                   candidate, cand_params,
-                                                   loc) != 1) {
+                               if (!BetterFunction (ec, Arguments, arg_count,
+                                                    method, method_params,
+                                                    candidate, cand_params,
+                                                    loc)) {
                                        Report.SymbolRelatedToPreviousError (candidate);
                                        ambiguous = true;
                                }
@@ -4791,7 +4799,7 @@ namespace Mono.CSharp {
 
                        if (ambiguous) {
                                Report.SymbolRelatedToPreviousError (method);
-                               Report.Error (121, loc, "Ambiguous call when selecting function due to implicit casts");                                        
+                               Report.Error (121, loc, "Ambiguous call when selecting function due to implicit casts");
                                return null;
                        }
 
@@ -4933,9 +4941,6 @@ namespace Mono.CSharp {
                        // First, resolve the expression that is used to
                        // trigger the invocation
                        //
-                       if (expr is BaseAccess)
-                               is_base = true;
-
                        expr = expr.Resolve (ec, ResolveFlags.VariableOrValue | ResolveFlags.MethodGroup);
                        if (expr == null)
                                return null;
@@ -4971,7 +4976,7 @@ namespace Mono.CSharp {
 
                        if (method == null)
                                return null;
-                       
+
                        MethodInfo mi = method as MethodInfo;
                        if (mi != null) {
                                type = TypeManager.TypeToCoreType (mi.ReturnType);
@@ -5001,14 +5006,14 @@ namespace Mono.CSharp {
                        //
                        // Only base will allow this invocation to happen.
                        //
-                       if (is_base && method.IsAbstract){
+                       if (mg.IsBase && method.IsAbstract){
                                Report.Error (205, loc, "Cannot call an abstract base member: " +
                                              FullMethodDesc (method));
                                return null;
                        }
 
                        if (method.Name == "Finalize" && Arguments == null) {
-                               if (is_base)
+                               if (mg.IsBase)
                                        Report.Error (250, loc, "Do not directly call your base class Finalize method. It is called automatically from your destructor");
                                else
                                        Report.Error (245, loc, "Destructors and object.Finalize cannot be called directly. Consider calling IDisposable.Dispose if available");
@@ -5349,7 +5354,7 @@ namespace Mono.CSharp {
                {
                        MethodGroupExpr mg = (MethodGroupExpr) this.expr;
 
-                       EmitCall (ec, is_base, method.IsStatic, mg.InstanceExpression, method, Arguments, loc);
+                       EmitCall (ec, mg.IsBase, method.IsStatic, mg.InstanceExpression, method, Arguments, loc);
                }
                
                public override void EmitStatement (EmitContext ec)
@@ -5384,9 +5389,9 @@ namespace Mono.CSharp {
                        //
                        // First try to resolve it as a cast.
                        //
-                       type = ec.DeclSpace.ResolveType (expr, true, loc);
-                       if (type != null) {
-                               Cast cast = new Cast (new TypeExpression (type, loc), argument, loc);
+                       TypeExpr te = expr.ResolveAsTypeTerminal (ec, true);
+                       if (te != null) {
+                               Cast cast = new Cast (te, argument, loc);
                                return cast.Resolve (ec);
                        }
 
@@ -5431,8 +5436,8 @@ namespace Mono.CSharp {
                        //
                        // First try to resolve it as a cast.
                        //
-                       type = ec.DeclSpace.ResolveType (expr, true, loc);
-                       if (type != null) {
+                       TypeExpr te = expr.ResolveAsTypeTerminal (ec, true);
+                       if (te != null) {
                                error201 ();
                                return null;
                        }
@@ -5566,10 +5571,11 @@ namespace Mono.CSharp {
                                return this;
                        }
                        
-                       type = ec.DeclSpace.ResolveType (RequestedType, false, loc);
-                       
-                       if (type == null)
+                       RequestedType = RequestedType.ResolveAsTypeTerminal (ec, false);
+                       if (RequestedType == null)
                                return null;
+
+                       type = RequestedType.Type;
                        
                        CheckObsoleteAttribute (type);
 
@@ -6756,7 +6762,7 @@ namespace Mono.CSharp {
        ///   Implements the typeof operator
        /// </summary>
        public class TypeOf : Expression {
-               public readonly Expression QueriedType;
+               public Expression QueriedType;
                protected Type typearg;
                
                public TypeOf (Expression queried_type, Location l)
@@ -6767,11 +6773,12 @@ namespace Mono.CSharp {
 
                public override Expression DoResolve (EmitContext ec)
                {
-                       typearg = ec.DeclSpace.ResolveType (QueriedType, false, loc);
-
-                       if (typearg == null)
+                       QueriedType = QueriedType.ResolveAsTypeTerminal (ec, false);
+                       if (QueriedType == null)
                                return null;
 
+                       typearg = QueriedType.Type;
+
                        if (typearg == TypeManager.void_type) {
                                Error (673, "System.Void cannot be used from C# - " +
                                       "use typeof (void) to get the void type object");