|
@@ -14610,7 +14610,9 @@ namespace {
|
|
// context so never needs to be transformed.
|
|
// context so never needs to be transformed.
|
|
// FIXME: Ideally we wouldn't transform the closure type either, and would
|
|
// FIXME: Ideally we wouldn't transform the closure type either, and would
|
|
// just recreate the capture expressions and lambda expression.
|
|
// 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.
|
|
/// *FunctionScopeIndexToStopAt on the FunctionScopeInfo stack.
|
|
static void
|
|
static void
|
|
MarkVarDeclODRUsed(VarDecl *Var, SourceLocation Loc, Sema &SemaRef,
|
|
MarkVarDeclODRUsed(VarDecl *Var, SourceLocation Loc, Sema &SemaRef,
|
|
- const unsigned *const FunctionScopeIndexToStopAt) {
|
|
|
|
|
|
+ const unsigned *const FunctionScopeIndexToStopAt = nullptr) {
|
|
// Keep track of used but undefined variables.
|
|
// Keep track of used but undefined variables.
|
|
// FIXME: We shouldn't suppress this warning for static data members.
|
|
// FIXME: We shouldn't suppress this warning for static data members.
|
|
if (Var->hasDefinition(SemaRef.Context) == VarDecl::DeclarationOnly &&
|
|
if (Var->hasDefinition(SemaRef.Context) == VarDecl::DeclarationOnly &&
|
|
@@ -15735,14 +15737,19 @@ void Sema::UpdateMarkingForLValueToRValue(Expr *E) {
|
|
// variable.
|
|
// variable.
|
|
if (LambdaScopeInfo *LSI = getCurLambda()) {
|
|
if (LambdaScopeInfo *LSI = getCurLambda()) {
|
|
Expr *SansParensExpr = E->IgnoreParens();
|
|
Expr *SansParensExpr = E->IgnoreParens();
|
|
- VarDecl *Var = nullptr;
|
|
|
|
|
|
+ VarDecl *Var;
|
|
|
|
+ ArrayRef<VarDecl *> Vars = None;
|
|
if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(SansParensExpr))
|
|
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))
|
|
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);
|
|
std::swap(LocalMaybeODRUseExprs, MaybeODRUseExprs);
|
|
|
|
|
|
for (Expr *E : LocalMaybeODRUseExprs) {
|
|
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 {
|
|
} else {
|
|
llvm_unreachable("Unexpected expression");
|
|
llvm_unreachable("Unexpected expression");
|
|
}
|
|
}
|
|
-
|
|
|
|
- MarkVarDeclODRUsed(Var, Loc, *this,
|
|
|
|
- /*MaxFunctionScopeIndex Pointer*/ nullptr);
|
|
|
|
}
|
|
}
|
|
|
|
|
|
assert(MaybeODRUseExprs.empty() &&
|
|
assert(MaybeODRUseExprs.empty() &&
|
|
@@ -15789,7 +15794,8 @@ void Sema::CleanupVarDeclMarking() {
|
|
|
|
|
|
static void DoMarkVarDeclReferenced(Sema &SemaRef, SourceLocation Loc,
|
|
static void DoMarkVarDeclReferenced(Sema &SemaRef, SourceLocation Loc,
|
|
VarDecl *Var, Expr *E) {
|
|
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");
|
|
"Invalid Expr argument to DoMarkVarDeclReferenced");
|
|
Var->setReferenced();
|
|
Var->setReferenced();
|
|
|
|
|
|
@@ -16022,6 +16028,12 @@ void Sema::MarkMemberReferenced(MemberExpr *E) {
|
|
MarkExprReferenced(*this, Loc, E->getMemberDecl(), E, MightBeOdrUse);
|
|
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
|
|
/// Perform marking for a reference to an arbitrary declaration. It
|
|
/// marks the declaration referenced, and performs odr-use checking for
|
|
/// marks the declaration referenced, and performs odr-use checking for
|
|
/// functions and variables. This method should not be used when building a
|
|
/// functions and variables. This method should not be used when building a
|