diff options
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/SemaCodeComplete.cpp | 10 | ||||
-rw-r--r-- | lib/Sema/SemaCoroutine.cpp | 35 | ||||
-rw-r--r-- | lib/Sema/SemaDeclAttr.cpp | 14 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 8 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 9 | ||||
-rw-r--r-- | lib/Sema/SemaLambda.cpp | 16 | ||||
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 58 |
7 files changed, 94 insertions, 56 deletions
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp index b9349dc06bff..83c3bd27596c 100644 --- a/lib/Sema/SemaCodeComplete.cpp +++ b/lib/Sema/SemaCodeComplete.cpp @@ -4542,8 +4542,10 @@ void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS, bool EnteringContext) { if (!SS.getScopeRep() || !CodeCompleter) return; - - DeclContext *Ctx = computeDeclContext(SS, EnteringContext); + + // Always pretend to enter a context to ensure that a dependent type + // resolves to a dependent record. + DeclContext *Ctx = computeDeclContext(SS, /*EnteringContext=*/true); if (!Ctx) return; @@ -4573,7 +4575,9 @@ void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS, Results.ExitScope(); CodeCompletionDeclConsumer Consumer(Results, CurContext); - LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer); + LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer, + /*IncludeGlobalScope=*/true, + /*IncludeDependentBases=*/true); HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(), diff --git a/lib/Sema/SemaCoroutine.cpp b/lib/Sema/SemaCoroutine.cpp index 06ae66076e8a..b05c0998d3dd 100644 --- a/lib/Sema/SemaCoroutine.cpp +++ b/lib/Sema/SemaCoroutine.cpp @@ -470,11 +470,11 @@ static FunctionScopeInfo *checkCoroutineContext(Sema &S, SourceLocation Loc, return ScopeInfo; } -static bool actOnCoroutineBodyStart(Sema &S, Scope *SC, SourceLocation KWLoc, - StringRef Keyword) { - if (!checkCoroutineContext(S, KWLoc, Keyword)) +bool Sema::ActOnCoroutineBodyStart(Scope *SC, SourceLocation KWLoc, + StringRef Keyword) { + if (!checkCoroutineContext(*this, KWLoc, Keyword)) return false; - auto *ScopeInfo = S.getCurFunction(); + auto *ScopeInfo = getCurFunction(); assert(ScopeInfo->CoroutinePromise); // If we have existing coroutine statements then we have already built @@ -484,24 +484,24 @@ static bool actOnCoroutineBodyStart(Sema &S, Scope *SC, SourceLocation KWLoc, ScopeInfo->setNeedsCoroutineSuspends(false); - auto *Fn = cast<FunctionDecl>(S.CurContext); + auto *Fn = cast<FunctionDecl>(CurContext); SourceLocation Loc = Fn->getLocation(); // Build the initial suspend point auto buildSuspends = [&](StringRef Name) mutable -> StmtResult { ExprResult Suspend = - buildPromiseCall(S, ScopeInfo->CoroutinePromise, Loc, Name, None); + buildPromiseCall(*this, ScopeInfo->CoroutinePromise, Loc, Name, None); if (Suspend.isInvalid()) return StmtError(); - Suspend = buildOperatorCoawaitCall(S, SC, Loc, Suspend.get()); + Suspend = buildOperatorCoawaitCall(*this, SC, Loc, Suspend.get()); if (Suspend.isInvalid()) return StmtError(); - Suspend = S.BuildResolvedCoawaitExpr(Loc, Suspend.get(), - /*IsImplicit*/ true); - Suspend = S.ActOnFinishFullExpr(Suspend.get()); + Suspend = BuildResolvedCoawaitExpr(Loc, Suspend.get(), + /*IsImplicit*/ true); + Suspend = ActOnFinishFullExpr(Suspend.get()); if (Suspend.isInvalid()) { - S.Diag(Loc, diag::note_coroutine_promise_suspend_implicitly_required) + Diag(Loc, diag::note_coroutine_promise_suspend_implicitly_required) << ((Name == "initial_suspend") ? 0 : 1); - S.Diag(KWLoc, diag::note_declared_coroutine_here) << Keyword; + Diag(KWLoc, diag::note_declared_coroutine_here) << Keyword; return StmtError(); } return cast<Stmt>(Suspend.get()); @@ -521,7 +521,7 @@ static bool actOnCoroutineBodyStart(Sema &S, Scope *SC, SourceLocation KWLoc, } ExprResult Sema::ActOnCoawaitExpr(Scope *S, SourceLocation Loc, Expr *E) { - if (!actOnCoroutineBodyStart(*this, S, Loc, "co_await")) { + if (!ActOnCoroutineBodyStart(S, Loc, "co_await")) { CorrectDelayedTyposInExpr(E); return ExprError(); } @@ -613,7 +613,7 @@ ExprResult Sema::BuildResolvedCoawaitExpr(SourceLocation Loc, Expr *E, } ExprResult Sema::ActOnCoyieldExpr(Scope *S, SourceLocation Loc, Expr *E) { - if (!actOnCoroutineBodyStart(*this, S, Loc, "co_yield")) { + if (!ActOnCoroutineBodyStart(S, Loc, "co_yield")) { CorrectDelayedTyposInExpr(E); return ExprError(); } @@ -658,14 +658,15 @@ ExprResult Sema::BuildCoyieldExpr(SourceLocation Loc, Expr *E) { if (RSS.IsInvalid) return ExprError(); - Expr *Res = new (Context) CoyieldExpr(Loc, E, RSS.Results[0], RSS.Results[1], - RSS.Results[2], RSS.OpaqueValue); + Expr *Res = + new (Context) CoyieldExpr(Loc, E, RSS.Results[0], RSS.Results[1], + RSS.Results[2], RSS.OpaqueValue); return Res; } StmtResult Sema::ActOnCoreturnStmt(Scope *S, SourceLocation Loc, Expr *E) { - if (!actOnCoroutineBodyStart(*this, S, Loc, "co_return")) { + if (!ActOnCoroutineBodyStart(S, Loc, "co_return")) { CorrectDelayedTyposInExpr(E); return StmtError(); } diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 6c492fac9eb9..b43642f5493b 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -313,8 +313,8 @@ static bool checkAttrMutualExclusion(Sema &S, Decl *D, SourceRange Range, /// \returns true if IdxExpr is a valid index. template <typename AttrInfo> static bool checkFunctionOrMethodParameterIndex( - Sema &S, const Decl *D, const AttrInfo& Attr, - unsigned AttrArgNum, const Expr *IdxExpr, uint64_t &Idx) { + Sema &S, const Decl *D, const AttrInfo &Attr, unsigned AttrArgNum, + const Expr *IdxExpr, uint64_t &Idx, bool AllowImplicitThis = false) { assert(isFunctionOrMethodOrBlock(D)); // In C++ the implicit 'this' function parameter also counts. @@ -341,7 +341,7 @@ static bool checkFunctionOrMethodParameterIndex( return false; } Idx--; // Convert to zero-based. - if (HasImplicitThisParam) { + if (HasImplicitThisParam && !AllowImplicitThis) { if (Idx == 0) { S.Diag(getAttrLoc(Attr), diag::err_attribute_invalid_implicit_this_argument) @@ -4604,14 +4604,16 @@ static void handleTypeTagForDatatypeAttr(Sema &S, Decl *D, static void handleXRayLogArgsAttr(Sema &S, Decl *D, const AttributeList &Attr) { uint64_t ArgCount; + if (!checkFunctionOrMethodParameterIndex(S, D, Attr, 1, Attr.getArgAsExpr(0), - ArgCount)) + ArgCount, + true /* AllowImplicitThis*/)) return; // ArgCount isn't a parameter index [0;n), it's a count [1;n] - hence + 1. D->addAttr(::new (S.Context) - XRayLogArgsAttr(Attr.getRange(), S.Context, ++ArgCount, - Attr.getAttributeSpellingListIndex())); + XRayLogArgsAttr(Attr.getRange(), S.Context, ++ArgCount, + Attr.getAttributeSpellingListIndex())); } //===----------------------------------------------------------------------===// diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 0f8f5c253ac6..75a6903392ea 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -12057,11 +12057,17 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, } break; case UO_Extension: - case UO_Coawait: resultType = Input.get()->getType(); VK = Input.get()->getValueKind(); OK = Input.get()->getObjectKind(); break; + case UO_Coawait: + // It's unnessesary to represent the pass-through operator co_await in the + // AST; just return the input expression instead. + assert(!Input.get()->getType()->isDependentType() && + "the co_await expression must be non-dependant before " + "building operator co_await"); + return Input; } if (resultType.isNull() || Input.isInvalid()) return ExprError(); diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 00a4b39f1423..a9ff21bc41ab 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -189,12 +189,15 @@ ParsedType Sema::getDestructorName(SourceLocation TildeLoc, // have one) and, if that fails to find a match, in the scope (if // we're allowed to look there). Found.clear(); - if (Step == 0 && LookupCtx) + if (Step == 0 && LookupCtx) { + if (RequireCompleteDeclContext(SS, LookupCtx)) + return nullptr; LookupQualifiedName(Found, LookupCtx); - else if (Step == 1 && LookInScope && S) + } else if (Step == 1 && LookInScope && S) { LookupName(Found, S); - else + } else { continue; + } // FIXME: Should we be suppressing ambiguities here? if (Found.isAmbiguous()) diff --git a/lib/Sema/SemaLambda.cpp b/lib/Sema/SemaLambda.cpp index a6239283b47b..d6b70610d461 100644 --- a/lib/Sema/SemaLambda.cpp +++ b/lib/Sema/SemaLambda.cpp @@ -1492,6 +1492,7 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc, bool ExplicitResultType; CleanupInfo LambdaCleanup; bool ContainsUnexpandedParameterPack; + bool IsGenericLambda; { CallOperator = LSI->CallOperator; Class = LSI->Lambda; @@ -1500,7 +1501,8 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc, ExplicitResultType = !LSI->HasImplicitReturnType; LambdaCleanup = LSI->Cleanup; ContainsUnexpandedParameterPack = LSI->ContainsUnexpandedParameterPack; - + IsGenericLambda = Class->isGenericLambda(); + CallOperator->setLexicalDeclContext(Class); Decl *TemplateOrNonTemplateCallOperatorDecl = CallOperator->getDescribedFunctionTemplate() @@ -1520,8 +1522,13 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc, bool IsImplicit = I >= LSI->NumExplicitCaptures; // Warn about unused explicit captures. - if (!CurContext->isDependentContext() && !IsImplicit && !From.isODRUsed()) - DiagnoseUnusedLambdaCapture(From); + if (!CurContext->isDependentContext() && !IsImplicit && !From.isODRUsed()) { + // Initialized captures that are non-ODR used may not be eliminated. + bool NonODRUsedInitCapture = + IsGenericLambda && From.isNonODRUsed() && From.getInitExpr(); + if (!NonODRUsedInitCapture) + DiagnoseUnusedLambdaCapture(From); + } // Handle 'this' capture. if (From.isThisCapture()) { @@ -1568,8 +1575,7 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc, // same parameter and return types as the closure type's function call // operator. // FIXME: Fix generic lambda to block conversions. - if (getLangOpts().Blocks && getLangOpts().ObjC1 && - !Class->isGenericLambda()) + if (getLangOpts().Blocks && getLangOpts().ObjC1 && !IsGenericLambda) addBlockPointerConversion(*this, IntroducerRange, Class, CallOperator); // Finalize the lambda class. diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index 151b89ab8d2a..eed10b077eb8 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -1989,11 +1989,11 @@ StmtResult Sema::ActOnCXXForRangeStmt(Scope *S, SourceLocation ForLoc, return StmtError(); } - // Coroutines: 'for co_await' implicitly co_awaits its range. - if (CoawaitLoc.isValid()) { - ExprResult Coawait = ActOnCoawaitExpr(S, CoawaitLoc, Range); - if (Coawait.isInvalid()) return StmtError(); - Range = Coawait.get(); + // Build the coroutine state immediately and not later during template + // instantiation + if (!CoawaitLoc.isInvalid()) { + if (!ActOnCoroutineBodyStart(S, CoawaitLoc, "co_await")) + return StmtError(); } // Build auto && __range = range-init @@ -2031,16 +2031,12 @@ StmtResult Sema::ActOnCXXForRangeStmt(Scope *S, SourceLocation ForLoc, /// BeginExpr and EndExpr are set and FRS_Success is returned on success; /// CandidateSet and BEF are set and some non-success value is returned on /// failure. -static Sema::ForRangeStatus BuildNonArrayForRange(Sema &SemaRef, - Expr *BeginRange, Expr *EndRange, - QualType RangeType, - VarDecl *BeginVar, - VarDecl *EndVar, - SourceLocation ColonLoc, - OverloadCandidateSet *CandidateSet, - ExprResult *BeginExpr, - ExprResult *EndExpr, - BeginEndFunction *BEF) { +static Sema::ForRangeStatus +BuildNonArrayForRange(Sema &SemaRef, Expr *BeginRange, Expr *EndRange, + QualType RangeType, VarDecl *BeginVar, VarDecl *EndVar, + SourceLocation ColonLoc, SourceLocation CoawaitLoc, + OverloadCandidateSet *CandidateSet, ExprResult *BeginExpr, + ExprResult *EndExpr, BeginEndFunction *BEF) { DeclarationNameInfo BeginNameInfo( &SemaRef.PP.getIdentifierTable().get("begin"), ColonLoc); DeclarationNameInfo EndNameInfo(&SemaRef.PP.getIdentifierTable().get("end"), @@ -2087,6 +2083,15 @@ static Sema::ForRangeStatus BuildNonArrayForRange(Sema &SemaRef, << ColonLoc << BEF_begin << BeginRange->getType(); return RangeStatus; } + if (!CoawaitLoc.isInvalid()) { + // FIXME: getCurScope() should not be used during template instantiation. + // We should pick up the set of unqualified lookup results for operator + // co_await during the initial parse. + *BeginExpr = SemaRef.ActOnCoawaitExpr(SemaRef.getCurScope(), ColonLoc, + BeginExpr->get()); + if (BeginExpr->isInvalid()) + return Sema::FRS_DiagnosticIssued; + } if (FinishForRangeVarDecl(SemaRef, BeginVar, BeginExpr->get(), ColonLoc, diag::err_for_range_iter_deduction_failure)) { NoteForRangeBeginEndFunction(SemaRef, BeginExpr->get(), *BEF); @@ -2206,8 +2211,12 @@ Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation CoawaitLoc, // Deduce any 'auto's in the loop variable as 'DependentTy'. We'll fill // them in properly when we instantiate the loop. - if (!LoopVar->isInvalidDecl() && Kind != BFRK_Check) + if (!LoopVar->isInvalidDecl() && Kind != BFRK_Check) { + if (auto *DD = dyn_cast<DecompositionDecl>(LoopVar)) + for (auto *Binding : DD->bindings()) + Binding->setType(Context.DependentTy); LoopVar->setType(SubstAutoType(LoopVar->getType(), Context.DependentTy)); + } } else if (!BeginDeclStmt.get()) { SourceLocation RangeLoc = RangeVar->getLocation(); @@ -2249,6 +2258,11 @@ Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation CoawaitLoc, // begin-expr is __range. BeginExpr = BeginRangeRef; + if (!CoawaitLoc.isInvalid()) { + BeginExpr = ActOnCoawaitExpr(S, ColonLoc, BeginExpr.get()); + if (BeginExpr.isInvalid()) + return StmtError(); + } if (FinishForRangeVarDecl(*this, BeginVar, BeginRangeRef.get(), ColonLoc, diag::err_for_range_iter_deduction_failure)) { NoteForRangeBeginEndFunction(*this, BeginExpr.get(), BEF_begin); @@ -2331,11 +2345,10 @@ Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation CoawaitLoc, OverloadCandidateSet CandidateSet(RangeLoc, OverloadCandidateSet::CSK_Normal); BeginEndFunction BEFFailure; - ForRangeStatus RangeStatus = - BuildNonArrayForRange(*this, BeginRangeRef.get(), - EndRangeRef.get(), RangeType, - BeginVar, EndVar, ColonLoc, &CandidateSet, - &BeginExpr, &EndExpr, &BEFFailure); + ForRangeStatus RangeStatus = BuildNonArrayForRange( + *this, BeginRangeRef.get(), EndRangeRef.get(), RangeType, BeginVar, + EndVar, ColonLoc, CoawaitLoc, &CandidateSet, &BeginExpr, &EndExpr, + &BEFFailure); if (Kind == BFRK_Build && RangeStatus == FRS_NoViableFunction && BEFFailure == BEF_begin) { @@ -2432,6 +2445,9 @@ Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation CoawaitLoc, IncrExpr = ActOnUnaryOp(S, ColonLoc, tok::plusplus, BeginRef.get()); if (!IncrExpr.isInvalid() && CoawaitLoc.isValid()) + // FIXME: getCurScope() should not be used during template instantiation. + // We should pick up the set of unqualified lookup results for operator + // co_await during the initial parse. IncrExpr = ActOnCoawaitExpr(S, CoawaitLoc, IncrExpr.get()); if (!IncrExpr.isInvalid()) IncrExpr = ActOnFinishFullExpr(IncrExpr.get()); |