-
Notifications
You must be signed in to change notification settings - Fork 15.4k
[CIR] Emit CatchParamOp in the catch region #171169
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
[CIR] Emit CatchParamOp in the catch region #171169
Conversation
|
@llvm/pr-subscribers-clangir Author: Amr Hesham (AmrDeveloper) ChangesEmit structured CatchParamOp in the catch region Issue #154992 Full diff: https://github.com/llvm/llvm-project/pull/171169.diff 5 Files Affected:
diff --git a/clang/lib/CIR/CodeGen/CIRGenCXXABI.h b/clang/lib/CIR/CodeGen/CIRGenCXXABI.h
index 57b1a1f20aa17..b96d656b91e62 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCXXABI.h
+++ b/clang/lib/CIR/CodeGen/CIRGenCXXABI.h
@@ -126,6 +126,9 @@ class CIRGenCXXABI {
virtual void emitBadCastCall(CIRGenFunction &cgf, mlir::Location loc) = 0;
+ virtual void emitBeginCatch(CIRGenFunction &cgf,
+ const CXXCatchStmt *catchStmt) = 0;
+
virtual mlir::Attribute getAddrOfRTTIDescriptor(mlir::Location loc,
QualType ty) = 0;
diff --git a/clang/lib/CIR/CodeGen/CIRGenException.cpp b/clang/lib/CIR/CodeGen/CIRGenException.cpp
index 375828421eb1b..3fbf8953531e5 100644
--- a/clang/lib/CIR/CodeGen/CIRGenException.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenException.cpp
@@ -419,7 +419,8 @@ void CIRGenFunction::exitCXXTryStmt(const CXXTryStmt &s, bool isFnTryBlock) {
RunCleanupsScope catchScope(*this);
// Initialize the catch variable and set up the cleanups.
- assert(!cir::MissingFeatures::catchParamOp());
+ SaveAndRestore restoreCurrentFuncletPad(currentFuncletPad);
+ cgm.getCXXABI().emitBeginCatch(*this, catchStmt);
// Emit the PGO counter increment.
assert(!cir::MissingFeatures::incrementProfileCounter());
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index 0df812bcfb94e..b5879f9945f22 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -1231,6 +1231,7 @@ class CIRGenFunction : public CIRGenTypeCache {
};
LexicalScope *curLexScope = nullptr;
+ mlir::Operation *currentFuncletPad = nullptr;
typedef void Destroyer(CIRGenFunction &cgf, Address addr, QualType ty);
diff --git a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
index 7e145f2c57ce6..95ad50135b587 100644
--- a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
@@ -81,6 +81,9 @@ class CIRGenItaniumCXXABI : public CIRGenCXXABI {
void emitRethrow(CIRGenFunction &cgf, bool isNoReturn) override;
void emitThrow(CIRGenFunction &cgf, const CXXThrowExpr *e) override;
+ void emitBeginCatch(CIRGenFunction &cgf,
+ const CXXCatchStmt *catchStmt) override;
+
bool useThunkForDtorVariant(const CXXDestructorDecl *dtor,
CXXDtorType dt) const override {
// Itanium does not emit any destructor variant as an inline thunk.
@@ -2266,3 +2269,163 @@ Address CIRGenItaniumCXXABI::initializeArrayCookie(CIRGenFunction &cgf,
CharUnits finalAlignment = baseAlignment.alignmentAtOffset(cookieSize);
return Address(finalPtr, newPtr.getElementType(), finalAlignment);
}
+
+namespace {
+/// From traditional LLVM, useful info for LLVM lowering support:
+/// A cleanup to call __cxa_end_catch. In many cases, the caught
+/// exception type lets us state definitively that the thrown exception
+/// type does not have a destructor. In particular:
+/// - Catch-alls tell us nothing, so we have to conservatively
+/// assume that the thrown exception might have a destructor.
+/// - Catches by reference behave according to their base types.
+/// - Catches of non-record types will only trigger for exceptions
+/// of non-record types, which never have destructors.
+/// - Catches of record types can trigger for arbitrary subclasses
+/// of the caught type, so we have to assume the actual thrown
+/// exception type might have a throwing destructor, even if the
+/// caught type's destructor is trivial or nothrow.
+struct CallEndCatch final : EHScopeStack::Cleanup {
+ CallEndCatch(bool mightThrow) : mightThrow(mightThrow) {}
+ bool mightThrow;
+
+ void emit(CIRGenFunction &cgf, Flags flags) override {
+ if (!mightThrow) {
+ // Traditional LLVM codegen would emit a call to __cxa_end_catch
+ // here. For CIR, just let it pass since the cleanup is going
+ // to be emitted on a later pass when lowering the catch region.
+ // CGF.EmitNounwindRuntimeCall(getEndCatchFn(CGF.CGM));
+ cir::YieldOp::create(cgf.getBuilder(), *cgf.currSrcLoc);
+ return;
+ }
+
+ // Traditional LLVM codegen would emit a call to __cxa_end_catch
+ // here. For CIR, just let it pass since the cleanup is going
+ // to be emitted on a later pass when lowering the catch region.
+ // CGF.EmitRuntimeCallOrTryCall(getEndCatchFn(CGF.CGM));
+ if (!cgf.getBuilder().getBlock()->mightHaveTerminator())
+ cir::YieldOp::create(cgf.getBuilder(), *cgf.currSrcLoc);
+ }
+};
+} // namespace
+
+static mlir::Value callBeginCatch(CIRGenFunction &cgf, mlir::Type paramTy,
+ bool endMightThrow) {
+
+ auto catchParam = cir::CatchParamOp::create(
+ cgf.getBuilder(), cgf.getBuilder().getUnknownLoc(), paramTy);
+
+ cgf.ehStack.pushCleanup<CallEndCatch>(
+ NormalAndEHCleanup,
+ endMightThrow && !cgf.cgm.getLangOpts().AssumeNothrowExceptionDtor);
+
+ return catchParam.getParam();
+}
+
+/// A "special initializer" callback for initializing a catch
+/// parameter during catch initialization.
+static void initCatchParam(CIRGenFunction &cgf, const VarDecl &catchParam,
+ Address paramAddr, SourceLocation loc) {
+ CanQualType catchType =
+ cgf.cgm.getASTContext().getCanonicalType(catchParam.getType());
+ // If we're catching by reference, we can just cast the object
+ // pointer to the appropriate pointer.
+ if (isa<ReferenceType>(catchType)) {
+ cgf.cgm.errorNYI(loc, "initCatchParam: ReferenceType");
+ return;
+ }
+
+ // Scalars and complexes.
+ cir::TypeEvaluationKind tek = cgf.getEvaluationKind(catchType);
+ if (tek != cir::TEK_Aggregate) {
+ // Notes for LLVM lowering:
+ // If the catch type is a pointer type, __cxa_begin_catch returns
+ // the pointer by value.
+ if (catchType->hasPointerRepresentation()) {
+ cgf.cgm.errorNYI(loc, "initCatchParam: hasPointerRepresentation");
+ return;
+ }
+
+ mlir::Type cirCatchTy = cgf.convertTypeForMem(catchType);
+ mlir::Value catchParam =
+ callBeginCatch(cgf, cgf.getBuilder().getPointerTo(cirCatchTy), false);
+ LValue srcLV = cgf.makeNaturalAlignAddrLValue(catchParam, catchType);
+ LValue destLV = cgf.makeAddrLValue(paramAddr, catchType);
+ switch (tek) {
+ case cir::TEK_Complex: {
+ cgf.cgm.errorNYI(loc, "initCatchParam: cir::TEK_Complex");
+ return;
+ }
+ case cir::TEK_Scalar: {
+ auto exnLoad = cgf.emitLoadOfScalar(srcLV, loc);
+ cgf.emitStoreOfScalar(exnLoad, destLV, /*isInit=*/true);
+ return;
+ }
+ case cir::TEK_Aggregate:
+ llvm_unreachable("evaluation kind filtered out!");
+ }
+
+ // Otherwise, it returns a pointer into the exception object.
+ llvm_unreachable("bad evaluation kind");
+ }
+
+ cgf.cgm.errorNYI(loc, "initCatchParam: cir::TEK_Aggregate");
+}
+
+/// Begins a catch statement by initializing the catch variable and
+/// calling __cxa_begin_catch.
+void CIRGenItaniumCXXABI::emitBeginCatch(CIRGenFunction &cgf,
+ const CXXCatchStmt *catchStmt) {
+ // We have to be very careful with the ordering of cleanups here:
+ // C++ [except.throw]p4:
+ // The destruction [of the exception temporary] occurs
+ // immediately after the destruction of the object declared in
+ // the exception-declaration in the handler.
+ //
+ // So the precise ordering is:
+ // 1. Construct catch variable.
+ // 2. __cxa_begin_catch
+ // 3. Enter __cxa_end_catch cleanup
+ // 4. Enter dtor cleanup
+ //
+ // We do this by using a slightly abnormal initialization process.
+ // Delegation sequence:
+ // - ExitCXXTryStmt opens a RunCleanupsScope
+ // - EmitAutoVarAlloca creates the variable and debug info
+ // - InitCatchParam initializes the variable from the exception
+ // - CallBeginCatch calls __cxa_begin_catch
+ // - CallBeginCatch enters the __cxa_end_catch cleanup
+ // - EmitAutoVarCleanups enters the variable destructor cleanup
+ // - EmitCXXTryStmt emits the code for the catch body
+ // - EmitCXXTryStmt close the RunCleanupsScope
+
+ VarDecl *catchParam = catchStmt->getExceptionDecl();
+ if (!catchParam) {
+ callBeginCatch(cgf, cgf.getBuilder().getVoidPtrTy(),
+ /*endMightThrow=*/true);
+ return;
+ }
+
+ auto getCatchParamAllocaIP = [&]() {
+ auto currIns = cgf.getBuilder().saveInsertionPoint();
+ mlir::Operation *currParent = currIns.getBlock()->getParentOp();
+
+ mlir::Block *insertBlock = nullptr;
+ if (auto scopeOp = currParent->getParentOfType<cir::ScopeOp>()) {
+ insertBlock = &scopeOp.getScopeRegion().getBlocks().back();
+ } else if (auto fnOp = currParent->getParentOfType<cir::FuncOp>()) {
+ insertBlock = &fnOp.getRegion().getBlocks().back();
+ } else {
+ llvm_unreachable("unknown outermost scope-like parent");
+ }
+ return cgf.getBuilder().getBestAllocaInsertPoint(insertBlock);
+ };
+
+ // Emit the local. Make sure the alloca's superseed the current scope, since
+ // these are going to be consumed by `cir.catch`, which is not within the
+ // current scope.
+ CIRGenFunction::AutoVarEmission var =
+ cgf.emitAutoVarAlloca(*catchParam, getCatchParamAllocaIP());
+ initCatchParam(cgf, *catchParam, var.getObjectAddress(cgf),
+ catchStmt->getBeginLoc());
+ cgf.emitAutoVarCleanups(var);
+}
diff --git a/clang/test/CIR/CodeGen/try-catch-tmp.cpp b/clang/test/CIR/CodeGen/try-catch-tmp.cpp
index 078447f844d9a..baf5d102a8b74 100644
--- a/clang/test/CIR/CodeGen/try-catch-tmp.cpp
+++ b/clang/test/CIR/CodeGen/try-catch-tmp.cpp
@@ -17,6 +17,7 @@ void calling_division_inside_try_block() {
// CIR: %[[CALL:.*]] = cir.call @_Z8divisionv() : () -> !s32i
// CIR: cir.yield
// CIR: } catch all {
+// CIR: %[[CATCH_PARAM:.*]] = cir.catch_param : !cir.ptr<!void>
// CIR: cir.yield
// CIR: }
// CIR: }
|
|
@llvm/pr-subscribers-clang Author: Amr Hesham (AmrDeveloper) ChangesEmit structured CatchParamOp in the catch region Issue #154992 Full diff: https://github.com/llvm/llvm-project/pull/171169.diff 5 Files Affected:
diff --git a/clang/lib/CIR/CodeGen/CIRGenCXXABI.h b/clang/lib/CIR/CodeGen/CIRGenCXXABI.h
index 57b1a1f20aa17..b96d656b91e62 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCXXABI.h
+++ b/clang/lib/CIR/CodeGen/CIRGenCXXABI.h
@@ -126,6 +126,9 @@ class CIRGenCXXABI {
virtual void emitBadCastCall(CIRGenFunction &cgf, mlir::Location loc) = 0;
+ virtual void emitBeginCatch(CIRGenFunction &cgf,
+ const CXXCatchStmt *catchStmt) = 0;
+
virtual mlir::Attribute getAddrOfRTTIDescriptor(mlir::Location loc,
QualType ty) = 0;
diff --git a/clang/lib/CIR/CodeGen/CIRGenException.cpp b/clang/lib/CIR/CodeGen/CIRGenException.cpp
index 375828421eb1b..3fbf8953531e5 100644
--- a/clang/lib/CIR/CodeGen/CIRGenException.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenException.cpp
@@ -419,7 +419,8 @@ void CIRGenFunction::exitCXXTryStmt(const CXXTryStmt &s, bool isFnTryBlock) {
RunCleanupsScope catchScope(*this);
// Initialize the catch variable and set up the cleanups.
- assert(!cir::MissingFeatures::catchParamOp());
+ SaveAndRestore restoreCurrentFuncletPad(currentFuncletPad);
+ cgm.getCXXABI().emitBeginCatch(*this, catchStmt);
// Emit the PGO counter increment.
assert(!cir::MissingFeatures::incrementProfileCounter());
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index 0df812bcfb94e..b5879f9945f22 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -1231,6 +1231,7 @@ class CIRGenFunction : public CIRGenTypeCache {
};
LexicalScope *curLexScope = nullptr;
+ mlir::Operation *currentFuncletPad = nullptr;
typedef void Destroyer(CIRGenFunction &cgf, Address addr, QualType ty);
diff --git a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
index 7e145f2c57ce6..95ad50135b587 100644
--- a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
@@ -81,6 +81,9 @@ class CIRGenItaniumCXXABI : public CIRGenCXXABI {
void emitRethrow(CIRGenFunction &cgf, bool isNoReturn) override;
void emitThrow(CIRGenFunction &cgf, const CXXThrowExpr *e) override;
+ void emitBeginCatch(CIRGenFunction &cgf,
+ const CXXCatchStmt *catchStmt) override;
+
bool useThunkForDtorVariant(const CXXDestructorDecl *dtor,
CXXDtorType dt) const override {
// Itanium does not emit any destructor variant as an inline thunk.
@@ -2266,3 +2269,163 @@ Address CIRGenItaniumCXXABI::initializeArrayCookie(CIRGenFunction &cgf,
CharUnits finalAlignment = baseAlignment.alignmentAtOffset(cookieSize);
return Address(finalPtr, newPtr.getElementType(), finalAlignment);
}
+
+namespace {
+/// From traditional LLVM, useful info for LLVM lowering support:
+/// A cleanup to call __cxa_end_catch. In many cases, the caught
+/// exception type lets us state definitively that the thrown exception
+/// type does not have a destructor. In particular:
+/// - Catch-alls tell us nothing, so we have to conservatively
+/// assume that the thrown exception might have a destructor.
+/// - Catches by reference behave according to their base types.
+/// - Catches of non-record types will only trigger for exceptions
+/// of non-record types, which never have destructors.
+/// - Catches of record types can trigger for arbitrary subclasses
+/// of the caught type, so we have to assume the actual thrown
+/// exception type might have a throwing destructor, even if the
+/// caught type's destructor is trivial or nothrow.
+struct CallEndCatch final : EHScopeStack::Cleanup {
+ CallEndCatch(bool mightThrow) : mightThrow(mightThrow) {}
+ bool mightThrow;
+
+ void emit(CIRGenFunction &cgf, Flags flags) override {
+ if (!mightThrow) {
+ // Traditional LLVM codegen would emit a call to __cxa_end_catch
+ // here. For CIR, just let it pass since the cleanup is going
+ // to be emitted on a later pass when lowering the catch region.
+ // CGF.EmitNounwindRuntimeCall(getEndCatchFn(CGF.CGM));
+ cir::YieldOp::create(cgf.getBuilder(), *cgf.currSrcLoc);
+ return;
+ }
+
+ // Traditional LLVM codegen would emit a call to __cxa_end_catch
+ // here. For CIR, just let it pass since the cleanup is going
+ // to be emitted on a later pass when lowering the catch region.
+ // CGF.EmitRuntimeCallOrTryCall(getEndCatchFn(CGF.CGM));
+ if (!cgf.getBuilder().getBlock()->mightHaveTerminator())
+ cir::YieldOp::create(cgf.getBuilder(), *cgf.currSrcLoc);
+ }
+};
+} // namespace
+
+static mlir::Value callBeginCatch(CIRGenFunction &cgf, mlir::Type paramTy,
+ bool endMightThrow) {
+
+ auto catchParam = cir::CatchParamOp::create(
+ cgf.getBuilder(), cgf.getBuilder().getUnknownLoc(), paramTy);
+
+ cgf.ehStack.pushCleanup<CallEndCatch>(
+ NormalAndEHCleanup,
+ endMightThrow && !cgf.cgm.getLangOpts().AssumeNothrowExceptionDtor);
+
+ return catchParam.getParam();
+}
+
+/// A "special initializer" callback for initializing a catch
+/// parameter during catch initialization.
+static void initCatchParam(CIRGenFunction &cgf, const VarDecl &catchParam,
+ Address paramAddr, SourceLocation loc) {
+ CanQualType catchType =
+ cgf.cgm.getASTContext().getCanonicalType(catchParam.getType());
+ // If we're catching by reference, we can just cast the object
+ // pointer to the appropriate pointer.
+ if (isa<ReferenceType>(catchType)) {
+ cgf.cgm.errorNYI(loc, "initCatchParam: ReferenceType");
+ return;
+ }
+
+ // Scalars and complexes.
+ cir::TypeEvaluationKind tek = cgf.getEvaluationKind(catchType);
+ if (tek != cir::TEK_Aggregate) {
+ // Notes for LLVM lowering:
+ // If the catch type is a pointer type, __cxa_begin_catch returns
+ // the pointer by value.
+ if (catchType->hasPointerRepresentation()) {
+ cgf.cgm.errorNYI(loc, "initCatchParam: hasPointerRepresentation");
+ return;
+ }
+
+ mlir::Type cirCatchTy = cgf.convertTypeForMem(catchType);
+ mlir::Value catchParam =
+ callBeginCatch(cgf, cgf.getBuilder().getPointerTo(cirCatchTy), false);
+ LValue srcLV = cgf.makeNaturalAlignAddrLValue(catchParam, catchType);
+ LValue destLV = cgf.makeAddrLValue(paramAddr, catchType);
+ switch (tek) {
+ case cir::TEK_Complex: {
+ cgf.cgm.errorNYI(loc, "initCatchParam: cir::TEK_Complex");
+ return;
+ }
+ case cir::TEK_Scalar: {
+ auto exnLoad = cgf.emitLoadOfScalar(srcLV, loc);
+ cgf.emitStoreOfScalar(exnLoad, destLV, /*isInit=*/true);
+ return;
+ }
+ case cir::TEK_Aggregate:
+ llvm_unreachable("evaluation kind filtered out!");
+ }
+
+ // Otherwise, it returns a pointer into the exception object.
+ llvm_unreachable("bad evaluation kind");
+ }
+
+ cgf.cgm.errorNYI(loc, "initCatchParam: cir::TEK_Aggregate");
+}
+
+/// Begins a catch statement by initializing the catch variable and
+/// calling __cxa_begin_catch.
+void CIRGenItaniumCXXABI::emitBeginCatch(CIRGenFunction &cgf,
+ const CXXCatchStmt *catchStmt) {
+ // We have to be very careful with the ordering of cleanups here:
+ // C++ [except.throw]p4:
+ // The destruction [of the exception temporary] occurs
+ // immediately after the destruction of the object declared in
+ // the exception-declaration in the handler.
+ //
+ // So the precise ordering is:
+ // 1. Construct catch variable.
+ // 2. __cxa_begin_catch
+ // 3. Enter __cxa_end_catch cleanup
+ // 4. Enter dtor cleanup
+ //
+ // We do this by using a slightly abnormal initialization process.
+ // Delegation sequence:
+ // - ExitCXXTryStmt opens a RunCleanupsScope
+ // - EmitAutoVarAlloca creates the variable and debug info
+ // - InitCatchParam initializes the variable from the exception
+ // - CallBeginCatch calls __cxa_begin_catch
+ // - CallBeginCatch enters the __cxa_end_catch cleanup
+ // - EmitAutoVarCleanups enters the variable destructor cleanup
+ // - EmitCXXTryStmt emits the code for the catch body
+ // - EmitCXXTryStmt close the RunCleanupsScope
+
+ VarDecl *catchParam = catchStmt->getExceptionDecl();
+ if (!catchParam) {
+ callBeginCatch(cgf, cgf.getBuilder().getVoidPtrTy(),
+ /*endMightThrow=*/true);
+ return;
+ }
+
+ auto getCatchParamAllocaIP = [&]() {
+ auto currIns = cgf.getBuilder().saveInsertionPoint();
+ mlir::Operation *currParent = currIns.getBlock()->getParentOp();
+
+ mlir::Block *insertBlock = nullptr;
+ if (auto scopeOp = currParent->getParentOfType<cir::ScopeOp>()) {
+ insertBlock = &scopeOp.getScopeRegion().getBlocks().back();
+ } else if (auto fnOp = currParent->getParentOfType<cir::FuncOp>()) {
+ insertBlock = &fnOp.getRegion().getBlocks().back();
+ } else {
+ llvm_unreachable("unknown outermost scope-like parent");
+ }
+ return cgf.getBuilder().getBestAllocaInsertPoint(insertBlock);
+ };
+
+ // Emit the local. Make sure the alloca's superseed the current scope, since
+ // these are going to be consumed by `cir.catch`, which is not within the
+ // current scope.
+ CIRGenFunction::AutoVarEmission var =
+ cgf.emitAutoVarAlloca(*catchParam, getCatchParamAllocaIP());
+ initCatchParam(cgf, *catchParam, var.getObjectAddress(cgf),
+ catchStmt->getBeginLoc());
+ cgf.emitAutoVarCleanups(var);
+}
diff --git a/clang/test/CIR/CodeGen/try-catch-tmp.cpp b/clang/test/CIR/CodeGen/try-catch-tmp.cpp
index 078447f844d9a..baf5d102a8b74 100644
--- a/clang/test/CIR/CodeGen/try-catch-tmp.cpp
+++ b/clang/test/CIR/CodeGen/try-catch-tmp.cpp
@@ -17,6 +17,7 @@ void calling_division_inside_try_block() {
// CIR: %[[CALL:.*]] = cir.call @_Z8divisionv() : () -> !s32i
// CIR: cir.yield
// CIR: } catch all {
+// CIR: %[[CATCH_PARAM:.*]] = cir.catch_param : !cir.ptr<!void>
// CIR: cir.yield
// CIR: }
// CIR: }
|
andykaylor
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not convinced that we need the CXXABI-specific handling at this point. Is there going to be anything target-specific needed before lowering?
| }; | ||
|
|
||
| LexicalScope *curLexScope = nullptr; | ||
| mlir::Operation *currentFuncletPad = nullptr; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't used other than saving and restoring. It appears that it isn't used in the incubator either. I think this is only needed for Windows exception handling. Because it's target-specific, I hope we'll be able to avoid using this at all until lowering. Classic codegen creates landing pad blocks for funclets when needed, but that's not going to be consistent with the CIR representation.
I was going to suggest adding a MissingFeature marker, but I'm not sure we even want that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we can add it to the MissingFeatures with explanation comment 🤔
| // Emit the local. Make sure the alloca's superseed the current scope, since | ||
| // these are going to be consumed by `cir.catch`, which is not within the | ||
| // current scope. | ||
| CIRGenFunction::AutoVarEmission var = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we get here currently? If so, it doesn't appear to be happening in the test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
b74f4e3 to
e40c920
Compare
andykaylor
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we'll eventually want to have a target-independent way of representing C++ exception handling. What you have here is actually target-independent except for the fact that it's implemented in CIRGenItaniumCXXABI. We can clean that up later when we have a more complete implementation.
This looks good for now.
Emit structured CatchParamOp in the catch region
Issue #154992