X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fecore.cs;h=34ff9a30dab3cb423f4b9f64b7a7640d67a2b56a;hb=adaf7fd65b9a53a8e127d41bf430e56001c6e472;hp=99ba10dcb9dce06e5e15819cc5bbd6345131bc92;hpb=3b3017dbe482ef7fef5e56f19aeae9c9ccea35d7;p=mono.git diff --git a/mcs/mcs/ecore.cs b/mcs/mcs/ecore.cs index 99ba10dcb9d..34ff9a30dab 100644 --- a/mcs/mcs/ecore.cs +++ b/mcs/mcs/ecore.cs @@ -45,7 +45,7 @@ namespace Mono.CSharp { PropertyAccess, EventAccess, IndexerAccess, - Nothing, + Nothing, } /// @@ -239,6 +239,15 @@ namespace Mono.CSharp { return null; } + protected void CheckExpressionVariable (ResolveContext rc) + { + if (rc.HasAny (ResolveContext.Options.BaseInitializer | ResolveContext.Options.FieldInitializerScope)) { + rc.Report.Error (8200, loc, "Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers"); + } else if (rc.HasSet (ResolveContext.Options.QueryClauseScope)) { + rc.Report.Error (8201, loc, "Out variable and pattern variable declarations are not allowed within a query clause"); + } + } + public static void ErrorIsInaccesible (IMemberContext rc, string member, Location loc) { rc.Module.Compiler.Report.Error (122, loc, "`{0}' is inaccessible due to its protection level", member); @@ -294,7 +303,12 @@ namespace Mono.CSharp { return; string from_type = type.GetSignatureForError (); + if (type.Kind == MemberKind.ByRef) + from_type = "ref " + from_type; string to_type = target.GetSignatureForError (); + if (target.Kind == MemberKind.ByRef) + to_type = "ref " + to_type; + if (from_type == to_type) { from_type = type.GetSignatureForErrorIncludingAssemblyName (); to_type = target.GetSignatureForErrorIncludingAssemblyName (); @@ -550,18 +564,18 @@ namespace Mono.CSharp { public Expression ResolveLValue (ResolveContext ec, Expression right_side) { int errors = ec.Report.Errors; - bool out_access = right_side == EmptyExpression.OutAccess; + //bool out_access = right_side == EmptyExpression.OutAccess; Expression e = DoResolveLValue (ec, right_side); - if (e != null && out_access && !(e is IMemoryLocation)) { + //if (e != null && out_access && !(e is IMemoryLocation)) { // FIXME: There's no problem with correctness, the 'Expr = null' handles that. // Enabling this 'throw' will "only" result in deleting useless code elsewhere, //throw new InternalErrorException ("ResolveLValue didn't return an IMemoryLocation: " + // e.GetType () + " " + e.GetSignatureForError ()); - e = null; - } + // e = null; + //} if (e == null) { if (errors == ec.Report.Errors) { @@ -638,6 +652,10 @@ namespace Mono.CSharp { ec.Emit (OpCodes.Pop); } + public virtual void EmitPrepare (EmitContext ec) + { + } + // // Emits the expression into temporary field variable. The method // should be used for await expressions only @@ -863,6 +881,15 @@ namespace Mono.CSharp { return MemberLookupToExpression (rc, members, errorMode, queried_type, name, arity, restrictions, loc); } + if ((restrictions & MemberLookupRestrictions.InvocableOnly) == 0) { + var ntuple = queried_type as NamedTupleSpec; + if (ntuple != null) { + var ms = ntuple.FindElement (rc, name, loc); + if (ms != null) + return ExprClassFromMemberInfo (ms, loc); + } + } + return null; } @@ -995,6 +1022,11 @@ namespace Mono.CSharp { { } + public virtual Reachability MarkReachable (Reachability rc) + { + return rc; + } + // // Special version of flow analysis for expressions which can return different // on-true and on-false result. Used by &&, ||, ?: expressions @@ -1295,10 +1327,6 @@ namespace Mono.CSharp { /// public abstract class ExpressionStatement : Expression { - public virtual void MarkReachable (Reachability rc) - { - } - public virtual ExpressionStatement ResolveStatement (BlockContext ec) { Expression e = Resolve (ec); @@ -1460,6 +1488,11 @@ namespace Mono.CSharp { #endif } + public override Reachability MarkReachable (Reachability rc) + { + return child.MarkReachable (rc); + } + protected override void CloneTo (CloneContext clonectx, Expression t) { // Nothing to clone @@ -2401,13 +2434,23 @@ namespace Mono.CSharp { public override void FlowAnalysis (FlowAnalysisContext fc) { - expr.FlowAnalysis (fc); + orig_expr.FlowAnalysis (fc); + } + + public override void FlowAnalysisConditional (FlowAnalysisContext fc) + { + orig_expr.FlowAnalysisConditional (fc); } public override SLE.Expression MakeExpression (BuilderContext ctx) { return orig_expr.MakeExpression (ctx); } + + public override Reachability MarkReachable (Reachability rc) + { + return expr.MarkReachable (rc); + } } // @@ -2762,9 +2805,13 @@ namespace Mono.CSharp { return null; } - public bool IsPossibleTypeOrNamespace (IMemberContext mc) + bool IsPossibleTypeOrNamespace (IMemberContext mc) { - return mc.LookupNamespaceOrType (Name, Arity, LookupMode.Probing, loc) != null; + // + // Has to ignore static usings because we are looking for any member not just type + // in this context + // + return mc.LookupNamespaceOrType (Name, Arity, LookupMode.Probing | LookupMode.IgnoreStaticUsing, loc) != null; } public bool IsPossibleType (IMemberContext mc) @@ -2886,6 +2933,15 @@ namespace Mono.CSharp { return me; } + // + // Stage 3: Lookup nested types, namespaces and type parameters in the context + // + if ((restrictions & MemberLookupRestrictions.InvocableOnly) == 0 && !variable_found) { + if (IsPossibleTypeOrNamespace (rc)) { + return ResolveAsTypeOrNamespace (rc, false); + } + } + var expr = NamespaceContainer.LookupStaticUsings (rc, Name, Arity, loc); if (expr != null) { if (Arity > 0) { @@ -2898,15 +2954,6 @@ namespace Mono.CSharp { return expr; } - // - // Stage 3: Lookup nested types, namespaces and type parameters in the context - // - if ((restrictions & MemberLookupRestrictions.InvocableOnly) == 0 && !variable_found) { - if (IsPossibleTypeOrNamespace (rc)) { - return ResolveAsTypeOrNamespace (rc, false); - } - } - if ((restrictions & MemberLookupRestrictions.NameOfExcluded) == 0 && Name == "nameof") return new NameOf (this); @@ -4017,6 +4064,11 @@ namespace Mono.CSharp { throw new NotSupportedException (); } + public override void EmitPrepare (EmitContext ec) + { + InstanceExpression?.EmitPrepare (ec); + } + public void EmitCall (EmitContext ec, Arguments arguments, bool statement) { var call = new CallEmitter (); @@ -5370,6 +5422,11 @@ namespace Mono.CSharp { if (arg_type == InternalType.VarOutType) return 0; + var ref_arg_type = arg_type as ReferenceContainer; + if (ref_arg_type != null) { + arg_type = ref_arg_type.Element; + } + // // Do full equality check after quick path // @@ -5935,13 +5992,13 @@ namespace Mono.CSharp { int arg_count = args == null ? 0 : args.Count; for (; a_idx < arg_count; a_idx++, ++a_pos) { - a = args[a_idx]; + a = args [a_idx]; if (a == null) continue; if (p_mod != Parameter.Modifier.PARAMS) { p_mod = cpd.FixedParameters [a_idx].ModFlags; - pt = ptypes[a_idx]; + pt = ptypes [a_idx]; has_unsafe_arg |= pt.IsPointer; if (p_mod == Parameter.Modifier.PARAMS) { @@ -5971,6 +6028,14 @@ namespace Mono.CSharp { continue; } + var ref_arg_type = arg_type as ReferenceContainer; + if (ref_arg_type != null) { + if (ref_arg_type.Element != pt) + break; + + return true; + } + if (!TypeSpecComparer.IsEqual (arg_type, pt)) break; } @@ -6478,12 +6543,12 @@ namespace Mono.CSharp { GetSignatureForError ()); } - return null; + return ErrorExpression.Instance; } if (right_side == EmptyExpression.LValueMemberAccess) { // Already reported as CS1648/CS1650 - return null; + return ErrorExpression.Instance; } if (right_side == EmptyExpression.LValueMemberOutAccess) { @@ -6494,7 +6559,7 @@ namespace Mono.CSharp { rc.Report.Error (1649, loc, "Members of readonly field `{0}' cannot be passed ref or out (except in a constructor)", GetSignatureForError ()); } - return null; + return ErrorExpression.Instance; } if (IsStatic) { @@ -6505,7 +6570,7 @@ namespace Mono.CSharp { GetSignatureForError ()); } - return null; + return ErrorExpression.Instance; } public override Expression DoResolveLValue (ResolveContext ec, Expression right_side) @@ -7294,6 +7359,15 @@ namespace Mono.CSharp { Error_NullPropagatingLValue (rc); if (right_side == EmptyExpression.OutAccess) { + if (best_candidate?.MemberType.Kind == MemberKind.ByRef) { + if (Arguments?.ContainsEmitWithAwait () == true) { + rc.Report.Error (8178, loc, "`await' cannot be used in an expression containing a call to `{0}' because it returns by reference", + GetSignatureForError ()); + } + + return this; + } + // TODO: best_candidate can be null at this point INamedBlockVariable variable = null; if (best_candidate != null && rc.CurrentBlock.ParametersBlock.TopBlock.GetLocalName (best_candidate.Name, rc.CurrentBlock, ref variable) && variable is Linq.RangeVariable) { @@ -7320,6 +7394,11 @@ namespace Mono.CSharp { if (ResolveAutopropertyAssignment (rc, right_side)) return this; + if (best_candidate.MemberType.Kind == MemberKind.ByRef) { + getter = CandidateToBaseOverride (rc, best_candidate.Get); + return ByRefDereference.Create(this).Resolve(rc); + } + rc.Report.Error (200, loc, "Property or indexer `{0}' cannot be assigned to (it is read-only)", GetSignatureForError ()); return null; @@ -7770,13 +7849,14 @@ namespace Mono.CSharp { { } - public bool InferType (ResolveContext ec, Expression right_side) + public bool InferType (ResolveContext ec, Expression rhs) { if (type != null) throw new InternalErrorException ("An implicitly typed local variable could not be redefined"); - type = right_side.Type; - if (type == InternalType.NullLiteral || type.Kind == MemberKind.Void || type == InternalType.AnonymousMethod || type == InternalType.MethodGroup) { + type = rhs.Type; + + if (type.Kind == MemberKind.Void || InternalType.HasNoType (type) || (rhs is TupleLiteral && TupleLiteral.ContainsNoTypeElement (type))) { ec.Report.Error (815, loc, "An implicitly typed local variable declaration cannot be initialized with `{0}'", type.GetSignatureForError ());