@@ -450,40 +450,69 @@ buildCallLikeOp(CIRGenFunction &CGF, mlir::Location callLoc,
450450 mlir::cir::CallingConv callingConv,
451451 mlir::cir::ExtraFuncAttributesAttr extraFnAttrs) {
452452 auto &builder = CGF.getBuilder ();
453+ auto getOrCreateSurroundingTryOp = [&]() {
454+ // In OG, we build the landing pad for this scope. In CIR, we emit a
455+ // synthetic cir.try because this didn't come from codegenerating from a
456+ // try/catch in C++.
457+ auto op = CGF.currLexScope ->getClosestTryParent ();
458+ if (op)
459+ return op;
460+
461+ op = builder.create <mlir::cir::TryOp>(
462+ *CGF.currSrcLoc , /* scopeBuilder=*/
463+ [&](mlir::OpBuilder &b, mlir::Location loc) {},
464+ // Don't emit the code right away for catch clauses, for
465+ // now create the regions and consume the try scope result.
466+ // Note that clauses are later populated in
467+ // CIRGenFunction::buildLandingPad.
468+ [&](mlir::OpBuilder &b, mlir::Location loc,
469+ mlir::OperationState &result) {
470+ // Since this didn't come from an explicit try, we only need one
471+ // handler: unwind.
472+ auto *r = result.addRegion ();
473+ builder.createBlock (r);
474+ });
475+ op.setSynthetic (true );
476+ return op;
477+ };
453478
454479 if (isInvoke) {
455480 // This call can throw, few options:
456481 // - If this call does not have an associated cir.try, use the
457482 // one provided by InvokeDest,
458483 // - User written try/catch clauses require calls to handle
459484 // exceptions under cir.try.
460- auto *invokeDest = CGF.getInvokeDest ();
461- auto tryOp = dyn_cast_if_present<mlir::cir::TryOp>(invokeDest);
485+ auto tryOp = getOrCreateSurroundingTryOp ();
486+ assert (tryOp && " expected" );
487+
462488 mlir::OpBuilder::InsertPoint ip = builder.saveInsertionPoint ();
463- bool changeInsertion = tryOp && tryOp.getSynthetic ();
464- if (changeInsertion) {
489+ if (tryOp.getSynthetic ()) {
465490 mlir::Block *lastBlock = &tryOp.getTryRegion ().back ();
466491 builder.setInsertionPointToStart (lastBlock);
467492 } else {
468493 assert (builder.getInsertionBlock () && " expected valid basic block" );
469494 }
470495
471- mlir::cir::CallOp tryCallOp ;
496+ mlir::cir::CallOp callOpWithExceptions ;
472497 // TODO(cir): Set calling convention for `cir.try_call`.
473498 assert (callingConv == mlir::cir::CallingConv::C && " NYI" );
474499 if (indirectFuncTy) {
475- tryCallOp = builder.createIndirectTryCallOp (callLoc, indirectFuncVal,
476- indirectFuncTy, CIRCallArgs);
500+ callOpWithExceptions = builder.createIndirectTryCallOp (
501+ callLoc, indirectFuncVal, indirectFuncTy, CIRCallArgs);
477502 } else {
478- tryCallOp = builder.createTryCallOp (callLoc, directFuncOp, CIRCallArgs);
503+ callOpWithExceptions =
504+ builder.createTryCallOp (callLoc, directFuncOp, CIRCallArgs);
479505 }
480- tryCallOp->setAttr (" extra_attrs" , extraFnAttrs);
506+ callOpWithExceptions->setAttr (" extra_attrs" , extraFnAttrs);
507+
508+ auto *invokeDest = CGF.getInvokeDest (tryOp);
509+ (void )invokeDest;
481510
482- if (changeInsertion ) {
511+ if (tryOp. getSynthetic () ) {
483512 builder.create <mlir::cir::YieldOp>(tryOp.getLoc ());
484513 builder.restoreInsertionPoint (ip);
485514 }
486- return tryCallOp ;
515+ return callOpWithExceptions ;
487516 }
488517
489518 assert (builder.getInsertionBlock () && " expected valid basic block" );
@@ -731,7 +760,6 @@ RValue CIRGenFunction::buildCall(const CIRGenFunctionInfo &CallInfo,
731760 noThrowAttr.getMnemonic ()))
732761 CannotThrow = true ;
733762 }
734- // mlir::Operation *InvokeDest = CannotThrow ? nullptr : getInvokeDest();
735763 bool isInvoke = CannotThrow ? false : isInvokeDest ();
736764
737765 // TODO: UnusedReturnSizePtr
0 commit comments