llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang @llvm/pr-subscribers-clang-codegen Author: Henrich Lauko (xlauko) <details> <summary>Changes</summary> Deduplicates the `EHPersonality` struct and its personality constants between CIR and classic CodeGen into `EHPersonality.h`. The `EHPersonality::get` factories become `getEHPersonality` overloads, since the shared struct cannot name either CodeGenModule. Assisted-by: Claude Code (Claude Fable 5.1). --- Patch is 27.86 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/223420.diff 11 Files Affected: - (added) clang/include/clang/CodeGenUtils/EHPersonality.h (+65) - (modified) clang/lib/CIR/CodeGen/CIRGenCleanup.h (+9-45) - (modified) clang/lib/CIR/CodeGen/CIRGenException.cpp (+11-43) - (modified) clang/lib/CodeGen/CGCall.cpp (+1-1) - (modified) clang/lib/CodeGen/CGCleanup.cpp (+1-1) - (modified) clang/lib/CodeGen/CGCleanup.h (+11-46) - (modified) clang/lib/CodeGen/CGException.cpp (+19-51) - (modified) clang/lib/CodeGen/CGObjCRuntime.cpp (+3-3) - (modified) clang/lib/CodeGen/ItaniumCXXABI.cpp (+1-1) - (modified) clang/lib/CodeGenUtils/CMakeLists.txt (+1) - (added) clang/lib/CodeGenUtils/EHPersonality.cpp (+49) ``````````diff diff --git a/clang/include/clang/CodeGenUtils/EHPersonality.h b/clang/include/clang/CodeGenUtils/EHPersonality.h new file mode 100644 index 0000000000000..ab604c801e07e --- /dev/null +++ b/clang/include/clang/CodeGenUtils/EHPersonality.h @@ -0,0 +1,65 @@ +//===--- EHPersonality.h - Shared EH personality descriptions ---*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file describes the exception personality functions that both classic +// CodeGen and CIR CodeGen can select for a function. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_CODEGENUTILS_EHPERSONALITY_H +#define LLVM_CLANG_CODEGENUTILS_EHPERSONALITY_H + +namespace clang::CodeGenUtils { + +/// 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 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::CodeGenUtils + +#endif // LLVM_CLANG_CODEGENUTILS_EHPERSONALITY_H diff --git a/clang/lib/CIR/CodeGen/CIRGenCleanup.h b/clang/lib/CIR/CodeGen/CIRGenCleanup.h index 46f1382bced7d..0f761b69c02d1 100644 --- a/clang/lib/CIR/CodeGen/CIRGenCleanup.h +++ b/clang/lib/CIR/CodeGen/CIRGenCleanup.h @@ -19,6 +19,7 @@ #include "EHScopeStack.h" #include "mlir/IR/Value.h" #include "clang/AST/StmtCXX.h" +#include "clang/CodeGenUtils/EHPersonality.h" namespace clang::CIRGen { @@ -251,53 +252,16 @@ EHScopeStack::find(stable_iterator savePoint) const { return iterator(endOfBuffer - savePoint.size); } -/// 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; - } +using CodeGenUtils::EHPersonality; - bool isWasmPersonality() const { return this == &GNU_Wasm_CPlusPlus; } +/// Selects the personality function to use for \p fd, or for the translation +/// unit as a whole when \p fd is null. +const EHPersonality &getEHPersonality(CIRGenModule &cgm, + const clang::FunctionDecl *fd); - bool isMSVCXXPersonality() const { return this == &MSVC_CxxFrameHandler3; } -}; +/// Selects the personality function to use for the function currently being +/// emitted. +const EHPersonality &getEHPersonality(CIRGenFunction &cgf); } // 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 2c2fa83e661d3..bd3e2014756e6 100644 --- a/clang/lib/CIR/CodeGen/CIRGenException.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenException.cpp @@ -22,42 +22,6 @@ 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(); @@ -159,8 +123,10 @@ static const EHPersonality &getSEHPersonalityMSVC(const llvm::Triple &triple) { : EHPersonality::MSVC_C_specific_handler; } -const EHPersonality &EHPersonality::get(CIRGenModule &cgm, - const FunctionDecl *fd) { +namespace clang::CIRGen { + +const EHPersonality &getEHPersonality(CIRGenModule &cgm, + const FunctionDecl *fd) { const llvm::Triple &triple = cgm.getTarget().getTriple(); const LangOptions &langOpts = cgm.getLangOpts(); const CodeGenOptions &cgOpts = cgm.getCodeGenOpts(); @@ -178,15 +144,17 @@ const EHPersonality &EHPersonality::get(CIRGenModule &cgm, : getCPersonality(target, cgOpts); } -const EHPersonality &EHPersonality::get(CIRGenFunction &cgf) { +const EHPersonality &getEHPersonality(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)); + return getEHPersonality(cgf.cgm, dyn_cast_or_null<FunctionDecl>(fg)); } +} // namespace clang::CIRGen + static llvm::StringRef getPersonalityFn(CIRGenModule &cgm, const EHPersonality &personality) { // Create the personality function type: i32 (...) @@ -194,7 +162,7 @@ static llvm::StringRef getPersonalityFn(CIRGenModule &cgm, auto funcTy = cir::FuncType::get({}, i32Ty, /*isVarArg=*/true); cir::FuncOp personalityFn = cgm.createRuntimeFunction( - funcTy, personality.personalityFn, {}, /*isLocal=*/true); + funcTy, personality.PersonalityFn, {}, /*isLocal=*/true); return personalityFn.getSymName(); } @@ -281,7 +249,7 @@ void CIRGenFunction::emitStartEHSpec(const Decl *d) { cir::FuncOp funcOp = mlir::cast<cir::FuncOp>(curFn); if (!funcOp.getPersonality()) - funcOp.setPersonality(getPersonalityFn(cgm, EHPersonality::get(*this))); + funcOp.setPersonality(getPersonalityFn(cgm, getEHPersonality(*this))); bool emptyFilter = permittedTypes.empty(); ehSpecTryOp = cir::TryOp::create( @@ -657,7 +625,7 @@ CIRGenFunction::emitCXXTryStmt(const CXXTryStmt &s, // Set personality function if not already set auto funcOp = mlir::cast<cir::FuncOp>(curFn); if (!funcOp.getPersonality()) - funcOp.setPersonality(getPersonalityFn(cgm, EHPersonality::get(*this))); + funcOp.setPersonality(getPersonalityFn(cgm, getEHPersonality(*this))); mlir::OpBuilder::InsertionGuard guard(builder); builder.restoreInsertionPoint(scopeIP); diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 2193a89203f29..c294621b28d1d 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -6322,7 +6322,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, // SEH cares about asynchronous exceptions, so everything can "throw." CannotThrow = false; } else if (isCleanupPadScope() && - EHPersonality::get(*this).isMSVCXXPersonality()) { + getEHPersonality(*this).isMSVCXXPersonality()) { // The MSVC++ personality will implicitly terminate the program if an // exception is thrown during a cleanup outside of a try/catch. // We don't need to model anything in IR to get this behavior. diff --git a/clang/lib/CodeGen/CGCleanup.cpp b/clang/lib/CodeGen/CGCleanup.cpp index 9d279bebe5e0d..3cac452a5f215 100644 --- a/clang/lib/CodeGen/CGCleanup.cpp +++ b/clang/lib/CodeGen/CGCleanup.cpp @@ -1049,7 +1049,7 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough, SaveAndRestore RestoreCurrentFuncletPad(CurrentFuncletPad); llvm::CleanupPadInst *CPI = nullptr; - const EHPersonality &Personality = EHPersonality::get(*this); + const EHPersonality &Personality = getEHPersonality(*this); if (Personality.usesFuncletPads()) { llvm::Value *ParentPad = CurrentFuncletPad; if (!ParentPad) diff --git a/clang/lib/CodeGen/CGCleanup.h b/clang/lib/CodeGen/CGCleanup.h index 375dbbbb19709..fd8206fbccfe1 100644 --- a/clang/lib/CodeGen/CGCleanup.h +++ b/clang/lib/CodeGen/CGCleanup.h @@ -16,6 +16,7 @@ #include "EHScopeStack.h" #include "Address.h" +#include "clang/CodeGenUtils/EHPersonality.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallPtrSet.h" @@ -674,52 +675,16 @@ EHScopeStack::stabilize(iterator ir) const { return stable_iterator(EndOfBuffer - ir.Ptr); } -/// The exceptions personality for a function. -struct EHPersonality { - const char *PersonalityFn; - - // 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; - - static const EHPersonality &get(CodeGenModule &CGM, const FunctionDecl *FD); - static const EHPersonality &get(CodeGenFunction &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; } -}; +using CodeGenUtils::EHPersonality; + +/// Selects the personality function to use for \p FD, or for the translation +/// unit as a whole when \p FD is null. +const EHPersonality &getEHPersonality(CodeGenModule &CGM, + const FunctionDecl *FD); + +/// Selects the personality function to use for the function currently being +/// emitted. +const EHPersonality &getEHPersonality(CodeGenFunction &CGF); } } diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp index f06edde9739b4..f8b4cbc516a40 100644 --- a/clang/lib/CodeGen/CGException.cpp +++ b/clang/lib/CodeGen/CGException.cpp @@ -82,42 +82,6 @@ static llvm::FunctionCallee getCatchallRethrowFn(CodeGenModule &CGM, return CGM.CreateRuntimeFunction(FTy, Name); } -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 &T = Target.getTriple(); @@ -230,8 +194,10 @@ static const EHPersonality &getSEHPersonalityMSVC(const llvm::Triple &T) { return EHPersonality::MSVC_C_specific_handler; } -const EHPersonality &EHPersonality::get(CodeGenModule &CGM, - const FunctionDecl *FD) { +namespace clang::CodeGen { + +const EHPersonality &getEHPersonality(CodeGenModule &CGM, + const FunctionDecl *FD) { const llvm::Triple &T = CGM.getTarget().getTriple(); const CodeGenOptions &CGOpts = CGM.getCodeGenOpts(); const LangOptions &L = CGM.getLangOpts(); @@ -248,15 +214,17 @@ const EHPersonality &EHPersonality::get(CodeGenModule &CGM, : getCPersonality(Target, CGOpts); } -const EHPersonality &EHPersonality::get(CodeGenFunction &CGF) { +const EHPersonality &getEHPersonality(CodeGenFunction &CGF) { const auto *FD = 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. FD = FD ? FD : CGF.CurSEHParent.getDecl(); - return get(CGF.CGM, dyn_cast_or_null<FunctionDecl>(FD)); + return getEHPersonality(CGF.CGM, dyn_cast_or_null<FunctionDecl>(FD)); } +} // namespace clang::CodeGen + static llvm::FunctionCallee getPersonalityFn(CodeGenModule &CGM, const EHPersonality &Personality) { llvm::FunctionType *FTy; @@ -346,7 +314,7 @@ void CodeGenModule::SimplifyPersonality() { if (!LangOpts.ObjCRuntime.isNeXTFamily()) return; - const EHPersonality &ObjCXX = EHPersonality::get(*this, /*FD=*/nullptr); + const EHPersonality &ObjCXX = getEHPersonality(*this, /*FD=*/nullptr); const EHPersonality &CXX = getCXXPersonality(getTarget(), CodeGenOpts); if (&ObjCXX == &CXX) return; @@ -676,7 +644,7 @@ void CodeGenFunction::EnterCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock) { llvm::BasicBlock * CodeGenFunction::getEHDispatchBlock(EHScopeStack::stable_iterator si) { - if (EHPersonality::get(*this).usesFuncletPads()) + if (getEHPersonality(*this).usesFuncletPads()) return getFuncletEHDispatchBlock(si); // The dispatch block for the end of the scope chain is a block that @@ -802,7 +770,7 @@ llvm::BasicBlock *CodeGenFunction::getInvokeDestImpl() { llvm::BasicBlock *LP = EHStack.begin()->getCachedLandingPad(); if (LP) return LP; - const EHPersonality &Personality = EHPersonality::get(*this); + const EHPersonality &Personality = getEHPersonality(*this); if (!CurFn->hasPersonalityFn()) CurFn->setPersonalityFn(getOpaquePersonalityFn(CGM, Personality)); @@ -995,7 +963,7 @@ static void... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/223420 _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
