Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions clang/lib/CodeGen/CGDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,12 @@ void CodeGenFunction::EmitDecl(const Decl &D, bool EvaluateConditionDecl) {
// None of these decls require codegen support.
return;

case Decl::CXXExpansionStmt:
llvm_unreachable("TODO");
case Decl::CXXExpansionStmt: {
const auto *ESD = cast<CXXExpansionStmtDecl>(&D);
assert(ESD->getInstantiations() && "expansion statement not expanded?");
EmitStmt(ESD->getInstantiations());
return;
}

case Decl::NamespaceAlias:
if (CGDebugInfo *DI = getDebugInfo())
Expand Down
41 changes: 40 additions & 1 deletion clang/lib/CodeGen/CGStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,8 @@ void CodeGenFunction::EmitStmt(const Stmt *S, ArrayRef<const Attr *> Attrs) {
case Stmt::CXXDependentExpansionStmtPatternClass:
llvm_unreachable("unexpanded expansion statements should not be emitted");
case Stmt::CXXExpansionStmtInstantiationClass:
llvm_unreachable("Todo");
EmitCXXExpansionStmtInstantiation(cast<CXXExpansionStmtInstantiation>(*S));
break;
case Stmt::SEHTryStmtClass:
EmitSEHTryStmt(cast<SEHTryStmt>(*S));
break;
Expand Down Expand Up @@ -1563,6 +1564,44 @@ CodeGenFunction::EmitCXXForRangeStmt(const CXXForRangeStmt &S,
}
}

void CodeGenFunction::EmitCXXExpansionStmtInstantiation(
const CXXExpansionStmtInstantiation &S) {
// FIXME: For reasons beyond my understanding, two scopes are required to emit
// the destructors of lifetime-extended temporaries in the right place, but
// only in some templates. There are some other issues with lifetime-extended
// temporaries currently (https://github.com/llvm/llvm-project/issues/165182);
// perhaps resolving those will allow us to remove the second scope here
// because there really ought to be a better way of doing this.
LexicalScope Scope(*this, S.getSourceRange());
LexicalScope Scope2(*this, S.getSourceRange());

for (const Stmt *DS : S.getSharedStmts())
EmitStmt(DS);

if (S.getInstantiations().empty() || !HaveInsertPoint())
return;

JumpDest ExpandExit = getJumpDestInCurrentScope("expand.end");
JumpDest ContinueDest;
for (auto [N, Inst] : enumerate(S.getInstantiations())) {
if (!HaveInsertPoint()) {
EmitBlock(ExpandExit.getBlock(), true);
return;
}

if (N == S.getInstantiations().size() - 1)
ContinueDest = ExpandExit;
else
ContinueDest = getJumpDestInCurrentScope("expand.next");

LexicalScope ExpansionScope(*this, S.getSourceRange());
BreakContinueStack.push_back(BreakContinue(S, ExpandExit, ContinueDest));
EmitStmt(Inst);
BreakContinueStack.pop_back();
EmitBlock(ContinueDest.getBlock(), true);
}
}

void CodeGenFunction::EmitReturnOfRValue(RValue RV, QualType Ty) {
if (RV.isScalar()) {
Builder.CreateStore(RV.getScalarVal(), ReturnValue);
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/CodeGen/CodeGenFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -3690,6 +3690,9 @@ class CodeGenFunction : public CodeGenTypeCache {
void EmitCXXForRangeStmt(const CXXForRangeStmt &S,
ArrayRef<const Attr *> Attrs = {});

void
EmitCXXExpansionStmtInstantiation(const CXXExpansionStmtInstantiation &S);

/// Controls insertion of cancellation exit blocks in worksharing constructs.
class OMPCancelStackRAII {
CodeGenFunction &CGF;
Expand Down
Loading
Loading