Rework gc descriptor to include size information in more cases.
[mono.git] / mcs / mcs / ecore.cs
index de9306cba570884e2bfd7d029c35cbcea6581bab..6263adab8b99b96e64fe7e943f8ea1baf4447c5c 100644 (file)
@@ -402,7 +402,7 @@ namespace Mono.CSharp {
                                        throw;
 
                                ec.Report.Error (584, loc, "Internal compiler error: {0}", ex.Message);
-                               return EmptyExpression.Null;    // TODO: Add location
+                               return ErrorExpression.Instance;        // TODO: Add location
                        }
                }
 
@@ -640,15 +640,11 @@ namespace Mono.CSharp {
                        }
 
                        var r = new OverloadResolver (ctors, OverloadResolver.Restrictions.NoBaseMembers, loc);
-                       var ctor = r.ResolveMember<MethodSpec> (rc, ref args);
-                       if (ctor == null)
-                               return null;
-
-                       if ((ctor.Modifiers & Modifiers.PROTECTED) != 0 && !rc.HasSet (ResolveContext.Options.BaseInitializer)) {
-                               MemberExpr.CheckProtectedMemberAccess (rc, ctor, ctor.DeclaringType, loc);
+                       if (!rc.HasSet (ResolveContext.Options.BaseInitializer)) {
+                               r.InstanceQualifier = new ConstructorInstanceQualifier (type);
                        }
 
-                       return ctor;
+                       return r.ResolveMember<MethodSpec> (rc, ref args);
                }
 
                [Flags]
@@ -1010,6 +1006,11 @@ namespace Mono.CSharp {
                {
                        throw new NotImplementedException ("MakeExpression for " + GetType ());
                }
+                       
+               public virtual object Accept (StructuralVisitor visitor)
+               {
+                       return visitor.Visit (this);
+               }
        }
 
        /// <summary>
@@ -2531,6 +2532,11 @@ namespace Mono.CSharp {
                        //if (ec.CurrentBlock == null || ec.CurrentBlock.CheckInvariantMeaningInBlock (Name, e, Location))
                        return e;
                }
+               
+               public override object Accept (StructuralVisitor visitor)
+               {
+                       return visitor.Visit (this);
+               }
        }
 
        /// <summary>
@@ -2660,7 +2666,7 @@ namespace Mono.CSharp {
        ///   This class denotes an expression which evaluates to a member
        ///   of a struct or a class.
        /// </summary>
-       public abstract class MemberExpr : Expression
+       public abstract class MemberExpr : Expression, OverloadResolver.IInstanceQualifier
        {
                //
                // An instance expression associated with this member, if it's a
@@ -2700,6 +2706,12 @@ namespace Mono.CSharp {
                        get;
                }
 
+               TypeSpec OverloadResolver.IInstanceQualifier.InstanceType {
+                       get {
+                               return InstanceExpression.Type;
+                       }
+               }
+
                //
                // Converts best base candidate for virtual method starting from QueriedBaseType
                //
@@ -2764,32 +2776,41 @@ namespace Mono.CSharp {
                        return method;
                }
 
-               protected void CheckProtectedMemberAccess<T> (ResolveContext rc, T member) where T : MemberSpec
+               protected void CheckProtectedMemberAccess (ResolveContext rc, MemberSpec member)
                {
                        if (InstanceExpression == null)
                                return;
 
                        if ((member.Modifiers & Modifiers.PROTECTED) != 0 && !(InstanceExpression is This)) {
-                               CheckProtectedMemberAccess (rc, member, InstanceExpression.Type, loc);
+                               if (!CheckProtectedMemberAccess (rc, member, InstanceExpression.Type)) {
+                                       Error_ProtectedMemberAccess (rc, member, InstanceExpression.Type, loc);
+                               }
                        }
                }
 
-               public static void CheckProtectedMemberAccess<T> (ResolveContext rc, T member, TypeSpec qualifier, Location loc) where T : MemberSpec
+               bool OverloadResolver.IInstanceQualifier.CheckProtectedMemberAccess (ResolveContext rc, MemberSpec member)
+               {
+                       if (InstanceExpression == null)
+                               return true;
+
+                       return InstanceExpression is This || CheckProtectedMemberAccess (rc, member, InstanceExpression.Type);
+               }
+
+               public static bool CheckProtectedMemberAccess<T> (ResolveContext rc, T member, TypeSpec qualifier) where T : MemberSpec
                {
                        var ct = rc.CurrentType;
                        if (ct == qualifier)
-                               return;
+                               return true;
 
                        if ((member.Modifiers & Modifiers.INTERNAL) != 0 && member.DeclaringType.MemberDefinition.IsInternalAsPublic (ct.MemberDefinition.DeclaringAssembly))
-                               return;
+                               return true;
 
                        qualifier = qualifier.GetDefinition ();
                        if (ct != qualifier && !IsSameOrBaseQualifier (ct, qualifier)) {
-                               rc.Report.SymbolRelatedToPreviousError (member);
-                               rc.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",
-                                       member.GetSignatureForError (), qualifier.GetSignatureForError (), ct.GetSignatureForError ());
+                               return false;
                        }
+
+                       return true;
                }
 
                public override bool ContainsEmitWithAwait ()
@@ -2842,6 +2863,14 @@ namespace Mono.CSharp {
                        rc.Report.Error (205, loc, "Cannot call an abstract base member `{0}'", name);
                }
 
+               public static void Error_ProtectedMemberAccess (ResolveContext rc, MemberSpec member, TypeSpec qualifier, Location loc)
+               {
+                       rc.Report.SymbolRelatedToPreviousError (member);
+                       rc.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",
+                               member.GetSignatureForError (), qualifier.GetSignatureForError (), rc.CurrentType.GetSignatureForError ());
+               }
+
                //
                // Implements identicial simple name and type-name
                //
