[clang] [CIR][CodeGen][NFC] Extract the EHPersonality struct into CodeGenUtils (PR #223420)
Henrich Lauko via cfe-commits
cfe-commits at lists.llvm.org
Thu Oct 1 01:18:14 PDT 2026
https://github.com/xlauko updated https://github.com/llvm/llvm-project/pull/223420
>From 6bccb9589d6940241c28d49ddc367091d34513df Mon Sep 17 00:00:00 2001
From: Henrich Lauko <hlauko at nvidia.com>
Date: Mon, 14 Sep 2026 13:10:50 +0000
Subject: [PATCH 1/2] [CIR][CodeGen][NFCI] Share the COMDAT and common-linkage
predicates
Deduplicates `shouldBeInCOMDAT` and `isVarDeclStrongDefinition` between CIR and
classic CodeGen into `ModuleUtils.h`.
Assisted-by: Claude Code (Claude Fable 5.1).
---
.../include/clang/CodeGenUtils/ModuleUtils.h | 32 +++++
clang/lib/CIR/CodeGen/CIRGenModule.cpp | 109 +----------------
clang/lib/CodeGen/CodeGenModule.cpp | 107 +---------------
clang/lib/CodeGenUtils/CMakeLists.txt | 1 +
clang/lib/CodeGenUtils/ModuleUtils.cpp | 114 ++++++++++++++++++
5 files changed, 155 insertions(+), 208 deletions(-)
create mode 100644 clang/include/clang/CodeGenUtils/ModuleUtils.h
create mode 100644 clang/lib/CodeGenUtils/ModuleUtils.cpp
diff --git a/clang/include/clang/CodeGenUtils/ModuleUtils.h b/clang/include/clang/CodeGenUtils/ModuleUtils.h
new file mode 100644
index 0000000000000..5c7423ad4fac5
--- /dev/null
+++ b/clang/include/clang/CodeGenUtils/ModuleUtils.h
@@ -0,0 +1,32 @@
+//===--- ModuleUtils.h - Shared module emission queries ---------*- 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 holds the AST queries that both classic CodeGen and CIR CodeGen
+// need while deciding how a declaration is emitted at module scope, such as
+// its linkage and whether it belongs in a COMDAT group.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CODEGENUTILS_MODULEUTILS_H
+#define LLVM_CLANG_CODEGENUTILS_MODULEUTILS_H
+
+#include "clang/AST/ASTContext.h"
+
+namespace clang::CodeGenUtils {
+
+/// Check whether \p D is a strong definition, and thus must not be given
+/// common linkage. \p NoCommon reflects -fno-common.
+bool isVarDeclStrongDefinition(const ASTContext &Ctx, const VarDecl *D,
+ bool NoCommon);
+
+/// Check whether \p D should be emitted into a COMDAT group.
+bool shouldBeInCOMDAT(const ASTContext &Ctx, const Decl &D);
+
+} // namespace clang::CodeGenUtils
+
+#endif // LLVM_CLANG_CODEGENUTILS_MODULEUTILS_H
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index 007788d7e27c7..8978f8305b267 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -37,6 +37,7 @@
#include "clang/CIR/Interfaces/CIROpInterfaces.h"
#include "clang/CIR/MissingFeatures.h"
#include "clang/CodeGenUtils/CodeGenUtils.h"
+#include "clang/CodeGenUtils/ModuleUtils.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
@@ -1828,34 +1829,8 @@ bool CIRGenModule::supportsCOMDAT() const {
return getTriple().supportsCOMDAT();
}
-static bool shouldBeInCOMDAT(CIRGenModule &cgm, const Decl &d) {
- if (!cgm.supportsCOMDAT())
- return false;
-
- if (d.hasAttr<SelectAnyAttr>())
- return true;
-
- GVALinkage linkage;
- if (auto *vd = dyn_cast<VarDecl>(&d))
- linkage = cgm.getASTContext().GetGVALinkageForVariable(vd);
- else
- linkage =
- cgm.getASTContext().GetGVALinkageForFunction(cast<FunctionDecl>(&d));
-
- switch (linkage) {
- case clang::GVA_Internal:
- case clang::GVA_AvailableExternally:
- case clang::GVA_StrongExternal:
- return false;
- case clang::GVA_DiscardableODR:
- case clang::GVA_StrongODR:
- return true;
- }
- llvm_unreachable("No such linkage");
-}
-
void CIRGenModule::maybeSetTrivialComdat(const Decl &d, mlir::Operation *op) {
- if (!shouldBeInCOMDAT(*this, d))
+ if (!CodeGenUtils::shouldBeInCOMDAT(getASTContext(), d))
return;
if (auto globalOp = dyn_cast_or_null<cir::GlobalOp>(op)) {
globalOp.setComdat(true);
@@ -1969,82 +1944,6 @@ cir::GlobalOp CIRGenModule::createOrReplaceCXXRuntimeVariable(
return gv;
}
-// TODO(CIR): this could be a common method between LLVM codegen.
-static bool isVarDeclStrongDefinition(const ASTContext &astContext,
- CIRGenModule &cgm, const VarDecl *vd,
- bool noCommon) {
- // Don't give variables common linkage if -fno-common was specified unless it
- // was overridden by a NoCommon attribute.
- if ((noCommon || vd->hasAttr<NoCommonAttr>()) && !vd->hasAttr<CommonAttr>())
- return true;
-
- // C11 6.9.2/2:
- // A declaration of an identifier for an object that has file scope without
- // an initializer, and without a storage-class specifier or with the
- // storage-class specifier static, constitutes a tentative definition.
- if (vd->getInit() || vd->hasExternalStorage())
- return true;
-
- // A variable cannot be both common and exist in a section.
- if (vd->hasAttr<SectionAttr>())
- return true;
-
- // A variable cannot be both common and exist in a section.
- // We don't try to determine which is the right section in the front-end.
- // If no specialized section name is applicable, it will resort to default.
- if (vd->hasAttr<PragmaClangBSSSectionAttr>() ||
- vd->hasAttr<PragmaClangDataSectionAttr>() ||
- vd->hasAttr<PragmaClangRelroSectionAttr>() ||
- vd->hasAttr<PragmaClangRodataSectionAttr>())
- return true;
-
- // Thread local vars aren't considered common linkage.
- if (vd->getTLSKind())
- return true;
-
- // Tentative definitions marked with WeakImportAttr are true definitions.
- if (vd->hasAttr<WeakImportAttr>())
- return true;
-
- // A variable cannot be both common and exist in a comdat.
- if (shouldBeInCOMDAT(cgm, *vd))
- return true;
-
- // Declarations with a required alignment do not have common linkage in MSVC
- // mode.
- if (astContext.getTargetInfo().getCXXABI().isMicrosoft()) {
- if (vd->hasAttr<AlignedAttr>())
- return true;
- QualType varType = vd->getType();
- if (astContext.isAlignmentRequired(varType))
- return true;
-
- if (const auto *rd = varType->getAsRecordDecl()) {
- for (const FieldDecl *fd : rd->fields()) {
- if (fd->isBitField())
- continue;
- if (fd->hasAttr<AlignedAttr>())
- return true;
- if (astContext.isAlignmentRequired(fd->getType()))
- return true;
- }
- }
- }
-
- // Microsoft's link.exe doesn't support alignments greater than 32 bytes for
- // common symbols, so symbols with greater alignment requirements cannot be
- // common.
- // Other COFF linkers (ld.bfd and LLD) support arbitrary power-of-two
- // alignments for common symbols via the aligncomm directive, so this
- // restriction only applies to MSVC environments.
- if (astContext.getTargetInfo().getTriple().isKnownWindowsMSVCEnvironment() &&
- astContext.getTypeAlignIfKnown(vd->getType()) >
- astContext.toBits(CharUnits::fromQuantity(32)))
- return true;
-
- return false;
-}
-
cir::GlobalLinkageKind
CIRGenModule::getCIRLinkageForDeclarator(const DeclaratorDecl *dd,
GVALinkage linkage) {
@@ -2103,8 +2002,8 @@ CIRGenModule::getCIRLinkageForDeclarator(const DeclaratorDecl *dd,
// C++ doesn't have tentative definitions and thus cannot have common
// linkage.
if (!getLangOpts().CPlusPlus && isa<VarDecl>(dd) &&
- !isVarDeclStrongDefinition(astContext, *this, cast<VarDecl>(dd),
- getCodeGenOpts().NoCommon))
+ !CodeGenUtils::isVarDeclStrongDefinition(astContext, cast<VarDecl>(dd),
+ getCodeGenOpts().NoCommon))
return cir::GlobalLinkageKind::CommonLinkage;
// selectany symbols are externally visible, so use weak instead of
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 7274a8588670f..6cdd35d5e1308 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -49,6 +49,7 @@
#include "clang/CodeGen/BackendUtil.h"
#include "clang/CodeGen/ConstantInitBuilder.h"
#include "clang/CodeGenUtils/CodeGenUtils.h"
+#include "clang/CodeGenUtils/ModuleUtils.h"
#include "clang/Lex/Preprocessor.h"
#include "llvm/ABI/IRTypeMapper.h"
#include "llvm/ABI/TargetInfo.h"
@@ -6520,38 +6521,13 @@ void CodeGenModule::MaybeHandleStaticInExternC(const SomeDecl *D,
R.first->second = nullptr;
}
-static bool shouldBeInCOMDAT(CodeGenModule &CGM, const Decl &D) {
- if (!CGM.supportsCOMDAT())
- return false;
-
- if (D.hasAttr<SelectAnyAttr>())
- return true;
-
- GVALinkage Linkage;
- if (auto *VD = dyn_cast<VarDecl>(&D))
- Linkage = CGM.getContext().GetGVALinkageForVariable(VD);
- else
- Linkage = CGM.getContext().GetGVALinkageForFunction(cast<FunctionDecl>(&D));
-
- switch (Linkage) {
- case GVA_Internal:
- case GVA_AvailableExternally:
- case GVA_StrongExternal:
- return false;
- case GVA_DiscardableODR:
- case GVA_StrongODR:
- return true;
- }
- llvm_unreachable("No such linkage");
-}
-
bool CodeGenModule::supportsCOMDAT() const {
return getTriple().supportsCOMDAT();
}
void CodeGenModule::maybeSetTrivialComdat(const Decl &D,
llvm::GlobalObject &GO) {
- if (!shouldBeInCOMDAT(*this, D))
+ if (!CodeGenUtils::shouldBeInCOMDAT(getContext(), D))
return;
GO.setComdat(TheModule.getOrInsertComdat(GO.getName()));
}
@@ -6860,81 +6836,6 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D,
DI->EmitGlobalVariable(GV, D);
}
-static bool isVarDeclStrongDefinition(const ASTContext &Context,
- CodeGenModule &CGM, const VarDecl *D,
- bool NoCommon) {
- // Don't give variables common linkage if -fno-common was specified unless it
- // was overridden by a NoCommon attribute.
- if ((NoCommon || D->hasAttr<NoCommonAttr>()) && !D->hasAttr<CommonAttr>())
- return true;
-
- // C11 6.9.2/2:
- // A declaration of an identifier for an object that has file scope without
- // an initializer, and without a storage-class specifier or with the
- // storage-class specifier static, constitutes a tentative definition.
- if (D->getInit() || D->hasExternalStorage())
- return true;
-
- // A variable cannot be both common and exist in a section.
- if (D->hasAttr<SectionAttr>())
- return true;
-
- // A variable cannot be both common and exist in a section.
- // We don't try to determine which is the right section in the front-end.
- // If no specialized section name is applicable, it will resort to default.
- if (D->hasAttr<PragmaClangBSSSectionAttr>() ||
- D->hasAttr<PragmaClangDataSectionAttr>() ||
- D->hasAttr<PragmaClangRelroSectionAttr>() ||
- D->hasAttr<PragmaClangRodataSectionAttr>())
- return true;
-
- // Thread local vars aren't considered common linkage.
- if (D->getTLSKind())
- return true;
-
- // Tentative definitions marked with WeakImportAttr are true definitions.
- if (D->hasAttr<WeakImportAttr>())
- return true;
-
- // A variable cannot be both common and exist in a comdat.
- if (shouldBeInCOMDAT(CGM, *D))
- return true;
-
- // Declarations with a required alignment do not have common linkage in MSVC
- // mode.
- if (Context.getTargetInfo().getCXXABI().isMicrosoft()) {
- if (D->hasAttr<AlignedAttr>())
- return true;
- QualType VarType = D->getType();
- if (Context.isAlignmentRequired(VarType))
- return true;
-
- if (const auto *RD = VarType->getAsRecordDecl()) {
- for (const FieldDecl *FD : RD->fields()) {
- if (FD->isBitField())
- continue;
- if (FD->hasAttr<AlignedAttr>())
- return true;
- if (Context.isAlignmentRequired(FD->getType()))
- return true;
- }
- }
- }
-
- // Microsoft's link.exe doesn't support alignments greater than 32 bytes for
- // common symbols, so symbols with greater alignment requirements cannot be
- // common.
- // Other COFF linkers (ld.bfd and LLD) support arbitrary power-of-two
- // alignments for common symbols via the aligncomm directive, so this
- // restriction only applies to MSVC environments.
- if (Context.getTargetInfo().getTriple().isKnownWindowsMSVCEnvironment() &&
- Context.getTypeAlignIfKnown(D->getType()) >
- Context.toBits(CharUnits::fromQuantity(32)))
- return true;
-
- return false;
-}
-
llvm::GlobalValue::LinkageTypes
CodeGenModule::getLLVMLinkageForDeclarator(const DeclaratorDecl *D,
GVALinkage Linkage) {
@@ -6991,8 +6892,8 @@ CodeGenModule::getLLVMLinkageForDeclarator(const DeclaratorDecl *D,
// C++ doesn't have tentative definitions and thus cannot have common
// linkage.
if (!getLangOpts().CPlusPlus && isa<VarDecl>(D) &&
- !isVarDeclStrongDefinition(Context, *this, cast<VarDecl>(D),
- CodeGenOpts.NoCommon))
+ !CodeGenUtils::isVarDeclStrongDefinition(Context, cast<VarDecl>(D),
+ CodeGenOpts.NoCommon))
return llvm::GlobalVariable::CommonLinkage;
// selectany symbols are externally visible, so use weak instead of
diff --git a/clang/lib/CodeGenUtils/CMakeLists.txt b/clang/lib/CodeGenUtils/CMakeLists.txt
index e3328aa13c343..804ed682305ca 100644
--- a/clang/lib/CodeGenUtils/CMakeLists.txt
+++ b/clang/lib/CodeGenUtils/CMakeLists.txt
@@ -9,6 +9,7 @@ add_clang_library(clangCodeGenUtils
ExprUtils.cpp
FunctionUtils.cpp
ItaniumCXXABIUtils.cpp
+ ModuleUtils.cpp
LINK_LIBS
clangAST
diff --git a/clang/lib/CodeGenUtils/ModuleUtils.cpp b/clang/lib/CodeGenUtils/ModuleUtils.cpp
new file mode 100644
index 0000000000000..0d4882345e303
--- /dev/null
+++ b/clang/lib/CodeGenUtils/ModuleUtils.cpp
@@ -0,0 +1,114 @@
+//===--- ModuleUtils.cpp - Shared module emission queries -----------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/CodeGenUtils/ModuleUtils.h"
+#include "clang/AST/Attr.h"
+#include "clang/Basic/TargetInfo.h"
+
+namespace clang::CodeGenUtils {
+
+bool isVarDeclStrongDefinition(const ASTContext &Ctx, const VarDecl *D,
+ bool NoCommon) {
+ // Don't give variables common linkage if -fno-common was specified unless it
+ // was overridden by a NoCommon attribute.
+ if ((NoCommon || D->hasAttr<NoCommonAttr>()) && !D->hasAttr<CommonAttr>())
+ return true;
+
+ // C11 6.9.2/2:
+ // A declaration of an identifier for an object that has file scope without
+ // an initializer, and without a storage-class specifier or with the
+ // storage-class specifier static, constitutes a tentative definition.
+ if (D->getInit() || D->hasExternalStorage())
+ return true;
+
+ // A variable cannot be both common and exist in a section.
+ if (D->hasAttr<SectionAttr>())
+ return true;
+
+ // A variable cannot be both common and exist in a section.
+ // We don't try to determine which is the right section in the front-end.
+ // If no specialized section name is applicable, it will resort to default.
+ if (D->hasAttr<PragmaClangBSSSectionAttr>() ||
+ D->hasAttr<PragmaClangDataSectionAttr>() ||
+ D->hasAttr<PragmaClangRelroSectionAttr>() ||
+ D->hasAttr<PragmaClangRodataSectionAttr>())
+ return true;
+
+ // Thread local vars aren't considered common linkage.
+ if (D->getTLSKind())
+ return true;
+
+ // Tentative definitions marked with WeakImportAttr are true definitions.
+ if (D->hasAttr<WeakImportAttr>())
+ return true;
+
+ // A variable cannot be both common and exist in a comdat.
+ if (shouldBeInCOMDAT(Ctx, *D))
+ return true;
+
+ // Declarations with a required alignment do not have common linkage in MSVC
+ // mode.
+ if (Ctx.getTargetInfo().getCXXABI().isMicrosoft()) {
+ if (D->hasAttr<AlignedAttr>())
+ return true;
+ QualType VarType = D->getType();
+ if (Ctx.isAlignmentRequired(VarType))
+ return true;
+
+ if (const auto *RD = VarType->getAsRecordDecl()) {
+ for (const FieldDecl *FD : RD->fields()) {
+ if (FD->isBitField())
+ continue;
+ if (FD->hasAttr<AlignedAttr>())
+ return true;
+ if (Ctx.isAlignmentRequired(FD->getType()))
+ return true;
+ }
+ }
+ }
+
+ // Microsoft's link.exe doesn't support alignments greater than 32 bytes for
+ // common symbols, so symbols with greater alignment requirements cannot be
+ // common.
+ // Other COFF linkers (ld.bfd and LLD) support arbitrary power-of-two
+ // alignments for common symbols via the aligncomm directive, so this
+ // restriction only applies to MSVC environments.
+ if (Ctx.getTargetInfo().getTriple().isKnownWindowsMSVCEnvironment() &&
+ Ctx.getTypeAlignIfKnown(D->getType()) >
+ Ctx.toBits(CharUnits::fromQuantity(32)))
+ return true;
+
+ return false;
+}
+
+bool shouldBeInCOMDAT(const ASTContext &Ctx, const Decl &D) {
+ if (!Ctx.getTargetInfo().getTriple().supportsCOMDAT())
+ return false;
+
+ if (D.hasAttr<SelectAnyAttr>())
+ return true;
+
+ GVALinkage Linkage;
+ if (auto *VD = dyn_cast<VarDecl>(&D))
+ Linkage = Ctx.GetGVALinkageForVariable(VD);
+ else
+ Linkage = Ctx.GetGVALinkageForFunction(cast<FunctionDecl>(&D));
+
+ switch (Linkage) {
+ case GVA_Internal:
+ case GVA_AvailableExternally:
+ case GVA_StrongExternal:
+ return false;
+ case GVA_DiscardableODR:
+ case GVA_StrongODR:
+ return true;
+ }
+ llvm_unreachable("No such linkage");
+}
+
+} // namespace clang::CodeGenUtils
>From 2f4859cc5389730db80eedf2bc05a4a50949e640 Mon Sep 17 00:00:00 2001
From: Henrich Lauko <hlauko at nvidia.com>
Date: Mon, 14 Sep 2026 13:17:32 +0000
Subject: [PATCH 2/2] [CIR][CodeGen][NFC] Extract the EHPersonality struct into
CodeGenUtils
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).
---
.../clang/CodeGenUtils/EHPersonality.h | 65 +++++++++++++++++
clang/lib/CIR/CodeGen/CIRGenCleanup.h | 54 +++-----------
clang/lib/CIR/CodeGen/CIRGenException.cpp | 54 +++-----------
clang/lib/CodeGen/CGCall.cpp | 2 +-
clang/lib/CodeGen/CGCleanup.cpp | 2 +-
clang/lib/CodeGen/CGCleanup.h | 57 +++------------
clang/lib/CodeGen/CGException.cpp | 70 +++++--------------
clang/lib/CodeGen/CGObjCRuntime.cpp | 6 +-
clang/lib/CodeGen/ItaniumCXXABI.cpp | 2 +-
clang/lib/CodeGenUtils/CMakeLists.txt | 1 +
clang/lib/CodeGenUtils/EHPersonality.cpp | 49 +++++++++++++
11 files changed, 171 insertions(+), 191 deletions(-)
create mode 100644 clang/include/clang/CodeGenUtils/EHPersonality.h
create mode 100644 clang/lib/CodeGenUtils/EHPersonality.cpp
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 emitCatchPadBlock(CodeGenFunction &CGF, EHCatchScope &CatchScope) {
CGF.Builder.SetInsertPoint(Handler.Block);
- if (EHPersonality::get(CGF).isMSVCXXPersonality()) {
+ if (getEHPersonality(CGF).isMSVCXXPersonality()) {
CGF.Builder.CreateCatchPad(
CatchSwitch, {TypeInfo.RTTI, CGF.Builder.getInt32(TypeInfo.Flags),
llvm::Constant::getNullValue(CGF.VoidPtrTy)});
@@ -1122,9 +1090,9 @@ static void emitWasmCatchPadBlock(CodeGenFunction &CGF,
/// It is an invariant that the dispatch block already exists.
static void emitCatchDispatchBlock(CodeGenFunction &CGF,
EHCatchScope &catchScope) {
- if (EHPersonality::get(CGF).isWasmPersonality())
+ if (getEHPersonality(CGF).isWasmPersonality())
return emitWasmCatchPadBlock(CGF, catchScope);
- if (EHPersonality::get(CGF).usesFuncletPads())
+ if (getEHPersonality(CGF).usesFuncletPads())
return emitCatchPadBlock(CGF, catchScope);
llvm::BasicBlock *dispatchBlock = catchScope.getCachedEHDispatchBlock();
@@ -1269,7 +1237,7 @@ void CodeGenFunction::ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock) {
// each catch handler.
SaveAndRestore RestoreCurrentFuncletPad(CurrentFuncletPad);
llvm::BasicBlock *WasmCatchStartBlock = nullptr;
- if (EHPersonality::get(*this).isWasmPersonality()) {
+ if (getEHPersonality(*this).isWasmPersonality()) {
auto *CatchSwitch =
cast<llvm::CatchSwitchInst>(DispatchBlock->getFirstNonPHIIt());
WasmCatchStartBlock = CatchSwitch->hasUnwindDest()
@@ -1333,7 +1301,7 @@ void CodeGenFunction::ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock) {
Builder.CreateBr(ContBB);
}
- if (EHPersonality::get(*this).isWasmPersonality() && !HasCatchAll) {
+ if (getEHPersonality(*this).isWasmPersonality() && !HasCatchAll) {
WasmEmitFallthroughRethrow(WasmCatchStartBlock);
}
@@ -1543,7 +1511,7 @@ llvm::BasicBlock *CodeGenFunction::getTerminateLandingPad() {
Builder.SetInsertPoint(TerminateLandingPad);
// Tell the backend that this is a landing pad.
- const EHPersonality &Personality = EHPersonality::get(*this);
+ const EHPersonality &Personality = getEHPersonality(*this);
if (!CurFn->hasPersonalityFn())
CurFn->setPersonalityFn(getOpaquePersonalityFn(CGM, Personality));
@@ -1591,7 +1559,7 @@ llvm::BasicBlock *CodeGenFunction::getTerminateHandler() {
}
llvm::BasicBlock *CodeGenFunction::getTerminateFunclet() {
- assert(EHPersonality::get(*this).usesFuncletPads() &&
+ assert(getEHPersonality(*this).usesFuncletPads() &&
"use getTerminateLandingPad for non-funclet EH");
llvm::BasicBlock *&TerminateFunclet = TerminateFunclets[CurrentFuncletPad];
@@ -1634,7 +1602,7 @@ llvm::BasicBlock *CodeGenFunction::getEHResumeBlock(bool isCleanup) {
EHResumeBlock = createBasicBlock("eh.resume");
Builder.SetInsertPoint(EHResumeBlock);
- const EHPersonality &Personality = EHPersonality::get(*this);
+ const EHPersonality &Personality = getEHPersonality(*this);
// This can always be a call because we necessarily didn't find
// anything on the EH stack which needs our help.
diff --git a/clang/lib/CodeGen/CGObjCRuntime.cpp b/clang/lib/CodeGen/CGObjCRuntime.cpp
index 3935987144756..3a009a1b248d2 100644
--- a/clang/lib/CodeGen/CGObjCRuntime.cpp
+++ b/clang/lib/CodeGen/CGObjCRuntime.cpp
@@ -150,9 +150,9 @@ void CGObjCRuntime::EmitTryCatchStmt(CodeGenFunction &CGF,
if (S.getNumCatchStmts())
Cont = CGF.getJumpDestInCurrentScope("eh.cont");
- bool useFunclets = EHPersonality::get(CGF).usesFuncletPads();
- bool IsWasm = EHPersonality::get(CGF).isWasmPersonality();
- bool IsMSVC = EHPersonality::get(CGF).isMSVCPersonality();
+ bool useFunclets = getEHPersonality(CGF).usesFuncletPads();
+ bool IsWasm = getEHPersonality(CGF).isWasmPersonality();
+ bool IsMSVC = getEHPersonality(CGF).isMSVCPersonality();
CodeGenFunction::FinallyInfo FinallyInfo;
if (const ObjCAtFinallyStmt *Finally = S.getFinallyStmt()) {
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index 754511e6a7d41..6dbf3fbbb0b12 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -5266,7 +5266,7 @@ WebAssemblyCXXABI::emitTerminateForUnexpectedException(CodeGenFunction &CGF,
// and call __clang_call_terminate only in Emscripten EH.
// TODO Consider code transformation that makes calling __clang_call_terminate
// in Wasm EH possible.
- if (Exn && !EHPersonality::get(CGF).isWasmPersonality()) {
+ if (Exn && !getEHPersonality(CGF).isWasmPersonality()) {
assert(CGF.CGM.getLangOpts().CPlusPlus);
return CGF.EmitNounwindRuntimeCall(getClangCallTerminateFn(CGF.CGM), Exn);
}
diff --git a/clang/lib/CodeGenUtils/CMakeLists.txt b/clang/lib/CodeGenUtils/CMakeLists.txt
index 804ed682305ca..5839e8f2e1fe5 100644
--- a/clang/lib/CodeGenUtils/CMakeLists.txt
+++ b/clang/lib/CodeGenUtils/CMakeLists.txt
@@ -6,6 +6,7 @@ add_clang_library(clangCodeGenUtils
CallUtils.cpp
ClassUtils.cpp
CodeGenUtils.cpp
+ EHPersonality.cpp
ExprUtils.cpp
FunctionUtils.cpp
ItaniumCXXABIUtils.cpp
diff --git a/clang/lib/CodeGenUtils/EHPersonality.cpp b/clang/lib/CodeGenUtils/EHPersonality.cpp
new file mode 100644
index 0000000000000..ee9fe010c98a7
--- /dev/null
+++ b/clang/lib/CodeGenUtils/EHPersonality.cpp
@@ -0,0 +1,49 @@
+//===--- EHPersonality.cpp - Shared EH personality descriptions -----------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/CodeGenUtils/EHPersonality.h"
+
+namespace clang::CodeGenUtils {
+
+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};
+
+} // namespace clang::CodeGenUtils
More information about the cfe-commits
mailing list