1414#include " CIRGenFunction.h"
1515
1616#include " mlir/IR/Builders.h"
17+ #include " mlir/IR/Location.h"
18+ #include " mlir/Support/LLVM.h"
1719#include " clang/AST/ExprCXX.h"
1820#include " clang/AST/Stmt.h"
1921#include " clang/AST/StmtOpenACC.h"
@@ -23,16 +25,68 @@ using namespace clang;
2325using namespace clang ::CIRGen;
2426using namespace cir ;
2527
26- void CIRGenFunction::emitCompoundStmtWithoutScope (const CompoundStmt &s) {
27- for (auto *curStmt : s.body ()) {
28- if (emitStmt (curStmt, /* useCurrentScope=*/ false ).failed ())
29- getCIRGenModule ().errorNYI (curStmt->getSourceRange (),
30- std::string (" emitCompoundStmtWithoutScope: " ) +
31- curStmt->getStmtClassName ());
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+
66+ mlir::LogicalResult CIRGenFunction::emitCompoundStmtWithoutScope (
67+ const CompoundStmt &s, Address *lastValue, AggValueSlot slot) {
68+ mlir::LogicalResult result = mlir::success ();
69+ const Stmt *exprResult = s.getStmtExprResult ();
70+ assert ((!lastValue || (lastValue && exprResult)) &&
71+ " If lastValue is not null then the CompoundStmt must have a "
72+ " StmtExprResult" );
73+
74+ for (const Stmt *curStmt : s.body ()) {
75+ const bool saveResult = lastValue && exprResult == curStmt;
76+ if (saveResult) {
77+ if (emitStmtWithResult (*this , exprResult, slot, lastValue).failed ())
78+ result = mlir::failure ();
79+ } else {
80+ if (emitStmt (curStmt, /* useCurrentScope=*/ false ).failed ())
81+ result = mlir::failure ();
82+ }
3283 }
84+ return result;
3385}
3486
35- void CIRGenFunction::emitCompoundStmt (const CompoundStmt &s) {
87+ mlir::LogicalResult CIRGenFunction::emitCompoundStmt (const CompoundStmt &s,
88+ Address *lastValue,
89+ AggValueSlot slot) {
3690 // Add local scope to track new declared variables.
3791 SymTableScopeTy varScope (symbolTable);
3892 mlir::Location scopeLoc = getLoc (s.getSourceRange ());
@@ -41,12 +95,10 @@ void CIRGenFunction::emitCompoundStmt(const CompoundStmt &s) {
4195 scopeLoc, [&](mlir::OpBuilder &b, mlir::Type &type, mlir::Location loc) {
4296 scopeInsPt = b.saveInsertionPoint ();
4397 });
44- {
45- mlir::OpBuilder::InsertionGuard guard (builder);
46- builder.restoreInsertionPoint (scopeInsPt);
47- LexicalScope lexScope (*this , scopeLoc, builder.getInsertionBlock ());
48- emitCompoundStmtWithoutScope (s);
49- }
98+ mlir::OpBuilder::InsertionGuard guard (builder);
99+ builder.restoreInsertionPoint (scopeInsPt);
100+ LexicalScope lexScope (*this , scopeLoc, builder.getInsertionBlock ());
101+ return emitCompoundStmtWithoutScope (s, lastValue, slot);
50102}
51103
52104void CIRGenFunction::emitStopPoint (const Stmt *s) {
@@ -249,10 +301,8 @@ mlir::LogicalResult CIRGenFunction::emitSimpleStmt(const Stmt *s,
249301 return emitDeclStmt (cast<DeclStmt>(*s));
250302 case Stmt::CompoundStmtClass:
251303 if (useCurrentScope)
252- emitCompoundStmtWithoutScope (cast<CompoundStmt>(*s));
253- else
254- emitCompoundStmt (cast<CompoundStmt>(*s));
255- break ;
304+ return emitCompoundStmtWithoutScope (cast<CompoundStmt>(*s));
305+ return emitCompoundStmt (cast<CompoundStmt>(*s));
256306 case Stmt::GotoStmtClass:
257307 return emitGotoStmt (cast<GotoStmt>(*s));
258308 case Stmt::ContinueStmtClass:
0 commit comments