@@ -25,6 +25,44 @@ using namespace clang;
25
25
using namespace clang ::CIRGen;
26
26
using namespace cir ;
27
27
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
+
28
66
mlir::LogicalResult CIRGenFunction::emitCompoundStmtWithoutScope (
29
67
const CompoundStmt &s, Address *lastValue, AggValueSlot slot) {
30
68
mlir::LogicalResult result = mlir::success ();
@@ -34,37 +72,10 @@ mlir::LogicalResult CIRGenFunction::emitCompoundStmtWithoutScope(
34
72
" StmtExprResult" );
35
73
36
74
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 ();
68
79
} else {
69
80
if (emitStmt (curStmt, /* useCurrentScope=*/ false ).failed ())
70
81
result = mlir::failure ();
0 commit comments