diff options
Diffstat (limited to 'clang/lib/CIR/CodeGen/CIRGenStmt.cpp')
| -rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenStmt.cpp | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/clang/lib/CIR/CodeGen/CIRGenStmt.cpp b/clang/lib/CIR/CodeGen/CIRGenStmt.cpp index f116efc20206..e842892d085d 100644 --- a/clang/lib/CIR/CodeGen/CIRGenStmt.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenStmt.cpp @@ -488,8 +488,11 @@ mlir::LogicalResult CIRGenFunction::emitReturnStmt(const ReturnStmt &s) { auto *retBlock = curLexScope->getOrCreateRetBlock(*this, loc); // This should emit a branch through the cleanup block if one exists. builder.create<cir::BrOp>(loc, retBlock); + assert(!cir::MissingFeatures::emitBranchThroughCleanup()); if (ehStack.stable_begin() != currentCleanupStackDepth) cgm.errorNYI(s.getSourceRange(), "return with cleanup stack"); + + // Insert the new block to continue codegen after branch to ret block. builder.createBlock(builder.getBlock()->getParent()); return mlir::success(); @@ -1041,3 +1044,21 @@ mlir::LogicalResult CIRGenFunction::emitSwitchStmt(const clang::SwitchStmt &s) { return res; } + +void CIRGenFunction::emitReturnOfRValue(mlir::Location loc, RValue rv, + QualType ty) { + if (rv.isScalar()) { + builder.createStore(loc, rv.getValue(), returnValue); + } else if (rv.isAggregate()) { + LValue dest = makeAddrLValue(returnValue, ty); + LValue src = makeAddrLValue(rv.getAggregateAddress(), ty); + emitAggregateCopy(dest, src, ty, getOverlapForReturnValue()); + } else { + cgm.errorNYI(loc, "emitReturnOfRValue: complex return type"); + } + mlir::Block *retBlock = curLexScope->getOrCreateRetBlock(*this, loc); + assert(!cir::MissingFeatures::emitBranchThroughCleanup()); + builder.create<cir::BrOp>(loc, retBlock); + if (ehStack.stable_begin() != currentCleanupStackDepth) + cgm.errorNYI(loc, "return with cleanup stack"); +} |
