Skip to content

Commit c93a279

Browse files
committed
[Clang] [C++26] Expansion Statements (Part 8)
1 parent d3761e5 commit c93a279

File tree

7 files changed

+3149
-0
lines changed

7 files changed

+3149
-0
lines changed

clang/lib/CodeGen/CGStmt.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,14 @@ void CodeGenFunction::EmitStmt(const Stmt *S, ArrayRef<const Attr *> Attrs) {
204204
case Stmt::CXXForRangeStmtClass:
205205
EmitCXXForRangeStmt(cast<CXXForRangeStmt>(*S), Attrs);
206206
break;
207+
case Stmt::CXXEnumeratingExpansionStmtPatternClass:
208+
case Stmt::CXXIteratingExpansionStmtPatternClass:
209+
case Stmt::CXXDestructuringExpansionStmtPatternClass:
210+
case Stmt::CXXDependentExpansionStmtPatternClass:
211+
llvm_unreachable("unexpanded expansion statements should not be emitted");
212+
case Stmt::CXXExpansionStmtInstantiationClass:
213+
EmitCXXExpansionStmtInstantiation(cast<CXXExpansionStmtInstantiation>(*S));
214+
break;
207215
case Stmt::SEHTryStmtClass:
208216
EmitSEHTryStmt(cast<SEHTryStmt>(*S));
209217
break;
@@ -1556,6 +1564,44 @@ CodeGenFunction::EmitCXXForRangeStmt(const CXXForRangeStmt &S,
15561564
}
15571565
}
15581566

1567+
void CodeGenFunction::EmitCXXExpansionStmtInstantiation(
1568+
const CXXExpansionStmtInstantiation &S) {
1569+
// FIXME: For reasons beyond my understanding, two scopes are required to emit
1570+
// the destructors of lifetime-extended temporaries in the right place, but
1571+
// only in some templates. There are some other issues with lifetime-extended
1572+
// temporaries currently (https://github.com/llvm/llvm-project/issues/165182);
1573+
// perhaps resolving those will allow us to remove the second scope here
1574+
// because there really ought to be a better way of doing this.
1575+
LexicalScope Scope(*this, S.getSourceRange());
1576+
LexicalScope Scope2(*this, S.getSourceRange());
1577+
1578+
for (const Stmt *DS : S.getSharedStmts())
1579+
EmitStmt(DS);
1580+
1581+
if (S.getInstantiations().empty() || !HaveInsertPoint())
1582+
return;
1583+
1584+
JumpDest ExpandExit = getJumpDestInCurrentScope("expand.end");
1585+
JumpDest ContinueDest;
1586+
for (auto [N, Inst] : enumerate(S.getInstantiations())) {
1587+
if (!HaveInsertPoint()) {
1588+
EmitBlock(ExpandExit.getBlock(), true);
1589+
return;
1590+
}
1591+
1592+
if (N == S.getInstantiations().size() - 1)
1593+
ContinueDest = ExpandExit;
1594+
else
1595+
ContinueDest = getJumpDestInCurrentScope("expand.next");
1596+
1597+
LexicalScope ExpansionScope(*this, S.getSourceRange());
1598+
BreakContinueStack.push_back(BreakContinue(S, ExpandExit, ContinueDest));
1599+
EmitStmt(Inst);
1600+
BreakContinueStack.pop_back();
1601+
EmitBlock(ContinueDest.getBlock(), true);
1602+
}
1603+
}
1604+
15591605
void CodeGenFunction::EmitReturnOfRValue(RValue RV, QualType Ty) {
15601606
if (RV.isScalar()) {
15611607
Builder.CreateStore(RV.getScalarVal(), ReturnValue);

clang/lib/CodeGen/CodeGenFunction.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3690,6 +3690,9 @@ class CodeGenFunction : public CodeGenTypeCache {
36903690
void EmitCXXForRangeStmt(const CXXForRangeStmt &S,
36913691
ArrayRef<const Attr *> Attrs = {});
36923692

3693+
void
3694+
EmitCXXExpansionStmtInstantiation(const CXXExpansionStmtInstantiation &S);
3695+
36933696
/// Controls insertion of cancellation exit blocks in worksharing constructs.
36943697
class OMPCancelStackRAII {
36953698
CodeGenFunction &CGF;

0 commit comments

Comments
 (0)