summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaExpr.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2019-06-04 17:17:20 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2019-06-04 17:17:20 +0000
commit7bf8f6fa8ab123fe97ccd82d9a0ddff85505ee5f (patch)
treec5eb10d1d4e1f82ebd3925ca1bde79d1145d73e3 /clang/lib/Sema/SemaExpr.cpp
parentf4302ad35e340f01529bf32919410b2577f899bd (diff)
downloadbcm5719-llvm-7bf8f6fa8ab123fe97ccd82d9a0ddff85505ee5f.tar.gz
bcm5719-llvm-7bf8f6fa8ab123fe97ccd82d9a0ddff85505ee5f.zip
PR42104: Support instantiations of lambdas that implicitly capture
packs. Two changes: * Track odr-use via FunctionParmPackExprs to properly handle dependent odr-uses of packs in generic lambdas. * Do not instantiate implicit captures; instead, regenerate them by instantiating the body of the lambda. This is necessary to distinguish between cases where only one element of a pack is captured and cases where the entire pack is captured. This reinstates r362358 (reverted in r362375) with a fix for an uninitialized variable use in UpdateMarkingForLValueToRValue. llvm-svn: 362531
Diffstat (limited to 'clang/lib/Sema/SemaExpr.cpp')
-rw-r--r--clang/lib/Sema/SemaExpr.cpp48
1 files changed, 31 insertions, 17 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 72b61b8e584..1e9164bc3ac 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,21 @@ void Sema::UpdateMarkingForLValueToRValue(Expr *E) {
// variable.
if (LambdaScopeInfo *LSI = getCurLambda()) {
Expr *SansParensExpr = E->IgnoreParens();
- VarDecl *Var = nullptr;
+ VarDecl *Var;
+ ArrayRef<VarDecl *> Vars(&Var, &Var + 1);
if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(SansParensExpr))
Var = dyn_cast<VarDecl>(DRE->getFoundDecl());
else if (MemberExpr *ME = dyn_cast<MemberExpr>(SansParensExpr))
Var = dyn_cast<VarDecl>(ME->getMemberDecl());
+ else if (auto *FPPE = dyn_cast<FunctionParmPackExpr>(SansParensExpr))
+ Vars = llvm::makeArrayRef(FPPE->begin(), FPPE->end());
+ else
+ Vars = None;
- if (Var && IsVariableNonDependentAndAConstantExpression(Var, Context))
- LSI->markVariableExprAsNonODRUsed(SansParensExpr);
+ for (VarDecl *VD : Vars) {
+ if (VD && IsVariableNonDependentAndAConstantExpression(VD, Context))
+ LSI->markVariableExprAsNonODRUsed(SansParensExpr);
+ }
}
}
@@ -15767,20 +15776,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 +15796,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 +16030,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
OpenPOWER on IntegriCloud