@@ -465,12 +465,48 @@ static cir::CIRCallOpInterface
465465emitCallLikeOp (CIRGenFunction &cgf, mlir::Location callLoc,
466466 cir::FuncType indirectFuncTy, mlir::Value indirectFuncVal,
467467 cir::FuncOp directFuncOp,
468- const SmallVectorImpl<mlir::Value> &cirCallArgs,
468+ const SmallVectorImpl<mlir::Value> &cirCallArgs, bool isInvoke,
469469 const mlir::NamedAttrList &attrs) {
470470 CIRGenBuilderTy &builder = cgf.getBuilder ();
471471
472472 assert (!cir::MissingFeatures::opCallSurroundingTry ());
473- assert (!cir::MissingFeatures::invokeOp ());
473+
474+ if (isInvoke) {
475+ // This call can throw, few options:
476+ // - If this call does not have an associated cir.try, use the
477+ // one provided by InvokeDest,
478+ // - User written try/catch clauses require calls to handle
479+ // exceptions under cir.try.
480+
481+ // In OG, we build the landing pad for this scope. In CIR, we emit a
482+ // synthetic cir.try because this didn't come from code generating from a
483+ // try/catch in C++.
484+ assert (cgf.curLexScope && " expected scope" );
485+ cir::TryOp tryOp = cgf.curLexScope ->getClosestTryParent ();
486+ if (!tryOp) {
487+ cgf.cgm .errorNYI (
488+ " emitCallLikeOp: call does not have an associated cir.try" );
489+ return {};
490+ }
491+
492+ if (tryOp.getSynthetic ()) {
493+ cgf.cgm .errorNYI (" emitCallLikeOp: tryOp synthetic" );
494+ return {};
495+ }
496+
497+ cir::CallOp callOpWithExceptions;
498+ if (indirectFuncTy) {
499+ cgf.cgm .errorNYI (" emitCallLikeOp: indirect function type" );
500+ return {};
501+ }
502+
503+ callOpWithExceptions =
504+ builder.createTryCallOp (callLoc, directFuncOp, cirCallArgs);
505+
506+ (void )cgf.getInvokeDest (tryOp);
507+
508+ return callOpWithExceptions;
509+ }
474510
475511 assert (builder.getInsertionBlock () && " expected valid basic block" );
476512
@@ -628,10 +664,16 @@ RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo &funcInfo,
628664 indirectFuncVal = calleePtr->getResult (0 );
629665 }
630666
667+ // TODO(cir): currentFunctionUsesSEHTry
668+ // TODO(cir): check for MSVCXXPersonality
669+ // TODO(cir): Create NoThrowAttr
670+ bool cannotThrow = attrs.getNamed (" nothrow" ).has_value ();
671+ bool isInvoke = !cannotThrow && isInvokeDest ();
672+
631673 mlir::Location callLoc = loc;
632674 cir::CIRCallOpInterface theCall =
633675 emitCallLikeOp (*this , loc, indirectFuncTy, indirectFuncVal, directFuncOp,
634- cirCallArgs, attrs);
676+ cirCallArgs, isInvoke, attrs);
635677
636678 if (callOp)
637679 *callOp = theCall;
0 commit comments