Skip to content

Commit 03608bb

Browse files
committed
introduce emitStmtWithResult
1 parent b226618 commit 03608bb

File tree

1 file changed

+42
-31
lines changed

1 file changed

+42
-31
lines changed

clang/lib/CIR/CodeGen/CIRGenStmt.cpp

Lines changed: 42 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,44 @@ using namespace clang;
2525
using namespace clang::CIRGen;
2626
using namespace cir;
2727

28+
static mlir::LogicalResult emitStmtWithResult(CIRGenFunction &cgf,
29+
const Stmt *exprResult,
30+
AggValueSlot slot,
31+
Address *lastValue) {
32+
// We have to special case labels here. They are statements, but when put
33+
// at the end of a statement expression, they yield the value of their
34+
// subexpression. Handle this by walking through all labels we encounter,
35+
// emitting them before we evaluate the subexpr.
36+
// Similar issues arise for attributed statements.
37+
while (!isa<Expr>(exprResult)) {
38+
if (const auto *ls = dyn_cast<LabelStmt>(exprResult)) {
39+
if (cgf.emitLabel(*ls->getDecl()).failed())
40+
return mlir::failure();
41+
exprResult = ls->getSubStmt();
42+
} else if (const auto *as = dyn_cast<AttributedStmt>(exprResult)) {
43+
// FIXME: Update this if we ever have attributes that affect the
44+
// semantics of an expression.
45+
exprResult = as->getSubStmt();
46+
} else {
47+
llvm_unreachable("Unknown value statement");
48+
}
49+
}
50+
51+
const Expr *e = cast<Expr>(exprResult);
52+
QualType exprTy = e->getType();
53+
if (cgf.hasAggregateEvaluationKind(exprTy)) {
54+
cgf.emitAggExpr(e, slot);
55+
} else {
56+
// We can't return an RValue here because there might be cleanups at
57+
// the end of the StmtExpr. Because of that, we have to emit the result
58+
// here into a temporary alloca.
59+
cgf.emitAnyExprToMem(e, *lastValue, Qualifiers(),
60+
/*IsInit*/ false);
61+
}
62+
63+
return mlir::success();
64+
}
65+
2866
mlir::LogicalResult CIRGenFunction::emitCompoundStmtWithoutScope(
2967
const CompoundStmt &s, Address *lastValue, AggValueSlot slot) {
3068
mlir::LogicalResult result = mlir::success();
@@ -34,37 +72,10 @@ mlir::LogicalResult CIRGenFunction::emitCompoundStmtWithoutScope(
3472
"StmtExprResult");
3573

3674
for (const Stmt *curStmt : s.body()) {
37-
// We have to special case labels here. They are statements, but when put
38-
// at the end of a statement expression, they yield the value of their
39-
// subexpression. Handle this by walking through all labels we encounter,
40-
// emitting them before we evaluate the subexpr.
41-
// Similar issues arise for attributed statements.
42-
if (lastValue && exprResult == curStmt) {
43-
while (!isa<Expr>(exprResult)) {
44-
if (const auto *ls = dyn_cast<LabelStmt>(exprResult)) {
45-
if (emitLabel(*ls->getDecl()).failed())
46-
return mlir::failure();
47-
exprResult = ls->getSubStmt();
48-
} else if (const auto *as = dyn_cast<AttributedStmt>(exprResult)) {
49-
// FIXME: Update this if we ever have attributes that affect the
50-
// semantics of an expression.
51-
exprResult = as->getSubStmt();
52-
} else {
53-
llvm_unreachable("Unknown value statement");
54-
}
55-
}
56-
57-
const Expr *e = cast<Expr>(exprResult);
58-
QualType exprTy = e->getType();
59-
if (hasAggregateEvaluationKind(exprTy)) {
60-
emitAggExpr(e, slot);
61-
} else {
62-
// We can't return an RValue here because there might be cleanups at
63-
// the end of the StmtExpr. Because of that, we have to emit the result
64-
// here into a temporary alloca.
65-
emitAnyExprToMem(e, *lastValue, Qualifiers(),
66-
/*IsInit*/ false);
67-
}
75+
const bool saveResult = lastValue && exprResult == curStmt;
76+
if (saveResult) {
77+
if (emitStmtWithResult(*this, exprResult, slot, lastValue).failed())
78+
result = mlir::failure();
6879
} else {
6980
if (emitStmt(curStmt, /*useCurrentScope=*/false).failed())
7081
result = mlir::failure();

0 commit comments

Comments
 (0)