|
@@ -450,8 +450,10 @@ public:
|
|
/// TransformDefinition. However, in some cases (e.g., lambda expressions),
|
|
/// TransformDefinition. However, in some cases (e.g., lambda expressions),
|
|
/// the transformer itself has to transform the declarations. This routine
|
|
/// the transformer itself has to transform the declarations. This routine
|
|
/// can be overridden by a subclass that keeps track of such mappings.
|
|
/// can be overridden by a subclass that keeps track of such mappings.
|
|
- void transformedLocalDecl(Decl *Old, Decl *New) {
|
|
|
|
- TransformedLocalDecls[Old] = New;
|
|
|
|
|
|
+ void transformedLocalDecl(Decl *Old, ArrayRef<Decl *> New) {
|
|
|
|
+ assert(New.size() == 1 &&
|
|
|
|
+ "must override transformedLocalDecl if performing pack expansion");
|
|
|
|
+ TransformedLocalDecls[Old] = New.front();
|
|
}
|
|
}
|
|
|
|
|
|
/// Transform the definition of the given declaration.
|
|
/// Transform the definition of the given declaration.
|
|
@@ -7122,7 +7124,7 @@ TreeTransform<Derived>::TransformCoroutineBodyStmt(CoroutineBodyStmt *S) {
|
|
auto *Promise = SemaRef.buildCoroutinePromise(FD->getLocation());
|
|
auto *Promise = SemaRef.buildCoroutinePromise(FD->getLocation());
|
|
if (!Promise)
|
|
if (!Promise)
|
|
return StmtError();
|
|
return StmtError();
|
|
- getDerived().transformedLocalDecl(S->getPromiseDecl(), Promise);
|
|
|
|
|
|
+ getDerived().transformedLocalDecl(S->getPromiseDecl(), {Promise});
|
|
ScopeInfo->CoroutinePromise = Promise;
|
|
ScopeInfo->CoroutinePromise = Promise;
|
|
|
|
|
|
// Transform the implicit coroutine statements we built during the initial
|
|
// Transform the implicit coroutine statements we built during the initial
|
|
@@ -11176,33 +11178,80 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
|
|
// Transform any init-capture expressions before entering the scope of the
|
|
// Transform any init-capture expressions before entering the scope of the
|
|
// lambda body, because they are not semantically within that scope.
|
|
// lambda body, because they are not semantically within that scope.
|
|
typedef std::pair<ExprResult, QualType> InitCaptureInfoTy;
|
|
typedef std::pair<ExprResult, QualType> InitCaptureInfoTy;
|
|
- SmallVector<InitCaptureInfoTy, 8> InitCaptureExprsAndTypes;
|
|
|
|
- InitCaptureExprsAndTypes.resize(E->explicit_capture_end() -
|
|
|
|
- E->explicit_capture_begin());
|
|
|
|
|
|
+ struct TransformedInitCapture {
|
|
|
|
+ // The location of the ... if the result is retaining a pack expansion.
|
|
|
|
+ SourceLocation EllipsisLoc;
|
|
|
|
+ // Zero or more expansions of the init-capture.
|
|
|
|
+ SmallVector<InitCaptureInfoTy, 4> Expansions;
|
|
|
|
+ };
|
|
|
|
+ SmallVector<TransformedInitCapture, 4> InitCaptures;
|
|
|
|
+ InitCaptures.resize(E->explicit_capture_end() - E->explicit_capture_begin());
|
|
for (LambdaExpr::capture_iterator C = E->capture_begin(),
|
|
for (LambdaExpr::capture_iterator C = E->capture_begin(),
|
|
CEnd = E->capture_end();
|
|
CEnd = E->capture_end();
|
|
C != CEnd; ++C) {
|
|
C != CEnd; ++C) {
|
|
if (!E->isInitCapture(C))
|
|
if (!E->isInitCapture(C))
|
|
continue;
|
|
continue;
|
|
- EnterExpressionEvaluationContext EEEC(
|
|
|
|
- getSema(), Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
|
|
|
|
- ExprResult NewExprInitResult = getDerived().TransformInitializer(
|
|
|
|
- C->getCapturedVar()->getInit(),
|
|
|
|
- C->getCapturedVar()->getInitStyle() == VarDecl::CallInit);
|
|
|
|
-
|
|
|
|
- if (NewExprInitResult.isInvalid())
|
|
|
|
- return ExprError();
|
|
|
|
- Expr *NewExprInit = NewExprInitResult.get();
|
|
|
|
|
|
|
|
|
|
+ TransformedInitCapture &Result = InitCaptures[C - E->capture_begin()];
|
|
VarDecl *OldVD = C->getCapturedVar();
|
|
VarDecl *OldVD = C->getCapturedVar();
|
|
- QualType NewInitCaptureType =
|
|
|
|
- getSema().buildLambdaInitCaptureInitialization(
|
|
|
|
- C->getLocation(), OldVD->getType()->isReferenceType(),
|
|
|
|
- OldVD->getIdentifier(),
|
|
|
|
- C->getCapturedVar()->getInitStyle() != VarDecl::CInit, NewExprInit);
|
|
|
|
- NewExprInitResult = NewExprInit;
|
|
|
|
- InitCaptureExprsAndTypes[C - E->capture_begin()] =
|
|
|
|
- std::make_pair(NewExprInitResult, NewInitCaptureType);
|
|
|
|
|
|
+
|
|
|
|
+ auto SubstInitCapture = [&](SourceLocation EllipsisLoc,
|
|
|
|
+ Optional<unsigned> NumExpansions) {
|
|
|
|
+ EnterExpressionEvaluationContext EEEC(
|
|
|
|
+ getSema(), Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
|
|
|
|
+ ExprResult NewExprInitResult = getDerived().TransformInitializer(
|
|
|
|
+ OldVD->getInit(), OldVD->getInitStyle() == VarDecl::CallInit);
|
|
|
|
+
|
|
|
|
+ if (NewExprInitResult.isInvalid()) {
|
|
|
|
+ Result.Expansions.push_back(InitCaptureInfoTy(ExprError(), QualType()));
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ Expr *NewExprInit = NewExprInitResult.get();
|
|
|
|
+
|
|
|
|
+ QualType NewInitCaptureType =
|
|
|
|
+ getSema().buildLambdaInitCaptureInitialization(
|
|
|
|
+ C->getLocation(), OldVD->getType()->isReferenceType(),
|
|
|
|
+ EllipsisLoc, NumExpansions, OldVD->getIdentifier(),
|
|
|
|
+ C->getCapturedVar()->getInitStyle() != VarDecl::CInit,
|
|
|
|
+ NewExprInit);
|
|
|
|
+ Result.Expansions.push_back(
|
|
|
|
+ InitCaptureInfoTy(NewExprInit, NewInitCaptureType));
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ // If this is an init-capture pack, consider expanding the pack now.
|
|
|
|
+ if (OldVD->isParameterPack()) {
|
|
|
|
+ PackExpansionTypeLoc ExpansionTL = OldVD->getTypeSourceInfo()
|
|
|
|
+ ->getTypeLoc()
|
|
|
|
+ .castAs<PackExpansionTypeLoc>();
|
|
|
|
+ SmallVector<UnexpandedParameterPack, 2> Unexpanded;
|
|
|
|
+ SemaRef.collectUnexpandedParameterPacks(OldVD->getInit(), Unexpanded);
|
|
|
|
+
|
|
|
|
+ // Determine whether the set of unexpanded parameter packs can and should
|
|
|
|
+ // be expanded.
|
|
|
|
+ bool Expand = true;
|
|
|
|
+ bool RetainExpansion = false;
|
|
|
|
+ Optional<unsigned> OrigNumExpansions =
|
|
|
|
+ ExpansionTL.getTypePtr()->getNumExpansions();
|
|
|
|
+ Optional<unsigned> NumExpansions = OrigNumExpansions;
|
|
|
|
+ if (getDerived().TryExpandParameterPacks(
|
|
|
|
+ ExpansionTL.getEllipsisLoc(),
|
|
|
|
+ OldVD->getInit()->getSourceRange(), Unexpanded, Expand,
|
|
|
|
+ RetainExpansion, NumExpansions))
|
|
|
|
+ return ExprError();
|
|
|
|
+ if (Expand) {
|
|
|
|
+ for (unsigned I = 0; I != *NumExpansions; ++I) {
|
|
|
|
+ Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
|
|
|
|
+ SubstInitCapture(SourceLocation(), None);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (!Expand || RetainExpansion) {
|
|
|
|
+ ForgetPartiallySubstitutedPackRAII Forget(getDerived());
|
|
|
|
+ SubstInitCapture(ExpansionTL.getEllipsisLoc(), NumExpansions);
|
|
|
|
+ Result.EllipsisLoc = ExpansionTL.getEllipsisLoc();
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ SubstInitCapture(SourceLocation(), None);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
// Transform the template parameters, and add them to the current
|
|
// Transform the template parameters, and add them to the current
|
|
@@ -11245,7 +11294,7 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
|
|
NewCallOpTSI,
|
|
NewCallOpTSI,
|
|
/*KnownDependent=*/false,
|
|
/*KnownDependent=*/false,
|
|
E->getCaptureDefault());
|
|
E->getCaptureDefault());
|
|
- getDerived().transformedLocalDecl(E->getLambdaClass(), Class);
|
|
|
|
|
|
+ getDerived().transformedLocalDecl(E->getLambdaClass(), {Class});
|
|
|
|
|
|
// Build the call operator.
|
|
// Build the call operator.
|
|
CXXMethodDecl *NewCallOperator = getSema().startLambdaDefinition(
|
|
CXXMethodDecl *NewCallOperator = getSema().startLambdaDefinition(
|
|
@@ -11270,7 +11319,7 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
|
|
}
|
|
}
|
|
|
|
|
|
getDerived().transformAttrs(E->getCallOperator(), NewCallOperator);
|
|
getDerived().transformAttrs(E->getCallOperator(), NewCallOperator);
|
|
- getDerived().transformedLocalDecl(E->getCallOperator(), NewCallOperator);
|
|
|
|
|
|
+ getDerived().transformedLocalDecl(E->getCallOperator(), {NewCallOperator});
|
|
|
|
|
|
// Introduce the context of the call operator.
|
|
// Introduce the context of the call operator.
|
|
Sema::ContextRAII SavedContext(getSema(), NewCallOperator,
|
|
Sema::ContextRAII SavedContext(getSema(), NewCallOperator,
|
|
@@ -11313,24 +11362,33 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
|
|
|
|
|
|
// Rebuild init-captures, including the implied field declaration.
|
|
// Rebuild init-captures, including the implied field declaration.
|
|
if (E->isInitCapture(C)) {
|
|
if (E->isInitCapture(C)) {
|
|
- InitCaptureInfoTy InitExprTypePair =
|
|
|
|
- InitCaptureExprsAndTypes[C - E->capture_begin()];
|
|
|
|
- ExprResult Init = InitExprTypePair.first;
|
|
|
|
- QualType InitQualType = InitExprTypePair.second;
|
|
|
|
- if (Init.isInvalid() || InitQualType.isNull()) {
|
|
|
|
- Invalid = true;
|
|
|
|
- continue;
|
|
|
|
- }
|
|
|
|
|
|
+ TransformedInitCapture &NewC = InitCaptures[C - E->capture_begin()];
|
|
|
|
+
|
|
VarDecl *OldVD = C->getCapturedVar();
|
|
VarDecl *OldVD = C->getCapturedVar();
|
|
- VarDecl *NewVD = getSema().createLambdaInitCaptureVarDecl(
|
|
|
|
- OldVD->getLocation(), InitExprTypePair.second, OldVD->getIdentifier(),
|
|
|
|
- OldVD->getInitStyle(), Init.get());
|
|
|
|
- if (!NewVD)
|
|
|
|
- Invalid = true;
|
|
|
|
- else {
|
|
|
|
- getDerived().transformedLocalDecl(OldVD, NewVD);
|
|
|
|
|
|
+ llvm::SmallVector<Decl*, 4> NewVDs;
|
|
|
|
+
|
|
|
|
+ for (InitCaptureInfoTy &Info : NewC.Expansions) {
|
|
|
|
+ ExprResult Init = Info.first;
|
|
|
|
+ QualType InitQualType = Info.second;
|
|
|
|
+ if (Init.isInvalid() || InitQualType.isNull()) {
|
|
|
|
+ Invalid = true;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ VarDecl *NewVD = getSema().createLambdaInitCaptureVarDecl(
|
|
|
|
+ OldVD->getLocation(), InitQualType, NewC.EllipsisLoc,
|
|
|
|
+ OldVD->getIdentifier(), OldVD->getInitStyle(), Init.get());
|
|
|
|
+ if (!NewVD) {
|
|
|
|
+ Invalid = true;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ NewVDs.push_back(NewVD);
|
|
|
|
+ getSema().buildInitCaptureField(LSI, NewVD);
|
|
}
|
|
}
|
|
- getSema().buildInitCaptureField(LSI, NewVD);
|
|
|
|
|
|
+
|
|
|
|
+ if (Invalid)
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ getDerived().transformedLocalDecl(OldVD, NewVDs);
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -12471,8 +12529,7 @@ TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
|
|
VarDecl *oldCapture = I.getVariable();
|
|
VarDecl *oldCapture = I.getVariable();
|
|
|
|
|
|
// Ignore parameter packs.
|
|
// Ignore parameter packs.
|
|
- if (isa<ParmVarDecl>(oldCapture) &&
|
|
|
|
- cast<ParmVarDecl>(oldCapture)->isParameterPack())
|
|
|
|
|
|
+ if (oldCapture->isParameterPack())
|
|
continue;
|
|
continue;
|
|
|
|
|
|
VarDecl *newCapture =
|
|
VarDecl *newCapture =
|