@@ -3360,6 +3389,7 @@ namespace Mono.CSharp {
                        var r = new OverloadResolver (Methods, type_arguments, restr, loc);
                        if ((restr & OverloadResolver.Restrictions.NoBaseMembers) == 0) {
                                r.BaseMembersProvider = this;
+                               r.InstanceQualifier = this;
                        }
 
                        if (cerrors != null)
@@ -3388,8 +3418,6 @@ namespace Mono.CSharp {
                                }
 
                                ResolveInstanceExpression (ec, null);
-                               if (InstanceExpression != null)
-                                       CheckProtectedMemberAccess (ec, best_candidate);
                        }
 
                        var base_override = CandidateToBaseOverride (ec, best_candidate);
@@ -3455,6 +3483,22 @@ namespace Mono.CSharp {
                #endregion
        }
 
+       struct ConstructorInstanceQualifier : OverloadResolver.IInstanceQualifier
+       {
+               public ConstructorInstanceQualifier (TypeSpec type)
+                       : this ()
+               {
+                       InstanceType = type;
+               }
+
+               public TypeSpec InstanceType { get; private set; }
+
+               public bool CheckProtectedMemberAccess (ResolveContext rc, MemberSpec member)
+               {
+                       return MemberExpr.CheckProtectedMemberAccess (rc, member, InstanceType);
+               }
+       }
+
        public struct OverloadResolver
        {
                [Flags]
@@ -3483,6 +3527,12 @@ namespace Mono.CSharp {
                        bool TypeInferenceFailed (ResolveContext rc, MemberSpec best);
                }
 
+               public interface IInstanceQualifier
+               {
+                       TypeSpec InstanceType { get; }
+                       bool CheckProtectedMemberAccess (ResolveContext rc, MemberSpec member);
+               }
+
                sealed class NoBaseMembers : IBaseMembersProvider
                {
                        public static readonly IBaseMembersProvider Instance = new NoBaseMembers ();
@@ -3522,6 +3572,7 @@ namespace Mono.CSharp {
                TypeArguments type_arguments;
                IBaseMembersProvider base_provider;
                IErrorHandler custom_errors;
+               IInstanceQualifier instance_qualifier;
                Restrictions restrictions;
                MethodGroupExpr best_candidate_extension_group;
                TypeSpec best_candidate_return_type;
@@ -3599,6 +3650,15 @@ namespace Mono.CSharp {
                        }
                }
 
+               public IInstanceQualifier InstanceQualifier {
+                       get {
+                               return instance_qualifier;
+                       }
+                       set {
+                               instance_qualifier = value;
+                       }
+               }
+
                bool IsProbingOnly {
                        get {
                                return (restrictions & Restrictions.ProbingOnly) != 0;
@@ -4353,7 +4413,10 @@ namespace Mono.CSharp {
 
                        var ac_p = p as ArrayContainer;
                        if (ac_p != null) {
-                               var ac_q = ((ArrayContainer) q);
+                               var ac_q = q as ArrayContainer;
+                               if (ac_q == null)
+                                       return null;
+
                                TypeSpec specific = MoreSpecific (ac_p.Element, ac_q.Element);
                                if (specific == ac_p.Element)
                                        return p;
@@ -4428,6 +4491,11 @@ namespace Mono.CSharp {
 
                                                                if (rc.IsRuntimeBinder && !member.DeclaringType.IsAccessible (rc))
                                                                        continue;
+
+                                                               if ((member.Modifiers & (Modifiers.PROTECTED | Modifiers.STATIC)) == Modifiers.PROTECTED &&
+                                                                       instance_qualifier != null && !instance_qualifier.CheckProtectedMemberAccess (rc, member)) {
+                                                                       continue;
+                                                               }
                                                        }
 
                                                        IParametersMember pm = member as IParametersMember;
@@ -4567,6 +4635,9 @@ namespace Mono.CSharp {
                                if (error_mode)
                                        break;
 
+                               if (lambda_conv_msgs != null && !lambda_conv_msgs.IsEmpty)
+                                       break;
+
                                lambda_conv_msgs = null;
                                error_mode = true;
                        }
@@ -4729,6 +4800,12 @@ namespace Mono.CSharp {
                                        return;
                        }
 
+
+                       if ((best_candidate.Modifiers & (Modifiers.PROTECTED | Modifiers.STATIC)) == Modifiers.PROTECTED &&
+                               InstanceQualifier != null && !InstanceQualifier.CheckProtectedMemberAccess (rc, best_candidate)) {
+                               MemberExpr.Error_ProtectedMemberAccess (rc, best_candidate, InstanceQualifier.InstanceType, loc);
+                       }
+
                        //
                        // For candidates which match on parameters count report more details about incorrect arguments
                        //
@@ -5599,8 +5676,9 @@ namespace Mono.CSharp {
                        return CreateExpressionFactoryCall (ec, "Property", args);
                }
 
-               public Expression CreateSetterTypeOfExpression ()
+               public Expression CreateSetterTypeOfExpression (ResolveContext rc)
                {
+                       DoResolveLValue (rc, null);
                        return new TypeOfMethod (Setter, loc);
                }