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 <[email protected]> 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 <[email protected]> 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 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
