diff options
Diffstat (limited to 'clang/lib/Sema/SemaExpr.cpp')
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 50 |
1 files changed, 31 insertions, 19 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 72b61b8e584..d0b27602846 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -14610,7 +14610,9 @@ namespace { // context so never needs to be transformed. // FIXME: Ideally we wouldn't transform the closure type either, and would // just recreate the capture expressions and lambda expression. - StmtResult TransformLambdaBody(Stmt *Body) { return Body; } + StmtResult TransformLambdaBody(LambdaExpr *E, Stmt *Body) { + return SkipLambdaBody(E, Body); + } }; } @@ -15054,7 +15056,7 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func, /// *FunctionScopeIndexToStopAt on the FunctionScopeInfo stack. static void MarkVarDeclODRUsed(VarDecl *Var, SourceLocation Loc, Sema &SemaRef, - const unsigned *const FunctionScopeIndexToStopAt) { + const unsigned *const FunctionScopeIndexToStopAt = nullptr) { // Keep track of used but undefined variables. // FIXME: We shouldn't suppress this warning for static data members. if (Var->hasDefinition(SemaRef.Context) == VarDecl::DeclarationOnly && @@ -15735,14 +15737,19 @@ void Sema::UpdateMarkingForLValueToRValue(Expr *E) { // variable. if (LambdaScopeInfo *LSI = getCurLambda()) { Expr *SansParensExpr = E->IgnoreParens(); - VarDecl *Var = nullptr; + VarDecl *Var; + ArrayRef<VarDecl *> Vars = None; if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(SansParensExpr)) - Var = dyn_cast<VarDecl>(DRE->getFoundDecl()); + Vars = Var = dyn_cast<VarDecl>(DRE->getFoundDecl()); else if (MemberExpr *ME = dyn_cast<MemberExpr>(SansParensExpr)) - Var = dyn_cast<VarDecl>(ME->getMemberDecl()); + Vars = Var = dyn_cast<VarDecl>(ME->getMemberDecl()); + else if (auto *FPPE = dyn_cast<FunctionParmPackExpr>(SansParensExpr)) + Vars = llvm::makeArrayRef(FPPE->begin(), FPPE->end()); - if (Var && IsVariableNonDependentAndAConstantExpression(Var, Context)) - LSI->markVariableExprAsNonODRUsed(SansParensExpr); + for (VarDecl *VD : Vars) { + if (Var && IsVariableNonDependentAndAConstantExpression(VD, Context)) + LSI->markVariableExprAsNonODRUsed(SansParensExpr); + } } } @@ -15767,20 +15774,18 @@ void Sema::CleanupVarDeclMarking() { std::swap(LocalMaybeODRUseExprs, MaybeODRUseExprs); for (Expr *E : LocalMaybeODRUseExprs) { - VarDecl *Var; - SourceLocation Loc; - if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) { - Var = cast<VarDecl>(DRE->getDecl()); - Loc = DRE->getLocation(); - } else if (MemberExpr *ME = dyn_cast<MemberExpr>(E)) { - Var = cast<VarDecl>(ME->getMemberDecl()); - Loc = ME->getMemberLoc(); + if (auto *DRE = dyn_cast<DeclRefExpr>(E)) { + MarkVarDeclODRUsed(cast<VarDecl>(DRE->getDecl()), + DRE->getLocation(), *this); + } else if (auto *ME = dyn_cast<MemberExpr>(E)) { + MarkVarDeclODRUsed(cast<VarDecl>(ME->getMemberDecl()), ME->getMemberLoc(), + *this); + } else if (auto *FP = dyn_cast<FunctionParmPackExpr>(E)) { + for (VarDecl *VD : *FP) + MarkVarDeclODRUsed(VD, FP->getParameterPackLocation(), *this); } else { llvm_unreachable("Unexpected expression"); } - - MarkVarDeclODRUsed(Var, Loc, *this, - /*MaxFunctionScopeIndex Pointer*/ nullptr); } assert(MaybeODRUseExprs.empty() && @@ -15789,7 +15794,8 @@ void Sema::CleanupVarDeclMarking() { static void DoMarkVarDeclReferenced(Sema &SemaRef, SourceLocation Loc, VarDecl *Var, Expr *E) { - assert((!E || isa<DeclRefExpr>(E) || isa<MemberExpr>(E)) && + assert((!E || isa<DeclRefExpr>(E) || isa<MemberExpr>(E) || + isa<FunctionParmPackExpr>(E)) && "Invalid Expr argument to DoMarkVarDeclReferenced"); Var->setReferenced(); @@ -16022,6 +16028,12 @@ void Sema::MarkMemberReferenced(MemberExpr *E) { MarkExprReferenced(*this, Loc, E->getMemberDecl(), E, MightBeOdrUse); } +/// Perform reference-marking and odr-use handling for a FunctionParmPackExpr. +void Sema::MarkFunctionParmPackReferenced(FunctionParmPackExpr *E) { + for (VarDecl *VD : *E) + MarkExprReferenced(*this, E->getParameterPackLocation(), VD, E, true); +} + /// Perform marking for a reference to an arbitrary declaration. It /// marks the declaration referenced, and performs odr-use checking for /// functions and variables. This method should not be used when building a |