-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[CIR][NFC] Upstream EHPersonality for function #164883
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
[CIR][NFC] Upstream EHPersonality for function #164883
Conversation
|
@llvm/pr-subscribers-clangir Author: Amr Hesham (AmrDeveloper) ChangesUpstream the EHPersonality class for a function as a prerequisite for working with the handlers Issue #154992 Full diff: https://github.com/llvm/llvm-project/pull/164883.diff 3 Files Affected:
diff --git a/clang/lib/CIR/CodeGen/CIRGenCleanup.h b/clang/lib/CIR/CodeGen/CIRGenCleanup.h
index 9acf8b1f20e79..61a09a59b05c0 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCleanup.h
+++ b/clang/lib/CIR/CodeGen/CIRGenCleanup.h
@@ -15,6 +15,7 @@
#define CLANG_LIB_CIR_CODEGEN_CIRGENCLEANUP_H
#include "Address.h"
+#include "CIRGenModule.h"
#include "EHScopeStack.h"
#include "mlir/IR/Value.h"
@@ -257,5 +258,53 @@ inline void EHScopeStack::popCatch() {
deallocate(EHCatchScope::getSizeForNumHandlers(scope.getNumHandlers()));
}
+/// The exceptions personality for a function.
+struct EHPersonality {
+ const char *personalityFn = nullptr;
+
+ // If this is non-null, this personality requires a non-standard
+ // function for rethrowing an exception after a catchall cleanup.
+ // This function must have prototype void(void*).
+ const char *catchallRethrowFn = nullptr;
+
+ static const EHPersonality &get(CIRGenModule &cgm,
+ const clang::FunctionDecl *fd);
+ static const EHPersonality &get(CIRGenFunction &cgf);
+
+ static const EHPersonality GNU_C;
+ static const EHPersonality GNU_C_SJLJ;
+ static const EHPersonality GNU_C_SEH;
+ static const EHPersonality GNU_ObjC;
+ static const EHPersonality GNU_ObjC_SJLJ;
+ static const EHPersonality GNU_ObjC_SEH;
+ static const EHPersonality GNUstep_ObjC;
+ static const EHPersonality GNU_ObjCXX;
+ static const EHPersonality NeXT_ObjC;
+ static const EHPersonality GNU_CPlusPlus;
+ static const EHPersonality GNU_CPlusPlus_SJLJ;
+ static const EHPersonality GNU_CPlusPlus_SEH;
+ static const EHPersonality MSVC_except_handler;
+ static const EHPersonality MSVC_C_specific_handler;
+ static const EHPersonality MSVC_CxxFrameHandler3;
+ static const EHPersonality GNU_Wasm_CPlusPlus;
+ static const EHPersonality XL_CPlusPlus;
+ static const EHPersonality ZOS_CPlusPlus;
+
+ /// Does this personality use landingpads or the family of pad instructions
+ /// designed to form funclets?
+ bool usesFuncletPads() const {
+ return isMSVCPersonality() || isWasmPersonality();
+ }
+
+ bool isMSVCPersonality() const {
+ return this == &MSVC_except_handler || this == &MSVC_C_specific_handler ||
+ this == &MSVC_CxxFrameHandler3;
+ }
+
+ bool isWasmPersonality() const { return this == &GNU_Wasm_CPlusPlus; }
+
+ bool isMSVCXXPersonality() const { return this == &MSVC_CxxFrameHandler3; }
+};
+
} // namespace clang::CIRGen
#endif // CLANG_LIB_CIR_CODEGEN_CIRGENCLEANUP_H
diff --git a/clang/lib/CIR/CodeGen/CIRGenException.cpp b/clang/lib/CIR/CodeGen/CIRGenException.cpp
index 717a3e0032cea..67f46ffde8fda 100644
--- a/clang/lib/CIR/CodeGen/CIRGenException.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenException.cpp
@@ -18,6 +18,171 @@
using namespace clang;
using namespace clang::CIRGen;
+const EHPersonality EHPersonality::GNU_C = {"__gcc_personality_v0", nullptr};
+const EHPersonality EHPersonality::GNU_C_SJLJ = {"__gcc_personality_sj0",
+ nullptr};
+const EHPersonality EHPersonality::GNU_C_SEH = {"__gcc_personality_seh0",
+ nullptr};
+const EHPersonality EHPersonality::NeXT_ObjC = {"__objc_personality_v0",
+ nullptr};
+const EHPersonality EHPersonality::GNU_CPlusPlus = {"__gxx_personality_v0",
+ nullptr};
+const EHPersonality EHPersonality::GNU_CPlusPlus_SJLJ = {
+ "__gxx_personality_sj0", nullptr};
+const EHPersonality EHPersonality::GNU_CPlusPlus_SEH = {
+ "__gxx_personality_seh0", nullptr};
+const EHPersonality EHPersonality::GNU_ObjC = {"__gnu_objc_personality_v0",
+ "objc_exception_throw"};
+const EHPersonality EHPersonality::GNU_ObjC_SJLJ = {
+ "__gnu_objc_personality_sj0", "objc_exception_throw"};
+const EHPersonality EHPersonality::GNU_ObjC_SEH = {
+ "__gnu_objc_personality_seh0", "objc_exception_throw"};
+const EHPersonality EHPersonality::GNU_ObjCXX = {
+ "__gnustep_objcxx_personality_v0", nullptr};
+const EHPersonality EHPersonality::GNUstep_ObjC = {
+ "__gnustep_objc_personality_v0", nullptr};
+const EHPersonality EHPersonality::MSVC_except_handler = {"_except_handler3",
+ nullptr};
+const EHPersonality EHPersonality::MSVC_C_specific_handler = {
+ "__C_specific_handler", nullptr};
+const EHPersonality EHPersonality::MSVC_CxxFrameHandler3 = {
+ "__CxxFrameHandler3", nullptr};
+const EHPersonality EHPersonality::GNU_Wasm_CPlusPlus = {
+ "__gxx_wasm_personality_v0", nullptr};
+const EHPersonality EHPersonality::XL_CPlusPlus = {"__xlcxx_personality_v1",
+ nullptr};
+const EHPersonality EHPersonality::ZOS_CPlusPlus = {"__zos_cxx_personality_v2",
+ nullptr};
+
+static const EHPersonality &getCPersonality(const TargetInfo &target,
+ const CodeGenOptions &cgOpts) {
+ const llvm::Triple &triple = target.getTriple();
+ if (triple.isWindowsMSVCEnvironment())
+ return EHPersonality::MSVC_CxxFrameHandler3;
+ if (cgOpts.hasSjLjExceptions())
+ return EHPersonality::GNU_C_SJLJ;
+ if (cgOpts.hasDWARFExceptions())
+ return EHPersonality::GNU_C;
+ if (cgOpts.hasSEHExceptions())
+ return EHPersonality::GNU_C_SEH;
+ return EHPersonality::GNU_C;
+}
+
+static const EHPersonality &getObjCPersonality(const TargetInfo &target,
+ const LangOptions &langOpts,
+ const CodeGenOptions &cgOpts) {
+ const llvm::Triple &triple = target.getTriple();
+ if (triple.isWindowsMSVCEnvironment())
+ return EHPersonality::MSVC_CxxFrameHandler3;
+
+ switch (langOpts.ObjCRuntime.getKind()) {
+ case ObjCRuntime::FragileMacOSX:
+ return getCPersonality(target, cgOpts);
+ case ObjCRuntime::MacOSX:
+ case ObjCRuntime::iOS:
+ case ObjCRuntime::WatchOS:
+ return EHPersonality::NeXT_ObjC;
+ case ObjCRuntime::GNUstep:
+ if (langOpts.ObjCRuntime.getVersion() >= VersionTuple(1, 7))
+ return EHPersonality::GNUstep_ObjC;
+ [[fallthrough]];
+ case ObjCRuntime::GCC:
+ case ObjCRuntime::ObjFW:
+ if (cgOpts.hasSjLjExceptions())
+ return EHPersonality::GNU_ObjC_SJLJ;
+ if (cgOpts.hasSEHExceptions())
+ return EHPersonality::GNU_ObjC_SEH;
+ return EHPersonality::GNU_ObjC;
+ }
+ llvm_unreachable("bad runtime kind");
+}
+
+static const EHPersonality &getCXXPersonality(const TargetInfo &target,
+ const CodeGenOptions &cgOpts) {
+ const llvm::Triple &triple = target.getTriple();
+ if (triple.isWindowsMSVCEnvironment())
+ return EHPersonality::MSVC_CxxFrameHandler3;
+ if (triple.isOSAIX())
+ return EHPersonality::XL_CPlusPlus;
+ if (cgOpts.hasSjLjExceptions())
+ return EHPersonality::GNU_CPlusPlus_SJLJ;
+ if (cgOpts.hasDWARFExceptions())
+ return EHPersonality::GNU_CPlusPlus;
+ if (cgOpts.hasSEHExceptions())
+ return EHPersonality::GNU_CPlusPlus_SEH;
+ if (cgOpts.hasWasmExceptions())
+ return EHPersonality::GNU_Wasm_CPlusPlus;
+ return EHPersonality::GNU_CPlusPlus;
+}
+
+/// Determines the personality function to use when both C++
+/// and Objective-C exceptions are being caught.
+static const EHPersonality &getObjCXXPersonality(const TargetInfo &target,
+ const LangOptions &langOpts,
+ const CodeGenOptions &cgOpts) {
+ if (target.getTriple().isWindowsMSVCEnvironment())
+ return EHPersonality::MSVC_CxxFrameHandler3;
+
+ switch (langOpts.ObjCRuntime.getKind()) {
+ // In the fragile ABI, just use C++ exception handling and hope
+ // they're not doing crazy exception mixing.
+ case ObjCRuntime::FragileMacOSX:
+ return getCXXPersonality(target, cgOpts);
+
+ // The ObjC personality defers to the C++ personality for non-ObjC
+ // handlers. Unlike the C++ case, we use the same personality
+ // function on targets using (backend-driven) SJLJ EH.
+ case ObjCRuntime::MacOSX:
+ case ObjCRuntime::iOS:
+ case ObjCRuntime::WatchOS:
+ return getObjCPersonality(target, langOpts, cgOpts);
+
+ case ObjCRuntime::GNUstep:
+ return EHPersonality::GNU_ObjCXX;
+
+ // The GCC runtime's personality function inherently doesn't support
+ // mixed EH. Use the ObjC personality just to avoid returning null.
+ case ObjCRuntime::GCC:
+ case ObjCRuntime::ObjFW:
+ return getObjCPersonality(target, langOpts, cgOpts);
+ }
+ llvm_unreachable("bad runtime kind");
+}
+
+static const EHPersonality &getSEHPersonalityMSVC(const llvm::Triple &triple) {
+ return triple.getArch() == llvm::Triple::x86
+ ? EHPersonality::MSVC_except_handler
+ : EHPersonality::MSVC_C_specific_handler;
+}
+
+const EHPersonality &EHPersonality::get(CIRGenModule &cgm,
+ const FunctionDecl *fd) {
+ const llvm::Triple &triple = cgm.getTarget().getTriple();
+ const LangOptions &langOpts = cgm.getLangOpts();
+ const CodeGenOptions &cgOpts = cgm.getCodeGenOpts();
+ const TargetInfo &target = cgm.getTarget();
+
+ // Functions using SEH get an SEH personality.
+ if (fd && fd->usesSEHTry())
+ return getSEHPersonalityMSVC(triple);
+
+ if (langOpts.ObjC) {
+ return langOpts.CPlusPlus ? getObjCXXPersonality(target, langOpts, cgOpts)
+ : getObjCPersonality(target, langOpts, cgOpts);
+ }
+ return langOpts.CPlusPlus ? getCXXPersonality(target, cgOpts)
+ : getCPersonality(target, cgOpts);
+}
+
+const EHPersonality &EHPersonality::get(CIRGenFunction &cgf) {
+ const auto *fg = cgf.curCodeDecl;
+ // For outlined finallys and filters, use the SEH personality in case they
+ // contain more SEH. This mostly only affects finallys. Filters could
+ // hypothetically use gnu statement expressions to sneak in nested SEH.
+ fg = fg ? fg : cgf.curSEHParent.getDecl();
+ return get(cgf.cgm, dyn_cast_or_null<FunctionDecl>(fg));
+}
+
void CIRGenFunction::emitCXXThrowExpr(const CXXThrowExpr *e) {
const llvm::Triple &triple = getTarget().getTriple();
if (cgm.getLangOpts().OpenMPIsTargetDevice &&
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index 5f9dbdc64b9e5..5249b6a8c2afd 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -120,6 +120,8 @@ class CIRGenFunction : public CIRGenTypeCache {
/// Tracks function scope overall cleanup handling.
EHScopeStack ehStack;
+ GlobalDecl curSEHParent;
+
llvm::DenseMap<const clang::ValueDecl *, clang::FieldDecl *>
lambdaCaptureFields;
clang::FieldDecl *lambdaThisCaptureField = nullptr;
|
|
@llvm/pr-subscribers-clang Author: Amr Hesham (AmrDeveloper) ChangesUpstream the EHPersonality class for a function as a prerequisite for working with the handlers Issue #154992 Full diff: https://github.com/llvm/llvm-project/pull/164883.diff 3 Files Affected:
diff --git a/clang/lib/CIR/CodeGen/CIRGenCleanup.h b/clang/lib/CIR/CodeGen/CIRGenCleanup.h
index 9acf8b1f20e79..61a09a59b05c0 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCleanup.h
+++ b/clang/lib/CIR/CodeGen/CIRGenCleanup.h
@@ -15,6 +15,7 @@
#define CLANG_LIB_CIR_CODEGEN_CIRGENCLEANUP_H
#include "Address.h"
+#include "CIRGenModule.h"
#include "EHScopeStack.h"
#include "mlir/IR/Value.h"
@@ -257,5 +258,53 @@ inline void EHScopeStack::popCatch() {
deallocate(EHCatchScope::getSizeForNumHandlers(scope.getNumHandlers()));
}
+/// The exceptions personality for a function.
+struct EHPersonality {
+ const char *personalityFn = nullptr;
+
+ // If this is non-null, this personality requires a non-standard
+ // function for rethrowing an exception after a catchall cleanup.
+ // This function must have prototype void(void*).
+ const char *catchallRethrowFn = nullptr;
+
+ static const EHPersonality &get(CIRGenModule &cgm,
+ const clang::FunctionDecl *fd);
+ static const EHPersonality &get(CIRGenFunction &cgf);
+
+ static const EHPersonality GNU_C;
+ static const EHPersonality GNU_C_SJLJ;
+ static const EHPersonality GNU_C_SEH;
+ static const EHPersonality GNU_ObjC;
+ static const EHPersonality GNU_ObjC_SJLJ;
+ static const EHPersonality GNU_ObjC_SEH;
+ static const EHPersonality GNUstep_ObjC;
+ static const EHPersonality GNU_ObjCXX;
+ static const EHPersonality NeXT_ObjC;
+ static const EHPersonality GNU_CPlusPlus;
+ static const EHPersonality GNU_CPlusPlus_SJLJ;
+ static const EHPersonality GNU_CPlusPlus_SEH;
+ static const EHPersonality MSVC_except_handler;
+ static const EHPersonality MSVC_C_specific_handler;
+ static const EHPersonality MSVC_CxxFrameHandler3;
+ static const EHPersonality GNU_Wasm_CPlusPlus;
+ static const EHPersonality XL_CPlusPlus;
+ static const EHPersonality ZOS_CPlusPlus;
+
+ /// Does this personality use landingpads or the family of pad instructions
+ /// designed to form funclets?
+ bool usesFuncletPads() const {
+ return isMSVCPersonality() || isWasmPersonality();
+ }
+
+ bool isMSVCPersonality() const {
+ return this == &MSVC_except_handler || this == &MSVC_C_specific_handler ||
+ this == &MSVC_CxxFrameHandler3;
+ }
+
+ bool isWasmPersonality() const { return this == &GNU_Wasm_CPlusPlus; }
+
+ bool isMSVCXXPersonality() const { return this == &MSVC_CxxFrameHandler3; }
+};
+
} // namespace clang::CIRGen
#endif // CLANG_LIB_CIR_CODEGEN_CIRGENCLEANUP_H
diff --git a/clang/lib/CIR/CodeGen/CIRGenException.cpp b/clang/lib/CIR/CodeGen/CIRGenException.cpp
index 717a3e0032cea..67f46ffde8fda 100644
--- a/clang/lib/CIR/CodeGen/CIRGenException.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenException.cpp
@@ -18,6 +18,171 @@
using namespace clang;
using namespace clang::CIRGen;
+const EHPersonality EHPersonality::GNU_C = {"__gcc_personality_v0", nullptr};
+const EHPersonality EHPersonality::GNU_C_SJLJ = {"__gcc_personality_sj0",
+ nullptr};
+const EHPersonality EHPersonality::GNU_C_SEH = {"__gcc_personality_seh0",
+ nullptr};
+const EHPersonality EHPersonality::NeXT_ObjC = {"__objc_personality_v0",
+ nullptr};
+const EHPersonality EHPersonality::GNU_CPlusPlus = {"__gxx_personality_v0",
+ nullptr};
+const EHPersonality EHPersonality::GNU_CPlusPlus_SJLJ = {
+ "__gxx_personality_sj0", nullptr};
+const EHPersonality EHPersonality::GNU_CPlusPlus_SEH = {
+ "__gxx_personality_seh0", nullptr};
+const EHPersonality EHPersonality::GNU_ObjC = {"__gnu_objc_personality_v0",
+ "objc_exception_throw"};
+const EHPersonality EHPersonality::GNU_ObjC_SJLJ = {
+ "__gnu_objc_personality_sj0", "objc_exception_throw"};
+const EHPersonality EHPersonality::GNU_ObjC_SEH = {
+ "__gnu_objc_personality_seh0", "objc_exception_throw"};
+const EHPersonality EHPersonality::GNU_ObjCXX = {
+ "__gnustep_objcxx_personality_v0", nullptr};
+const EHPersonality EHPersonality::GNUstep_ObjC = {
+ "__gnustep_objc_personality_v0", nullptr};
+const EHPersonality EHPersonality::MSVC_except_handler = {"_except_handler3",
+ nullptr};
+const EHPersonality EHPersonality::MSVC_C_specific_handler = {
+ "__C_specific_handler", nullptr};
+const EHPersonality EHPersonality::MSVC_CxxFrameHandler3 = {
+ "__CxxFrameHandler3", nullptr};
+const EHPersonality EHPersonality::GNU_Wasm_CPlusPlus = {
+ "__gxx_wasm_personality_v0", nullptr};
+const EHPersonality EHPersonality::XL_CPlusPlus = {"__xlcxx_personality_v1",
+ nullptr};
+const EHPersonality EHPersonality::ZOS_CPlusPlus = {"__zos_cxx_personality_v2",
+ nullptr};
+
+static const EHPersonality &getCPersonality(const TargetInfo &target,
+ const CodeGenOptions &cgOpts) {
+ const llvm::Triple &triple = target.getTriple();
+ if (triple.isWindowsMSVCEnvironment())
+ return EHPersonality::MSVC_CxxFrameHandler3;
+ if (cgOpts.hasSjLjExceptions())
+ return EHPersonality::GNU_C_SJLJ;
+ if (cgOpts.hasDWARFExceptions())
+ return EHPersonality::GNU_C;
+ if (cgOpts.hasSEHExceptions())
+ return EHPersonality::GNU_C_SEH;
+ return EHPersonality::GNU_C;
+}
+
+static const EHPersonality &getObjCPersonality(const TargetInfo &target,
+ const LangOptions &langOpts,
+ const CodeGenOptions &cgOpts) {
+ const llvm::Triple &triple = target.getTriple();
+ if (triple.isWindowsMSVCEnvironment())
+ return EHPersonality::MSVC_CxxFrameHandler3;
+
+ switch (langOpts.ObjCRuntime.getKind()) {
+ case ObjCRuntime::FragileMacOSX:
+ return getCPersonality(target, cgOpts);
+ case ObjCRuntime::MacOSX:
+ case ObjCRuntime::iOS:
+ case ObjCRuntime::WatchOS:
+ return EHPersonality::NeXT_ObjC;
+ case ObjCRuntime::GNUstep:
+ if (langOpts.ObjCRuntime.getVersion() >= VersionTuple(1, 7))
+ return EHPersonality::GNUstep_ObjC;
+ [[fallthrough]];
+ case ObjCRuntime::GCC:
+ case ObjCRuntime::ObjFW:
+ if (cgOpts.hasSjLjExceptions())
+ return EHPersonality::GNU_ObjC_SJLJ;
+ if (cgOpts.hasSEHExceptions())
+ return EHPersonality::GNU_ObjC_SEH;
+ return EHPersonality::GNU_ObjC;
+ }
+ llvm_unreachable("bad runtime kind");
+}
+
+static const EHPersonality &getCXXPersonality(const TargetInfo &target,
+ const CodeGenOptions &cgOpts) {
+ const llvm::Triple &triple = target.getTriple();
+ if (triple.isWindowsMSVCEnvironment())
+ return EHPersonality::MSVC_CxxFrameHandler3;
+ if (triple.isOSAIX())
+ return EHPersonality::XL_CPlusPlus;
+ if (cgOpts.hasSjLjExceptions())
+ return EHPersonality::GNU_CPlusPlus_SJLJ;
+ if (cgOpts.hasDWARFExceptions())
+ return EHPersonality::GNU_CPlusPlus;
+ if (cgOpts.hasSEHExceptions())
+ return EHPersonality::GNU_CPlusPlus_SEH;
+ if (cgOpts.hasWasmExceptions())
+ return EHPersonality::GNU_Wasm_CPlusPlus;
+ return EHPersonality::GNU_CPlusPlus;
+}
+
+/// Determines the personality function to use when both C++
+/// and Objective-C exceptions are being caught.
+static const EHPersonality &getObjCXXPersonality(const TargetInfo &target,
+ const LangOptions &langOpts,
+ const CodeGenOptions &cgOpts) {
+ if (target.getTriple().isWindowsMSVCEnvironment())
+ return EHPersonality::MSVC_CxxFrameHandler3;
+
+ switch (langOpts.ObjCRuntime.getKind()) {
+ // In the fragile ABI, just use C++ exception handling and hope
+ // they're not doing crazy exception mixing.
+ case ObjCRuntime::FragileMacOSX:
+ return getCXXPersonality(target, cgOpts);
+
+ // The ObjC personality defers to the C++ personality for non-ObjC
+ // handlers. Unlike the C++ case, we use the same personality
+ // function on targets using (backend-driven) SJLJ EH.
+ case ObjCRuntime::MacOSX:
+ case ObjCRuntime::iOS:
+ case ObjCRuntime::WatchOS:
+ return getObjCPersonality(target, langOpts, cgOpts);
+
+ case ObjCRuntime::GNUstep:
+ return EHPersonality::GNU_ObjCXX;
+
+ // The GCC runtime's personality function inherently doesn't support
+ // mixed EH. Use the ObjC personality just to avoid returning null.
+ case ObjCRuntime::GCC:
+ case ObjCRuntime::ObjFW:
+ return getObjCPersonality(target, langOpts, cgOpts);
+ }
+ llvm_unreachable("bad runtime kind");
+}
+
+static const EHPersonality &getSEHPersonalityMSVC(const llvm::Triple &triple) {
+ return triple.getArch() == llvm::Triple::x86
+ ? EHPersonality::MSVC_except_handler
+ : EHPersonality::MSVC_C_specific_handler;
+}
+
+const EHPersonality &EHPersonality::get(CIRGenModule &cgm,
+ const FunctionDecl *fd) {
+ const llvm::Triple &triple = cgm.getTarget().getTriple();
+ const LangOptions &langOpts = cgm.getLangOpts();
+ const CodeGenOptions &cgOpts = cgm.getCodeGenOpts();
+ const TargetInfo &target = cgm.getTarget();
+
+ // Functions using SEH get an SEH personality.
+ if (fd && fd->usesSEHTry())
+ return getSEHPersonalityMSVC(triple);
+
+ if (langOpts.ObjC) {
+ return langOpts.CPlusPlus ? getObjCXXPersonality(target, langOpts, cgOpts)
+ : getObjCPersonality(target, langOpts, cgOpts);
+ }
+ return langOpts.CPlusPlus ? getCXXPersonality(target, cgOpts)
+ : getCPersonality(target, cgOpts);
+}
+
+const EHPersonality &EHPersonality::get(CIRGenFunction &cgf) {
+ const auto *fg = cgf.curCodeDecl;
+ // For outlined finallys and filters, use the SEH personality in case they
+ // contain more SEH. This mostly only affects finallys. Filters could
+ // hypothetically use gnu statement expressions to sneak in nested SEH.
+ fg = fg ? fg : cgf.curSEHParent.getDecl();
+ return get(cgf.cgm, dyn_cast_or_null<FunctionDecl>(fg));
+}
+
void CIRGenFunction::emitCXXThrowExpr(const CXXThrowExpr *e) {
const llvm::Triple &triple = getTarget().getTriple();
if (cgm.getLangOpts().OpenMPIsTargetDevice &&
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index 5f9dbdc64b9e5..5249b6a8c2afd 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -120,6 +120,8 @@ class CIRGenFunction : public CIRGenTypeCache {
/// Tracks function scope overall cleanup handling.
EHScopeStack ehStack;
+ GlobalDecl curSEHParent;
+
llvm::DenseMap<const clang::ValueDecl *, clang::FieldDecl *>
lambdaCaptureFields;
clang::FieldDecl *lambdaThisCaptureField = nullptr;
|
bcardosolopes
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.
Content LGTM, but I have a pending question.
| } | ||
|
|
||
| /// The exceptions personality for a function. | ||
| struct EHPersonality { |
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.
Is is possible to abstract most of this (or if you tried) into a base class that could be shared between it and classic CG? Seems like 95% is the same but ::get methods. It can come as follow up PR, but I think we should handle this sooner than later. (cc @andykaylor)
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.
Yes, I think it's possible and can also be done by one class with CodeGenModule and CodeGenFunction as a template parameters, and we can specialize the ::get method twice for both codegens 🤔.
I think that this case is also a good example for adding a shared codegen component.
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.
If you have the time it would be great to follow up on some of these refactoring (so it can open the road for easily incorporating later ones) before the GSoC term ends! Thanks again for working on this
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.
Sure, I will do that 🫡
Upstream the EHPersonality class for a function as a prerequisite for working with the handlers Issue llvm#154992
Upstream the EHPersonality class for a function as a prerequisite for working with the handlers Issue llvm#154992
Upstream the EHPersonality class for a function as a prerequisite for working with the handlers Issue llvm#154992
Upstream the EHPersonality class for a function as a prerequisite for working with the handlers
Issue #154992