Skip to content

Commit d4b162c

Browse files
committed
Add support for CatchParamOp
1 parent 02ffa41 commit d4b162c

File tree

4 files changed

+75
-6
lines changed

4 files changed

+75
-6
lines changed

clang/include/clang/CIR/MissingFeatures.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,6 @@ struct MissingFeatures {
376376
static bool tryOp() { return false; }
377377
static bool vecTernaryOp() { return false; }
378378
static bool zextOp() { return false; }
379-
static bool catchParamOp() { return false; }
380379

381380
// Future CIR attributes
382381
static bool optInfoAttr() { return false; }

clang/lib/CIR/CodeGen/CIRGenException.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -524,9 +524,6 @@ void CIRGenFunction::exitCXXTryStmt(const CXXTryStmt &s, bool isFnTryBlock) {
524524
emitStmt(catchStmt->getHandlerBlock(), /*useCurrentScope=*/true);
525525
assert(emitResult.succeeded() && "failed to emit catch handler block");
526526

527-
assert(!cir::MissingFeatures::catchParamOp());
528-
cir::YieldOp::create(builder, tryOp->getLoc());
529-
530527
// [except.handle]p11:
531528
// The currently handled exception is rethrown if control
532529
// reaches the end of a handler of the function-try-block of a

clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp

Lines changed: 74 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2317,7 +2317,6 @@ struct CallEndCatch final : EHScopeStack::Cleanup {
23172317

23182318
static 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.
23332382
void 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
}

clang/test/CIR/CodeGen/try-catch-tmp.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ void call_function_inside_try_catch_with_exception_type() {
5656
// CIR: %[[CALL:.*]] = cir.call @_Z8divisionv() : () -> !s32i
5757
// CIR: cir.yield
5858
// CIR: } catch [type #cir.global_view<@_ZTIi> : !cir.ptr<!u8i>] {
59+
// CIR: %[[CATCH_PARAM:.*]] = cir.catch_param : !cir.ptr<!s32i>
5960
// CIR: cir.yield
6061
// CIR: } unwind {
6162
// CIR: cir.resume

0 commit comments

Comments
 (0)