@@ -2317,7 +2317,6 @@ struct CallEndCatch final : EHScopeStack::Cleanup {
23172317
23182318static mlir::Value callBeginCatch (CIRGenFunction &cgf, mlir::Type paramTy,
23192319 bool endMightThrow) {
2320-
23212320 auto catchParam = cir::CatchParamOp::create (
23222321 cgf.getBuilder (), cgf.getBuilder ().getUnknownLoc (), paramTy);
23232322
@@ -2328,6 +2327,56 @@ static mlir::Value callBeginCatch(CIRGenFunction &cgf, mlir::Type paramTy,
23282327 return catchParam.getParam ();
23292328}
23302329
2330+ // / A "special initializer" callback for initializing a catch
2331+ // / parameter during catch initialization.
2332+ static void initCatchParam (CIRGenFunction &cgf, const VarDecl &catchParam,
2333+ Address paramAddr, SourceLocation loc) {
2334+ CanQualType catchType =
2335+ cgf.cgm .getASTContext ().getCanonicalType (catchParam.getType ());
2336+ // If we're catching by reference, we can just cast the object
2337+ // pointer to the appropriate pointer.
2338+ if (isa<ReferenceType>(catchType)) {
2339+ cgf.cgm .errorNYI (loc, " initCatchParam: ReferenceType" );
2340+ return ;
2341+ }
2342+
2343+ // Scalars and complexes.
2344+ cir::TypeEvaluationKind tek = cgf.getEvaluationKind (catchType);
2345+ if (tek != cir::TEK_Aggregate) {
2346+ // Notes for LLVM lowering:
2347+ // If the catch type is a pointer type, __cxa_begin_catch returns
2348+ // the pointer by value.
2349+ if (catchType->hasPointerRepresentation ()) {
2350+ cgf.cgm .errorNYI (loc, " initCatchParam: hasPointerRepresentation" );
2351+ return ;
2352+ }
2353+
2354+ mlir::Type cirCatchTy = cgf.convertTypeForMem (catchType);
2355+ mlir::Value catchParam =
2356+ callBeginCatch (cgf, cgf.getBuilder ().getPointerTo (cirCatchTy), false );
2357+ LValue srcLV = cgf.makeNaturalAlignAddrLValue (catchParam, catchType);
2358+ LValue destLV = cgf.makeAddrLValue (paramAddr, catchType);
2359+ switch (tek) {
2360+ case cir::TEK_Complex: {
2361+ cgf.cgm .errorNYI (loc, " initCatchParam: cir::TEK_Complex" );
2362+ return ;
2363+ }
2364+ case cir::TEK_Scalar: {
2365+ auto exnLoad = cgf.emitLoadOfScalar (srcLV, loc);
2366+ cgf.emitStoreOfScalar (exnLoad, destLV, /* isInit=*/ true );
2367+ return ;
2368+ }
2369+ case cir::TEK_Aggregate:
2370+ llvm_unreachable (" evaluation kind filtered out!" );
2371+ }
2372+
2373+ // Otherwise, it returns a pointer into the exception object.
2374+ llvm_unreachable (" bad evaluation kind" );
2375+ }
2376+
2377+ cgf.cgm .errorNYI (loc, " initCatchParam: cir::TEK_Aggregate" );
2378+ }
2379+
23312380// / Begins a catch statement by initializing the catch variable and
23322381// / calling __cxa_begin_catch.
23332382void CIRGenItaniumCXXABI::emitBeginCatch (CIRGenFunction &cgf,
@@ -2362,5 +2411,28 @@ void CIRGenItaniumCXXABI::emitBeginCatch(CIRGenFunction &cgf,
23622411 return ;
23632412 }
23642413
2365- cgf.cgm .errorNYI (" emitBeginCatch: catch with exception decl" );
2414+ auto getCatchParamAllocaIP = [&]() {
2415+ auto currIns = cgf.getBuilder ().saveInsertionPoint ();
2416+ mlir::Operation *currParent = currIns.getBlock ()->getParentOp ();
2417+
2418+ mlir::Block *insertBlock = nullptr ;
2419+ if (auto scopeOp = currParent->getParentOfType <cir::ScopeOp>()) {
2420+ insertBlock = &scopeOp.getScopeRegion ().getBlocks ().back ();
2421+ } else if (auto fnOp = currParent->getParentOfType <cir::FuncOp>()) {
2422+ insertBlock = &fnOp.getRegion ().getBlocks ().back ();
2423+ } else {
2424+ llvm_unreachable (" unknown outermost scope-like parent" );
2425+ }
2426+ return cgf.getBuilder ().getBestAllocaInsertPoint (insertBlock);
2427+ };
2428+
2429+ // Emit the local. Make sure the alloca's superseed the current scope, since
2430+ // these are going to be consumed by `cir.catch`, which is not within the
2431+ // current scope.
2432+
2433+ CIRGenFunction::AutoVarEmission var =
2434+ cgf.emitAutoVarAlloca (*catchParam, getCatchParamAllocaIP ());
2435+ initCatchParam (cgf, *catchParam, var.getObjectAddress (cgf),
2436+ catchStmt->getBeginLoc ());
2437+ cgf.emitAutoVarCleanups (var);
23662438}
0 commit comments