Skip to content

Commit eac7b11

Browse files
committed
Move unexpanded parameter handling into CapturingScopeInfo
1 parent 9c073cc commit eac7b11

File tree

15 files changed

+110
-66
lines changed

15 files changed

+110
-66
lines changed

clang/include/clang/AST/ComputeDependence.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,8 @@ ExprDependence computeDependence(ArrayInitLoopExpr *E);
132132
ExprDependence computeDependence(ImplicitValueInitExpr *E);
133133
ExprDependence computeDependence(InitListExpr *E);
134134
ExprDependence computeDependence(ExtVectorElementExpr *E);
135-
ExprDependence computeDependence(BlockExpr *E);
135+
ExprDependence computeDependence(BlockExpr *E,
136+
bool ContainsUnexpandedParameterPack);
136137
ExprDependence computeDependence(AsTypeExpr *E);
137138
ExprDependence computeDependence(DeclRefExpr *E, const ASTContext &Ctx);
138139
ExprDependence computeDependence(RecoveryExpr *E);

clang/include/clang/AST/Expr.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6369,9 +6369,9 @@ class BlockExpr : public Expr {
63696369
protected:
63706370
BlockDecl *TheBlock;
63716371
public:
6372-
BlockExpr(BlockDecl *BD, QualType ty)
6372+
BlockExpr(BlockDecl *BD, QualType ty, bool ContainsUnexpandedParameterPack)
63736373
: Expr(BlockExprClass, ty, VK_PRValue, OK_Ordinary), TheBlock(BD) {
6374-
setDependence(computeDependence(this));
6374+
setDependence(computeDependence(this, ContainsUnexpandedParameterPack));
63756375
}
63766376

63776377
/// Build an empty block expression.

clang/include/clang/Sema/ScopeInfo.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -724,10 +724,16 @@ class CapturingScopeInfo : public FunctionScopeInfo {
724724
/// is deduced (e.g. a lambda or block with omitted return type).
725725
bool HasImplicitReturnType = false;
726726

727+
/// Whether this contains an unexpanded parameter pack.
728+
bool ContainsUnexpandedParameterPack = false;
729+
727730
/// ReturnType - The target type of return statements in this context,
728731
/// or null if unknown.
729732
QualType ReturnType;
730733

734+
/// Packs introduced by this, if any.
735+
SmallVector<NamedDecl*, 4> LocalPacks;
736+
731737
void addCapture(ValueDecl *Var, bool isBlock, bool isByref, bool isNested,
732738
SourceLocation Loc, SourceLocation EllipsisLoc,
733739
QualType CaptureType, bool Invalid) {
@@ -895,12 +901,6 @@ class LambdaScopeInfo final :
895901
/// Whether any of the capture expressions requires cleanups.
896902
CleanupInfo Cleanup;
897903

898-
/// Whether the lambda contains an unexpanded parameter pack.
899-
bool ContainsUnexpandedParameterPack = false;
900-
901-
/// Packs introduced by this lambda, if any.
902-
SmallVector<NamedDecl*, 4> LocalPacks;
903-
904904
/// Source range covering the explicit template parameter list (if it exists).
905905
SourceRange ExplicitTemplateParamsRange;
906906

clang/include/clang/Sema/Sema.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -750,10 +750,10 @@ class Sema final : public SemaBase {
750750
/// Retrieve the current block, if any.
751751
sema::BlockScopeInfo *getCurBlock();
752752

753-
/// Get the innermost lambda enclosing the current location, if any. This
754-
/// looks through intervening non-lambda scopes such as local functions and
755-
/// blocks.
756-
sema::LambdaScopeInfo *getEnclosingLambda() const;
753+
/// Get the innermost lambda or block enclosing the current location, if any.
754+
/// This looks through intervening non-lambda, non-block scopes such as local
755+
/// functions.
756+
sema::CapturingScopeInfo *getEnclosingLambdaOrBlock() const;
757757

758758
/// Retrieve the current lambda scope info, if any.
759759
/// \param IgnoreNonLambdaCapturingScope true if should find the top-most

clang/include/clang/Sema/Template.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -411,10 +411,10 @@ enum class TemplateSubstitutionKind : char {
411411
/// lookup will search our outer scope.
412412
bool CombineWithOuterScope;
413413

414-
/// Whether this scope is being used to instantiate a lambda expression,
415-
/// in which case it should be reused for instantiating the lambda's
416-
/// FunctionProtoType.
417-
bool InstantiatingLambda = false;
414+
/// Whether this scope is being used to instantiate a lambda or block
415+
/// expression, in which case it should be reused for instantiating the
416+
/// lambda's FunctionProtoType.
417+
bool InstantiatingLambdaOrBlock = false;
418418

419419
/// If non-NULL, the template parameter pack that has been
420420
/// partially substituted per C++0x [temp.arg.explicit]p9.
@@ -431,10 +431,10 @@ enum class TemplateSubstitutionKind : char {
431431

432432
public:
433433
LocalInstantiationScope(Sema &SemaRef, bool CombineWithOuterScope = false,
434-
bool InstantiatingLambda = false)
434+
bool InstantiatingLambdaOrBlock = false)
435435
: SemaRef(SemaRef), Outer(SemaRef.CurrentInstantiationScope),
436436
CombineWithOuterScope(CombineWithOuterScope),
437-
InstantiatingLambda(InstantiatingLambda) {
437+
InstantiatingLambdaOrBlock(InstantiatingLambdaOrBlock) {
438438
SemaRef.CurrentInstantiationScope = this;
439439
}
440440

@@ -561,8 +561,8 @@ enum class TemplateSubstitutionKind : char {
561561
/// Determine whether D is a pack expansion created in this scope.
562562
bool isLocalPackExpansion(const Decl *D);
563563

564-
/// Determine whether this scope is for instantiating a lambda.
565-
bool isLambda() const { return InstantiatingLambda; }
564+
/// Determine whether this scope is for instantiating a lambda or block.
565+
bool isLambdaOrBlock() const { return InstantiatingLambdaOrBlock; }
566566
};
567567

568568
class TemplateDeclInstantiator

clang/lib/AST/ComputeDependence.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,10 +252,13 @@ ExprDependence clang::computeDependence(ExtVectorElementExpr *E) {
252252
return E->getBase()->getDependence();
253253
}
254254

255-
ExprDependence clang::computeDependence(BlockExpr *E) {
255+
ExprDependence clang::computeDependence(BlockExpr *E,
256+
bool ContainsUnexpandedParameterPack) {
256257
auto D = toExprDependenceForImpliedType(E->getType()->getDependence());
257258
if (E->getBlockDecl()->isDependentContext())
258259
D |= ExprDependence::Instantiation;
260+
if (ContainsUnexpandedParameterPack)
261+
D |= ExprDependence::UnexpandedPack;
259262
return D;
260263
}
261264

clang/lib/Sema/Sema.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2382,18 +2382,19 @@ FunctionScopeInfo *Sema::getEnclosingFunction() const {
23822382
return nullptr;
23832383
}
23842384

2385-
LambdaScopeInfo *Sema::getEnclosingLambda() const {
2385+
CapturingScopeInfo *Sema::getEnclosingLambdaOrBlock() const {
23862386
for (auto *Scope : llvm::reverse(FunctionScopes)) {
2387-
if (auto *LSI = dyn_cast<sema::LambdaScopeInfo>(Scope)) {
2388-
if (LSI->Lambda && !LSI->Lambda->Encloses(CurContext) &&
2387+
if (auto *CSI = dyn_cast<CapturingScopeInfo>(Scope)) {
2388+
auto *LSI = dyn_cast<LambdaScopeInfo>(CSI);
2389+
if (LSI && LSI->Lambda && !LSI->Lambda->Encloses(CurContext) &&
23892390
LSI->AfterParameterList) {
23902391
// We have switched contexts due to template instantiation.
23912392
// FIXME: We should swap out the FunctionScopes during code synthesis
23922393
// so that we don't need to check for this.
23932394
assert(!CodeSynthesisContexts.empty());
23942395
return nullptr;
23952396
}
2396-
return LSI;
2397+
return CSI;
23972398
}
23982399
}
23992400
return nullptr;

clang/lib/Sema/SemaDecl.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15139,8 +15139,8 @@ ParmVarDecl *Sema::CheckParameter(DeclContext *DC, SourceLocation StartLoc,
1513915139
// we know that references to that pack must also be expanded within the
1514015140
// lambda scope.
1514115141
if (New->isParameterPack())
15142-
if (auto *LSI = getEnclosingLambda())
15143-
LSI->LocalPacks.push_back(New);
15142+
if (auto *CSI = getEnclosingLambdaOrBlock())
15143+
CSI->LocalPacks.push_back(New);
1514415144

1514515145
if (New->getType().hasNonTrivialToPrimitiveDestructCUnion() ||
1514615146
New->getType().hasNonTrivialToPrimitiveCopyCUnion())

clang/lib/Sema/SemaExpr.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16356,7 +16356,8 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc,
1635616356
AnalysisBasedWarnings::Policy WP = AnalysisWarnings.getDefaultPolicy();
1635716357
PoppedFunctionScopePtr ScopeRAII = PopFunctionScopeInfo(&WP, BD, BlockTy);
1635816358

16359-
BlockExpr *Result = new (Context) BlockExpr(BD, BlockTy);
16359+
BlockExpr *Result = new (Context)
16360+
BlockExpr(BD, BlockTy, BSI->ContainsUnexpandedParameterPack);
1636016361

1636116362
// If the block isn't obviously global, i.e. it captures anything at
1636216363
// all, then we need to do a few things in the surrounding context:

clang/lib/Sema/SemaLambda.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2350,7 +2350,10 @@ ExprResult Sema::BuildBlockForLambdaConversion(SourceLocation CurrentLocation,
23502350
Block->setBody(new (Context) CompoundStmt(ConvLocation));
23512351

23522352
// Create the block literal expression.
2353-
Expr *BuildBlock = new (Context) BlockExpr(Block, Conv->getConversionType());
2353+
// TODO: Do we ever get here if we have unexpanded packs in the lambda???
2354+
Expr *BuildBlock =
2355+
new (Context) BlockExpr(Block, Conv->getConversionType(),
2356+
/*ContainsUnexpandedParameterPack=*/false);
23542357
ExprCleanupObjects.push_back(Block);
23552358
Cleanup.setExprNeedsCleanups(true);
23562359

0 commit comments

Comments
 (0)