From 33572eb9c918f88ea22ee51b73167ff9dec04aeb Mon Sep 17 00:00:00 2001 From: Andrew Rogers Date: Wed, 23 Jul 2025 15:39:58 -0700 Subject: [PATCH 1/6] [llvm] annotate ABIBreakingChecks symbols for DLL export (#149198) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Purpose This PR is a re-application of #145575 with independent definition of `ABI_BREAKING_EXPORT_ABI` that does not depend on `llvm/Support/Compiler.h`. It is one in a series of code-mods that annotate LLVM’s public interface for export. This patch annotates the ABI Breaking Checks interface in llvm/config. The annotations currently have no meaningful impact on the LLVM build; however, they are a prerequisite to support an LLVM Windows DLL (shared library) build. ## Background The effort to build LLVM as a Windows DLL is tracked in #109483. Additional context is provided in [this discourse](https://discourse.llvm.org/t/psa-annotating-llvm-public-interface/85307), and documentation for `LLVM_ABI` and related annotations is found in the LLVM repo [here](https://github.com/llvm/llvm-project/blob/main/llvm/docs/InterfaceExportAnnotations.rst). ## Validation Local builds and tests to validate cross-platform compatibility. This included llvm, clang, and lldb on the following configurations: - Windows with MSVC - Windows with Clang - Linux with GCC - Linux with Clang - Darwin with Clang --- llvm/include/llvm/Config/abi-breaking.h.cmake | 33 +++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/llvm/include/llvm/Config/abi-breaking.h.cmake b/llvm/include/llvm/Config/abi-breaking.h.cmake index 2d27e02b1d545..330f36011d231 100644 --- a/llvm/include/llvm/Config/abi-breaking.h.cmake +++ b/llvm/include/llvm/Config/abi-breaking.h.cmake @@ -12,12 +12,41 @@ #ifndef LLVM_ABI_BREAKING_CHECKS_H #define LLVM_ABI_BREAKING_CHECKS_H +// llvm-config.h is required for LLVM_ENABLE_LLVM_EXPORT_ANNOTATIONS +#include "llvm/Config/llvm-config.h" + /* Define to enable checks that alter the LLVM C++ ABI */ #cmakedefine01 LLVM_ENABLE_ABI_BREAKING_CHECKS /* Define to enable reverse iteration of unordered llvm containers */ #cmakedefine01 LLVM_ENABLE_REVERSE_ITERATION +#if !defined(__has_attribute) +#define __has_attribute(attribute) 0 +#endif + +// Properly annotate EnableABIBreakingChecks or DisableABIBreakingChecks for +// export from shared library. +// TODO(https://github.com/llvm/llvm-project/issues/145406): eliminate need for +// two preprocessor definitions to gate LLVM_ABI macro definitions. +#if defined(LLVM_BUILD_STATIC) || !defined(LLVM_ENABLE_LLVM_EXPORT_ANNOTATIONS) +#define ABI_BREAKING_EXPORT_ABI +#else +#if defined(_WIN32) +#if defined(LLVM_EXPORTS) +#define ABI_BREAKING_EXPORT_ABI __declspec(dllexport) +#else +#define ABI_BREAKING_EXPORT_ABI __declspec(dllimport) +#endif +#else +#if __has_attribute(visibility) +#define ABI_BREAKING_EXPORT_ABI __attribute__((__visibility__("default"))) +#else +#define ABI_BREAKING_EXPORT_ABI +#endif +#endif +#endif + /* Allow selectively disabling link-time mismatch checking so that header-only ADT content from LLVM can be used without linking libSupport. */ #if !defined(LLVM_DISABLE_ABI_BREAKING_CHECKS_ENFORCING) || !LLVM_DISABLE_ABI_BREAKING_CHECKS_ENFORCING @@ -43,12 +72,12 @@ #endif namespace llvm { #if LLVM_ENABLE_ABI_BREAKING_CHECKS -extern int EnableABIBreakingChecks; +ABI_BREAKING_EXPORT_ABI extern int EnableABIBreakingChecks; LLVM_HIDDEN_VISIBILITY __attribute__((weak)) int *VerifyEnableABIBreakingChecks = &EnableABIBreakingChecks; #else -extern int DisableABIBreakingChecks; +ABI_BREAKING_EXPORT_ABI extern int DisableABIBreakingChecks; LLVM_HIDDEN_VISIBILITY __attribute__((weak)) int *VerifyDisableABIBreakingChecks = &DisableABIBreakingChecks; From cddfe5b521a7bb21c74d169afcc879b5f2e7a3ae Mon Sep 17 00:00:00 2001 From: Andrew Rogers Date: Thu, 24 Jul 2025 03:50:16 -0700 Subject: [PATCH 2/6] [llvm] annotate interfaces in Demangle for DLL export (#147564) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Purpose This patch is one in a series of code-mods that annotate LLVM’s public interface for export. This patch annotates the `Demangle` interface with a new `DEMANGLE_ABI` annotation, which behaves like the `LLVM_ABI`. This annotation currently has no meaningful impact on the LLVM build; however, it is a prerequisite to support an LLVM Windows DLL (shared library) build. ## Overview 1. Add a new `Demangle/Visibility.h` header file that defines a new `DEMANGLE_ABI` macro. The macro resolves to the proper DLL export/import annotation on Windows and a "default" visibility annotation elsewhere. 2. Add a new `LLVM_ENABLE_DEMANGLE_EXPORT_ANNOTATIONS ` `#cmakedefine` that is used to gate the definition of `DEMANGLE_ABI`. 3. Code-mod annotate the public `Demangle` interface using the [Interface Definition Scanner (IDS)](https://github.com/compnerd/ids) tool. 4. Manually fix-up `#include` statements for consistency. 5. Format the changes with `clang-format`. 6. Add a "stub" version of `Visibility.h` under `libcxxabi/src/demangle` that always defines `DEMANGLE_ABI` to nothing. 7. Update the canonical `libcxxabi/src/demangle/ItaniumDemangle.h` instead of the llvm copy, and run `cp-to-llvm.sh` to ensure the llvm copy matches. NOTE: we rely on `ccp-to-llvm.sh` not copying `Visibillity.h` as is already the case for `DemangleConfig.h`. ## Background This PR follows the pattern established with the `llvm-c` changes made in #141701. This effort is tracked in #109483. Additional context is provided in [this discourse](https://discourse.llvm.org/t/psa-annotating-llvm-public-interface/85307), and documentation for `LLVM_ABI` and related annotations is found in the LLVM repo [here](https://github.com/llvm/llvm-project/blob/main/llvm/docs/InterfaceExportAnnotations.rst). ## Validation Local builds and tests to validate cross-platform compatibility. This included llvm, clang, and lldb on the following configurations: - Windows with MSVC - Windows with Clang - Linux with GCC - Linux with Clang - Darwin with Clang --------- Co-authored-by: Louis Dionne --- libcxxabi/src/demangle/DemangleConfig.h | 4 ++ libcxxabi/src/demangle/ItaniumDemangle.h | 3 +- llvm/include/llvm/Demangle/Demangle.h | 59 +++++++++--------- llvm/include/llvm/Demangle/DemangleConfig.h | 20 +++++++ llvm/include/llvm/Demangle/ItaniumDemangle.h | 3 +- .../include/llvm/Demangle/MicrosoftDemangle.h | 7 ++- .../llvm/Demangle/MicrosoftDemangleNodes.h | 60 ++++++++++--------- 7 files changed, 95 insertions(+), 61 deletions(-) diff --git a/libcxxabi/src/demangle/DemangleConfig.h b/libcxxabi/src/demangle/DemangleConfig.h index 7904e9d1eb133..79dbeb89cc28f 100644 --- a/libcxxabi/src/demangle/DemangleConfig.h +++ b/libcxxabi/src/demangle/DemangleConfig.h @@ -115,4 +115,8 @@ #define DEMANGLE_NAMESPACE_BEGIN namespace { namespace itanium_demangle { #define DEMANGLE_NAMESPACE_END } } +// The DEMANGLE_ABI macro resolves to nothing when building libc++abi. Only +// the llvm copy defines DEMANGLE_ABI as a visibility attribute. +#define DEMANGLE_ABI + #endif // LIBCXXABI_DEMANGLE_DEMANGLE_CONFIG_H diff --git a/libcxxabi/src/demangle/ItaniumDemangle.h b/libcxxabi/src/demangle/ItaniumDemangle.h index b306b2013445c..6f27da7b9cadf 100644 --- a/libcxxabi/src/demangle/ItaniumDemangle.h +++ b/libcxxabi/src/demangle/ItaniumDemangle.h @@ -3049,7 +3049,8 @@ template struct AbstractManglingParser { Node *parse(bool ParseParams = true); }; -const char* parse_discriminator(const char* first, const char* last); +DEMANGLE_ABI const char *parse_discriminator(const char *first, + const char *last); // ::= // N // ::= # See Scope Encoding below // Z diff --git a/llvm/include/llvm/Demangle/Demangle.h b/llvm/include/llvm/Demangle/Demangle.h index 21e7457b6336f..d9b08b2d856dc 100644 --- a/llvm/include/llvm/Demangle/Demangle.h +++ b/llvm/include/llvm/Demangle/Demangle.h @@ -9,6 +9,7 @@ #ifndef LLVM_DEMANGLE_DEMANGLE_H #define LLVM_DEMANGLE_DEMANGLE_H +#include "DemangleConfig.h" #include #include #include @@ -33,7 +34,8 @@ enum : int { /// Returns a non-NULL pointer to a NUL-terminated C style string /// that should be explicitly freed, if successful. Otherwise, may return /// nullptr if mangled_name is not a valid mangling or is nullptr. -char *itaniumDemangle(std::string_view mangled_name, bool ParseParams = true); +DEMANGLE_ABI char *itaniumDemangle(std::string_view mangled_name, + bool ParseParams = true); enum MSDemangleFlags { MSDF_None = 0, @@ -52,87 +54,90 @@ enum MSDemangleFlags { /// bytes of the input string were consumed. /// status receives one of the demangle_ enum entries above if it's not nullptr. /// Flags controls various details of the demangled representation. -char *microsoftDemangle(std::string_view mangled_name, size_t *n_read, - int *status, MSDemangleFlags Flags = MSDF_None); +DEMANGLE_ABI char *microsoftDemangle(std::string_view mangled_name, + size_t *n_read, int *status, + MSDemangleFlags Flags = MSDF_None); -std::optional +DEMANGLE_ABI std::optional getArm64ECInsertionPointInMangledName(std::string_view MangledName); // Demangles a Rust v0 mangled symbol. -char *rustDemangle(std::string_view MangledName); +DEMANGLE_ABI char *rustDemangle(std::string_view MangledName); // Demangles a D mangled symbol. -char *dlangDemangle(std::string_view MangledName); +DEMANGLE_ABI char *dlangDemangle(std::string_view MangledName); /// Attempt to demangle a string using different demangling schemes. /// The function uses heuristics to determine which demangling scheme to use. /// \param MangledName - reference to string to demangle. /// \returns - the demangled string, or a copy of the input string if no /// demangling occurred. -std::string demangle(std::string_view MangledName); +DEMANGLE_ABI std::string demangle(std::string_view MangledName); -bool nonMicrosoftDemangle(std::string_view MangledName, std::string &Result, - bool CanHaveLeadingDot = true, - bool ParseParams = true); +DEMANGLE_ABI bool nonMicrosoftDemangle(std::string_view MangledName, + std::string &Result, + bool CanHaveLeadingDot = true, + bool ParseParams = true); /// "Partial" demangler. This supports demangling a string into an AST /// (typically an intermediate stage in itaniumDemangle) and querying certain /// properties or partially printing the demangled name. struct ItaniumPartialDemangler { - ItaniumPartialDemangler(); + DEMANGLE_ABI ItaniumPartialDemangler(); - ItaniumPartialDemangler(ItaniumPartialDemangler &&Other); - ItaniumPartialDemangler &operator=(ItaniumPartialDemangler &&Other); + DEMANGLE_ABI ItaniumPartialDemangler(ItaniumPartialDemangler &&Other); + DEMANGLE_ABI ItaniumPartialDemangler & + operator=(ItaniumPartialDemangler &&Other); /// Demangle into an AST. Subsequent calls to the rest of the member functions /// implicitly operate on the AST this produces. /// \return true on error, false otherwise - bool partialDemangle(const char *MangledName); + DEMANGLE_ABI bool partialDemangle(const char *MangledName); /// Just print the entire mangled name into Buf. Buf and N behave like the /// second and third parameters to __cxa_demangle. - char *finishDemangle(char *Buf, size_t *N) const; + DEMANGLE_ABI char *finishDemangle(char *Buf, size_t *N) const; /// See \ref finishDemangle /// /// \param[in] OB A llvm::itanium_demangle::OutputBuffer that the demangled /// name will be printed into. /// - char *finishDemangle(void *OB) const; + DEMANGLE_ABI char *finishDemangle(void *OB) const; /// Get the base name of a function. This doesn't include trailing template /// arguments, ie for "a::b" this function returns "b". - char *getFunctionBaseName(char *Buf, size_t *N) const; + DEMANGLE_ABI char *getFunctionBaseName(char *Buf, size_t *N) const; /// Get the context name for a function. For "a::b::c", this function returns /// "a::b". - char *getFunctionDeclContextName(char *Buf, size_t *N) const; + DEMANGLE_ABI char *getFunctionDeclContextName(char *Buf, size_t *N) const; /// Get the entire name of this function. - char *getFunctionName(char *Buf, size_t *N) const; + DEMANGLE_ABI char *getFunctionName(char *Buf, size_t *N) const; /// Get the parameters for this function. - char *getFunctionParameters(char *Buf, size_t *N) const; - char *getFunctionReturnType(char *Buf, size_t *N) const; + DEMANGLE_ABI char *getFunctionParameters(char *Buf, size_t *N) const; + DEMANGLE_ABI char *getFunctionReturnType(char *Buf, size_t *N) const; /// If this function has any cv or reference qualifiers. These imply that /// the function is a non-static member function. - bool hasFunctionQualifiers() const; + DEMANGLE_ABI bool hasFunctionQualifiers() const; /// If this symbol describes a constructor or destructor. - bool isCtorOrDtor() const; + DEMANGLE_ABI bool isCtorOrDtor() const; /// If this symbol describes a function. - bool isFunction() const; + DEMANGLE_ABI bool isFunction() const; /// If this symbol describes a variable. - bool isData() const; + DEMANGLE_ABI bool isData() const; /// If this symbol is a . These are generally implicitly /// generated by the implementation, such as vtables and typeinfo names. - bool isSpecialName() const; + DEMANGLE_ABI bool isSpecialName() const; - ~ItaniumPartialDemangler(); + DEMANGLE_ABI ~ItaniumPartialDemangler(); private: void *RootNode; diff --git a/llvm/include/llvm/Demangle/DemangleConfig.h b/llvm/include/llvm/Demangle/DemangleConfig.h index 30f72ffe0d7ef..8807a0e597a17 100644 --- a/llvm/include/llvm/Demangle/DemangleConfig.h +++ b/llvm/include/llvm/Demangle/DemangleConfig.h @@ -94,4 +94,24 @@ #define DEMANGLE_NAMESPACE_BEGIN namespace llvm { namespace itanium_demangle { #define DEMANGLE_NAMESPACE_END } } +/// DEMANGLE_ABI is the export/visibility macro used to mark symbols delcared in +/// llvm/Demangle as exported when built as a shared library. +#if defined(LLVM_BUILD_STATIC) || !defined(LLVM_ENABLE_LLVM_EXPORT_ANNOTATIONS) +#define DEMANGLE_ABI +#else +#if defined(_WIN32) +#if defined(LLVM_EXPORTS) +#define DEMANGLE_ABI __declspec(dllexport) +#else +#define DEMANGLE_ABI__declspec(dllimport) +#endif +#else +#if __has_attribute(visibility) +#define DEMANGLE_ABI __attribute__((__visibility__("default"))) +#else +#define DEMANGLE_ABI +#endif +#endif +#endif + #endif diff --git a/llvm/include/llvm/Demangle/ItaniumDemangle.h b/llvm/include/llvm/Demangle/ItaniumDemangle.h index 5533652736dc8..62d427c3966bb 100644 --- a/llvm/include/llvm/Demangle/ItaniumDemangle.h +++ b/llvm/include/llvm/Demangle/ItaniumDemangle.h @@ -3049,7 +3049,8 @@ template struct AbstractManglingParser { Node *parse(bool ParseParams = true); }; -const char* parse_discriminator(const char* first, const char* last); +DEMANGLE_ABI const char *parse_discriminator(const char *first, + const char *last); // ::= // N // ::= # See Scope Encoding below // Z diff --git a/llvm/include/llvm/Demangle/MicrosoftDemangle.h b/llvm/include/llvm/Demangle/MicrosoftDemangle.h index b9a25e361eec0..a2af87537aa58 100644 --- a/llvm/include/llvm/Demangle/MicrosoftDemangle.h +++ b/llvm/include/llvm/Demangle/MicrosoftDemangle.h @@ -10,6 +10,7 @@ #define LLVM_DEMANGLE_MICROSOFTDEMANGLE_H #include "llvm/Demangle/Demangle.h" +#include "llvm/Demangle/DemangleConfig.h" #include "llvm/Demangle/MicrosoftDemangleNodes.h" #include @@ -151,14 +152,14 @@ class Demangler { // You are supposed to call parse() first and then check if error is true. If // it is false, call output() to write the formatted name to the given stream. - SymbolNode *parse(std::string_view &MangledName); + DEMANGLE_ABI SymbolNode *parse(std::string_view &MangledName); - TagTypeNode *parseTagUniqueName(std::string_view &MangledName); + DEMANGLE_ABI TagTypeNode *parseTagUniqueName(std::string_view &MangledName); // True if an error occurred. bool Error = false; - void dumpBackReferences(); + DEMANGLE_ABI void dumpBackReferences(); private: SymbolNode *demangleEncodedSymbol(std::string_view &MangledName, diff --git a/llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h b/llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h index a9cfe726a73d3..155cfe8dd3a98 100644 --- a/llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h +++ b/llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h @@ -13,6 +13,7 @@ #ifndef LLVM_DEMANGLE_MICROSOFTDEMANGLENODES_H #define LLVM_DEMANGLE_MICROSOFTDEMANGLENODES_H +#include "DemangleConfig.h" #include #include #include @@ -281,7 +282,7 @@ struct Node { virtual void output(OutputBuffer &OB, OutputFlags Flags) const = 0; - std::string toString(OutputFlags Flags = OF_Default) const; + DEMANGLE_ABI std::string toString(OutputFlags Flags = OF_Default) const; private: NodeKind Kind; @@ -332,7 +333,7 @@ struct TypeNode : public Node { Qualifiers Quals = Q_None; }; -struct PrimitiveTypeNode : public TypeNode { +struct DEMANGLE_ABI PrimitiveTypeNode : public TypeNode { explicit PrimitiveTypeNode(PrimitiveKind K) : TypeNode(NodeKind::PrimitiveType), PrimKind(K) {} @@ -346,7 +347,7 @@ struct PrimitiveTypeNode : public TypeNode { PrimitiveKind PrimKind; }; -struct FunctionSignatureNode : public TypeNode { +struct DEMANGLE_ABI FunctionSignatureNode : public TypeNode { explicit FunctionSignatureNode(NodeKind K) : TypeNode(K) {} FunctionSignatureNode() : TypeNode(NodeKind::FunctionSignature) {} @@ -394,10 +395,11 @@ struct IdentifierNode : public Node { NodeArrayNode *TemplateParams = nullptr; protected: - void outputTemplateParameters(OutputBuffer &OB, OutputFlags Flags) const; + DEMANGLE_ABI void outputTemplateParameters(OutputBuffer &OB, + OutputFlags Flags) const; }; -struct VcallThunkIdentifierNode : public IdentifierNode { +struct DEMANGLE_ABI VcallThunkIdentifierNode : public IdentifierNode { VcallThunkIdentifierNode() : IdentifierNode(NodeKind::VcallThunkIdentifier) {} void output(OutputBuffer &OB, OutputFlags Flags) const override; @@ -409,7 +411,7 @@ struct VcallThunkIdentifierNode : public IdentifierNode { uint64_t OffsetInVTable = 0; }; -struct DynamicStructorIdentifierNode : public IdentifierNode { +struct DEMANGLE_ABI DynamicStructorIdentifierNode : public IdentifierNode { DynamicStructorIdentifierNode() : IdentifierNode(NodeKind::DynamicStructorIdentifier) {} @@ -424,7 +426,7 @@ struct DynamicStructorIdentifierNode : public IdentifierNode { bool IsDestructor = false; }; -struct NamedIdentifierNode : public IdentifierNode { +struct DEMANGLE_ABI NamedIdentifierNode : public IdentifierNode { NamedIdentifierNode() : IdentifierNode(NodeKind::NamedIdentifier) {} void output(OutputBuffer &OB, OutputFlags Flags) const override; @@ -436,7 +438,7 @@ struct NamedIdentifierNode : public IdentifierNode { std::string_view Name; }; -struct IntrinsicFunctionIdentifierNode : public IdentifierNode { +struct DEMANGLE_ABI IntrinsicFunctionIdentifierNode : public IdentifierNode { explicit IntrinsicFunctionIdentifierNode(IntrinsicFunctionKind Operator) : IdentifierNode(NodeKind::IntrinsicFunctionIdentifier), Operator(Operator) {} @@ -450,7 +452,7 @@ struct IntrinsicFunctionIdentifierNode : public IdentifierNode { IntrinsicFunctionKind Operator; }; -struct LiteralOperatorIdentifierNode : public IdentifierNode { +struct DEMANGLE_ABI LiteralOperatorIdentifierNode : public IdentifierNode { LiteralOperatorIdentifierNode() : IdentifierNode(NodeKind::LiteralOperatorIdentifier) {} @@ -463,7 +465,7 @@ struct LiteralOperatorIdentifierNode : public IdentifierNode { std::string_view Name; }; -struct LocalStaticGuardIdentifierNode : public IdentifierNode { +struct DEMANGLE_ABI LocalStaticGuardIdentifierNode : public IdentifierNode { LocalStaticGuardIdentifierNode() : IdentifierNode(NodeKind::LocalStaticGuardIdentifier) {} @@ -477,7 +479,7 @@ struct LocalStaticGuardIdentifierNode : public IdentifierNode { uint32_t ScopeIndex = 0; }; -struct ConversionOperatorIdentifierNode : public IdentifierNode { +struct DEMANGLE_ABI ConversionOperatorIdentifierNode : public IdentifierNode { ConversionOperatorIdentifierNode() : IdentifierNode(NodeKind::ConversionOperatorIdentifier) {} @@ -491,7 +493,7 @@ struct ConversionOperatorIdentifierNode : public IdentifierNode { TypeNode *TargetType = nullptr; }; -struct StructorIdentifierNode : public IdentifierNode { +struct DEMANGLE_ABI StructorIdentifierNode : public IdentifierNode { StructorIdentifierNode() : IdentifierNode(NodeKind::StructorIdentifier) {} explicit StructorIdentifierNode(bool IsDestructor) : IdentifierNode(NodeKind::StructorIdentifier), @@ -508,7 +510,7 @@ struct StructorIdentifierNode : public IdentifierNode { bool IsDestructor = false; }; -struct ThunkSignatureNode : public FunctionSignatureNode { +struct DEMANGLE_ABI ThunkSignatureNode : public FunctionSignatureNode { ThunkSignatureNode() : FunctionSignatureNode(NodeKind::ThunkSignature) {} void outputPre(OutputBuffer &OB, OutputFlags Flags) const override; @@ -528,7 +530,7 @@ struct ThunkSignatureNode : public FunctionSignatureNode { ThisAdjustor ThisAdjust; }; -struct PointerTypeNode : public TypeNode { +struct DEMANGLE_ABI PointerTypeNode : public TypeNode { PointerTypeNode() : TypeNode(NodeKind::PointerType) {} void outputPre(OutputBuffer &OB, OutputFlags Flags) const override; void outputPost(OutputBuffer &OB, OutputFlags Flags) const override; @@ -550,7 +552,7 @@ struct PointerTypeNode : public TypeNode { TypeNode *Pointee = nullptr; }; -struct TagTypeNode : public TypeNode { +struct DEMANGLE_ABI TagTypeNode : public TypeNode { explicit TagTypeNode(TagKind Tag) : TypeNode(NodeKind::TagType), Tag(Tag) {} void outputPre(OutputBuffer &OB, OutputFlags Flags) const override; @@ -562,7 +564,7 @@ struct TagTypeNode : public TypeNode { TagKind Tag; }; -struct ArrayTypeNode : public TypeNode { +struct DEMANGLE_ABI ArrayTypeNode : public TypeNode { ArrayTypeNode() : TypeNode(NodeKind::ArrayType) {} void outputPre(OutputBuffer &OB, OutputFlags Flags) const override; @@ -591,7 +593,7 @@ struct IntrinsicNode : public TypeNode { } }; -struct CustomTypeNode : public TypeNode { +struct DEMANGLE_ABI CustomTypeNode : public TypeNode { CustomTypeNode() : TypeNode(NodeKind::Custom) {} void outputPre(OutputBuffer &OB, OutputFlags Flags) const override; @@ -602,7 +604,7 @@ struct CustomTypeNode : public TypeNode { IdentifierNode *Identifier = nullptr; }; -struct NodeArrayNode : public Node { +struct DEMANGLE_ABI NodeArrayNode : public Node { NodeArrayNode() : Node(NodeKind::NodeArray) {} void output(OutputBuffer &OB, OutputFlags Flags) const override; @@ -618,7 +620,7 @@ struct NodeArrayNode : public Node { size_t Count = 0; }; -struct QualifiedNameNode : public Node { +struct DEMANGLE_ABI QualifiedNameNode : public Node { QualifiedNameNode() : Node(NodeKind::QualifiedName) {} void output(OutputBuffer &OB, OutputFlags Flags) const override; @@ -635,7 +637,7 @@ struct QualifiedNameNode : public Node { } }; -struct TemplateParameterReferenceNode : public Node { +struct DEMANGLE_ABI TemplateParameterReferenceNode : public Node { TemplateParameterReferenceNode() : Node(NodeKind::TemplateParameterReference) {} @@ -653,7 +655,7 @@ struct TemplateParameterReferenceNode : public Node { bool IsMemberPointer = false; }; -struct IntegerLiteralNode : public Node { +struct DEMANGLE_ABI IntegerLiteralNode : public Node { IntegerLiteralNode() : Node(NodeKind::IntegerLiteral) {} IntegerLiteralNode(uint64_t Value, bool IsNegative) : Node(NodeKind::IntegerLiteral), Value(Value), IsNegative(IsNegative) {} @@ -668,7 +670,7 @@ struct IntegerLiteralNode : public Node { bool IsNegative = false; }; -struct RttiBaseClassDescriptorNode : public IdentifierNode { +struct DEMANGLE_ABI RttiBaseClassDescriptorNode : public IdentifierNode { RttiBaseClassDescriptorNode() : IdentifierNode(NodeKind::RttiBaseClassDescriptor) {} @@ -684,7 +686,7 @@ struct RttiBaseClassDescriptorNode : public IdentifierNode { uint32_t Flags = 0; }; -struct SymbolNode : public Node { +struct DEMANGLE_ABI SymbolNode : public Node { explicit SymbolNode(NodeKind K) : Node(K) {} void output(OutputBuffer &OB, OutputFlags Flags) const override; @@ -696,7 +698,7 @@ struct SymbolNode : public Node { QualifiedNameNode *Name = nullptr; }; -struct SpecialTableSymbolNode : public SymbolNode { +struct DEMANGLE_ABI SpecialTableSymbolNode : public SymbolNode { explicit SpecialTableSymbolNode() : SymbolNode(NodeKind::SpecialTableSymbol) {} @@ -710,7 +712,7 @@ struct SpecialTableSymbolNode : public SymbolNode { Qualifiers Quals = Qualifiers::Q_None; }; -struct LocalStaticGuardVariableNode : public SymbolNode { +struct DEMANGLE_ABI LocalStaticGuardVariableNode : public SymbolNode { LocalStaticGuardVariableNode() : SymbolNode(NodeKind::LocalStaticGuardVariable) {} @@ -723,7 +725,7 @@ struct LocalStaticGuardVariableNode : public SymbolNode { bool IsVisible = false; }; -struct EncodedStringLiteralNode : public SymbolNode { +struct DEMANGLE_ABI EncodedStringLiteralNode : public SymbolNode { EncodedStringLiteralNode() : SymbolNode(NodeKind::EncodedStringLiteral) {} void output(OutputBuffer &OB, OutputFlags Flags) const override; @@ -737,7 +739,7 @@ struct EncodedStringLiteralNode : public SymbolNode { CharKind Char = CharKind::Char; }; -struct VariableSymbolNode : public SymbolNode { +struct DEMANGLE_ABI VariableSymbolNode : public SymbolNode { VariableSymbolNode() : SymbolNode(NodeKind::VariableSymbol) {} void output(OutputBuffer &OB, OutputFlags Flags) const override; @@ -750,7 +752,7 @@ struct VariableSymbolNode : public SymbolNode { TypeNode *Type = nullptr; }; -struct FunctionSymbolNode : public SymbolNode { +struct DEMANGLE_ABI FunctionSymbolNode : public SymbolNode { FunctionSymbolNode() : SymbolNode(NodeKind::FunctionSymbol) {} void output(OutputBuffer &OB, OutputFlags Flags) const override; @@ -762,7 +764,7 @@ struct FunctionSymbolNode : public SymbolNode { FunctionSignatureNode *Signature = nullptr; }; -struct PointerAuthQualifierNode : public Node { +struct DEMANGLE_ABI PointerAuthQualifierNode : public Node { PointerAuthQualifierNode() : Node(NodeKind::PointerAuthQualifier) {} // __ptrauth takes three arguments: From 451771bb04b9bb67918f89a1e05cba7fd3685b1c Mon Sep 17 00:00:00 2001 From: Andrew Rogers Date: Thu, 24 Jul 2025 11:03:58 -0700 Subject: [PATCH 3/6] [llvm] get cl::opt instantiations working with MSVC DLL build (#147810) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Purpose This patch is one in a series of code-mods that annotate LLVM’s public interface for export. This patch annotates the `llvm::cl::opt` explicit template instantiations for export with `LLVM_TEMPLATE_ABI` and `LLVM_EXPORT_TEMPLATE`. This annotation currently has no meaningful impact on the LLVM build; however, it is a prerequisite to support an LLVM Windows DLL (shared library) build. ## Background This effort is tracked in #109483. Additional context is provided in [this discourse](https://discourse.llvm.org/t/psa-annotating-llvm-public-interface/85307), and documentation for `LLVM_ABI` and related annotations is found in the LLVM repo [here](https://github.com/llvm/llvm-project/blob/main/llvm/docs/InterfaceExportAnnotations.rst). Annotating the `llvm::cl::opt` template instances for DLL export was not straight-forward like other explicit template instances that have already been annotated. Annotating them as documented [here](https://github.com/llvm/llvm-project/blob/main/llvm/docs/InterfaceExportAnnotations.rst#templates) results in link errors when building a Windows DLL using MSVC. ## Overview There are two specific issues that appear when exporting the `llvm::cl::opt` templates and compiling a Windows DLL with MSVC: 1. We cannot export `opt`. This is because MSVC exports all ancestor classes when exporting an instantiated template class. Since one of `opt`'s ancestor classes is its type argument (via `opt_storage`), it is an ancestor of `std::string`. Therefore, if we export `opt` from the LLVM DLL, MSVC forces `std::basic_string` to also be exported. This leads to duplicate symbol errors and generally seems like a bad idea. Compiling with `clang-cl` does not exhibit this behavior. 2. The `opt` template instances other than `opt` get optimized out because they are not referenced in the TU (`opt` actually is). It is unclear exactly why MSVC optimizes these template instances away, but `clang-cl` does not. Adding explicit references to the instantiated `opt` template classes' vtables via implicit virtual destructor forces MSVC to export them. ## Validation Windows with MSVC Windows with Clang --- llvm/include/llvm/Support/CommandLine.h | 17 +++++++++++----- llvm/lib/Support/CommandLine.cpp | 27 ++++++++++++++++++++----- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/llvm/include/llvm/Support/CommandLine.h b/llvm/include/llvm/Support/CommandLine.h index adaa75cc6c348..ca725b8ac8712 100644 --- a/llvm/include/llvm/Support/CommandLine.h +++ b/llvm/include/llvm/Support/CommandLine.h @@ -1518,11 +1518,18 @@ class opt [](const typename ParserClass::parser_data_type &) {}; }; -extern template class opt; -extern template class opt; -extern template class opt; -extern template class opt; -extern template class opt; +#if !(defined(LLVM_ENABLE_LLVM_EXPORT_ANNOTATIONS) && defined(_MSC_VER)) +// Only instantiate opt when not building a Windows DLL. When +// exporting opt, MSVC implicitly exports symbols for +// std::basic_string through transitive inheritance via std::string. These +// symbols may appear in clients, leading to duplicate symbol conflicts. +extern template class LLVM_TEMPLATE_ABI opt; +#endif + +extern template class LLVM_TEMPLATE_ABI opt; +extern template class LLVM_TEMPLATE_ABI opt; +extern template class LLVM_TEMPLATE_ABI opt; +extern template class LLVM_TEMPLATE_ABI opt; //===----------------------------------------------------------------------===// // Default storage class definition: external storage. This implementation diff --git a/llvm/lib/Support/CommandLine.cpp b/llvm/lib/Support/CommandLine.cpp index d5c3cba13e030..8491633df97e8 100644 --- a/llvm/lib/Support/CommandLine.cpp +++ b/llvm/lib/Support/CommandLine.cpp @@ -68,11 +68,19 @@ template class LLVM_EXPORT_TEMPLATE basic_parser; template class LLVM_EXPORT_TEMPLATE basic_parser; template class LLVM_EXPORT_TEMPLATE basic_parser; -template class opt; -template class opt; -template class opt; -template class opt; -template class opt; +#if !(defined(LLVM_ENABLE_LLVM_EXPORT_ANNOTATIONS) && defined(_MSC_VER)) +// Only instantiate opt when not building a Windows DLL. When +// exporting opt, MSVC implicitly exports symbols for +// std::basic_string through transitive inheritance via std::string. These +// symbols may appear in clients, leading to duplicate symbol conflicts. +template class LLVM_EXPORT_TEMPLATE opt; +#endif + +template class LLVM_EXPORT_TEMPLATE opt; +template class LLVM_EXPORT_TEMPLATE opt; +template class LLVM_EXPORT_TEMPLATE opt; +template class LLVM_EXPORT_TEMPLATE opt; + } // namespace cl } // namespace llvm @@ -95,6 +103,15 @@ void parser::anchor() {} void parser::anchor() {} void parser::anchor() {} +// These anchor functions instantiate opt and reference its virtual +// destructor to ensure MSVC exports the corresponding vtable and typeinfo when +// building a Windows DLL. Without an explicit reference, MSVC may omit the +// instantiation at link time even if it is marked DLL-export. +void opt_bool_anchor() { opt anchor{""}; } +void opt_char_anchor() { opt anchor{""}; } +void opt_int_anchor() { opt anchor{""}; } +void opt_unsigned_anchor() { opt anchor{""}; } + //===----------------------------------------------------------------------===// const static size_t DefaultPad = 2; From 69d6cb821e3ccb80d0aabf78742145a5290cfa1f Mon Sep 17 00:00:00 2001 From: Andrew Rogers Date: Mon, 28 Jul 2025 17:44:09 -0700 Subject: [PATCH 4/6] [llvm] ensure DEMANGLE_ABI is properly defined (#151023) ## Overview Include `llvm-config.h` from `DemangleConfig.h` so `LLVM_ENABLE_LLVM_EXPORT_ANNOTATIONS` is defined correctly. The presence of this definition controls the definition of `LLVM_ABI` on Windows DLL builds. This include was missed in #147564. ## Background This effort is tracked in #109483. Additional context is provided in [this discourse](https://discourse.llvm.org/t/psa-annotating-llvm-public-interface/85307). --- llvm/include/llvm/Demangle/DemangleConfig.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/llvm/include/llvm/Demangle/DemangleConfig.h b/llvm/include/llvm/Demangle/DemangleConfig.h index 8807a0e597a17..93cf3edc87471 100644 --- a/llvm/include/llvm/Demangle/DemangleConfig.h +++ b/llvm/include/llvm/Demangle/DemangleConfig.h @@ -15,6 +15,9 @@ #ifndef LLVM_DEMANGLE_DEMANGLECONFIG_H #define LLVM_DEMANGLE_DEMANGLECONFIG_H +// llvm-config.h is required for LLVM_ENABLE_LLVM_EXPORT_ANNOTATIONS +#include "llvm/Config/llvm-config.h" + #ifndef __has_feature #define __has_feature(x) 0 #endif From fbf8ad71f631ccfac08e49c6c10eedcf7d7874fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Fri, 25 Jul 2025 13:04:36 +0300 Subject: [PATCH 5/6] [llvm] [Demangle] Fix a typo in the definition of DEMANGLE_ABI for dllimport This fixes a typo from 04f5198e3ecb5592cec3297a782b8179f95434bf, fixing building for mingw targets with dylib enabled. --- llvm/include/llvm/Demangle/DemangleConfig.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/include/llvm/Demangle/DemangleConfig.h b/llvm/include/llvm/Demangle/DemangleConfig.h index 93cf3edc87471..912c9b869bf7d 100644 --- a/llvm/include/llvm/Demangle/DemangleConfig.h +++ b/llvm/include/llvm/Demangle/DemangleConfig.h @@ -106,7 +106,7 @@ #if defined(LLVM_EXPORTS) #define DEMANGLE_ABI __declspec(dllexport) #else -#define DEMANGLE_ABI__declspec(dllimport) +#define DEMANGLE_ABI __declspec(dllimport) #endif #else #if __has_attribute(visibility) From 32ffe48a9fcefaf39dc1a913b06ab6d83cb2b407 Mon Sep 17 00:00:00 2001 From: Andrew Rogers Date: Tue, 29 Jul 2025 08:32:07 -0700 Subject: [PATCH 6/6] [llvm] annotate recently added interfaces for DLL export (#150101) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch is one in a series of code-mods that annotate LLVM’s public interface for export. This patch annotates symbols that were recently added to LLVM without proper annotations. The annotations currently have no meaningful impact on the LLVM build; however, they are a prerequisite to support an LLVM Windows DLL (shared library) build. This effort is tracked in #109483. Additional context is provided in [this discourse](https://discourse.llvm.org/t/psa-annotating-llvm-public-interface/85307), and documentation for `LLVM_ABI` and related annotations is found in the LLVM repo [here](https://github.com/llvm/llvm-project/blob/main/llvm/docs/InterfaceExportAnnotations.rst). The bulk of these changes were generated automatically using the [Interface Definition Scanner (IDS)](https://github.com/compnerd/ids) tool, followed formatting with `git clang-format`. The following manual adjustments were also applied after running IDS: - Add `LLVM_EXPORT_TEMPLATE` and `LLVM_TEMPLATE_ABI` annotations to explicitly instantiated instances of `llvm::object::SFrameParser`. Local builds and tests to validate cross-platform compatibility. This included llvm, clang, and lldb on the following configurations: - Windows with MSVC - Windows with Clang - Linux with GCC - Linux with Clang - Darwin with Clang --- llvm/include/llvm/Analysis/IR2Vec.h | 30 +++++++++---------- llvm/include/llvm/CodeGen/GCMetadata.h | 28 ++++++++--------- .../ExecutionEngine/Orc/EPCIndirectionUtils.h | 19 ++++++------ .../ExecutionEngine/Orc/SpeculateAnalyses.h | 9 +++--- llvm/include/llvm/IR/GCStrategy.h | 5 ++-- .../llvm/MC/DXContainerRootSignature.h | 5 ++-- llvm/include/llvm/TextAPI/SymbolSet.h | 2 +- .../llvm/Transforms/Scalar/Reassociate.h | 3 +- llvm/include/llvm/Transforms/Utils/Mem2Reg.h | 3 +- 9 files changed, 55 insertions(+), 49 deletions(-) diff --git a/llvm/include/llvm/Analysis/IR2Vec.h b/llvm/include/llvm/Analysis/IR2Vec.h index 3d7edf08c8807..075e2bab768d5 100644 --- a/llvm/include/llvm/Analysis/IR2Vec.h +++ b/llvm/include/llvm/Analysis/IR2Vec.h @@ -164,28 +164,28 @@ class Vocabulary { public: Vocabulary() = default; - Vocabulary(VocabVector &&Vocab); + LLVM_ABI Vocabulary(VocabVector &&Vocab); - bool isValid() const; - unsigned getDimension() const; - size_t size() const; + LLVM_ABI bool isValid() const; + LLVM_ABI unsigned getDimension() const; + LLVM_ABI size_t size() const; /// Helper function to get vocabulary key for a given Opcode - static StringRef getVocabKeyForOpcode(unsigned Opcode); + LLVM_ABI static StringRef getVocabKeyForOpcode(unsigned Opcode); /// Helper function to get vocabulary key for a given TypeID - static StringRef getVocabKeyForTypeID(Type::TypeID TypeID); + LLVM_ABI static StringRef getVocabKeyForTypeID(Type::TypeID TypeID); /// Helper function to get vocabulary key for a given OperandKind - static StringRef getVocabKeyForOperandKind(OperandKind Kind); + LLVM_ABI static StringRef getVocabKeyForOperandKind(OperandKind Kind); /// Helper function to classify an operand into OperandKind - static OperandKind getOperandKind(const Value *Op); + LLVM_ABI static OperandKind getOperandKind(const Value *Op); /// Accessors to get the embedding for a given entity. - const ir2vec::Embedding &operator[](unsigned Opcode) const; - const ir2vec::Embedding &operator[](Type::TypeID TypeId) const; - const ir2vec::Embedding &operator[](const Value *Arg) const; + LLVM_ABI const ir2vec::Embedding &operator[](unsigned Opcode) const; + LLVM_ABI const ir2vec::Embedding &operator[](Type::TypeID TypeId) const; + LLVM_ABI const ir2vec::Embedding &operator[](const Value *Arg) const; /// Const Iterator type aliases using const_iterator = VocabVector::const_iterator; @@ -212,13 +212,13 @@ class Vocabulary { /// Returns the string key for a given index position in the vocabulary. /// This is useful for debugging or printing the vocabulary. Do not use this /// for embedding generation as string based lookups are inefficient. - static StringRef getStringKey(unsigned Pos); + LLVM_ABI static StringRef getStringKey(unsigned Pos); /// Create a dummy vocabulary for testing purposes. - static VocabVector createDummyVocabForTest(unsigned Dim = 1); + LLVM_ABI static VocabVector createDummyVocabForTest(unsigned Dim = 1); - bool invalidate(Module &M, const PreservedAnalyses &PA, - ModuleAnalysisManager::Invalidator &Inv) const; + LLVM_ABI bool invalidate(Module &M, const PreservedAnalyses &PA, + ModuleAnalysisManager::Invalidator &Inv) const; }; /// Embedder provides the interface to generate embeddings (vector diff --git a/llvm/include/llvm/CodeGen/GCMetadata.h b/llvm/include/llvm/CodeGen/GCMetadata.h index 33f5301e68dcb..5b9ee2869aa1b 100644 --- a/llvm/include/llvm/CodeGen/GCMetadata.h +++ b/llvm/include/llvm/CodeGen/GCMetadata.h @@ -101,12 +101,12 @@ class GCFunctionInfo { // are live per safe point (1.5% on 64-bit hosts). public: - GCFunctionInfo(const Function &F, GCStrategy &S); - ~GCFunctionInfo(); + LLVM_ABI GCFunctionInfo(const Function &F, GCStrategy &S); + LLVM_ABI ~GCFunctionInfo(); /// Handle invalidation explicitly. - bool invalidate(Function &F, const PreservedAnalyses &PA, - FunctionAnalysisManager::Invalidator &Inv); + LLVM_ABI bool invalidate(Function &F, const PreservedAnalyses &PA, + FunctionAnalysisManager::Invalidator &Inv); /// getFunction - Return the function to which this metadata applies. const Function &getFunction() const { return F; } @@ -163,8 +163,8 @@ class GCStrategyMap { GCStrategyMap(GCStrategyMap &&) = default; /// Handle invalidation explicitly. - bool invalidate(Module &M, const PreservedAnalyses &PA, - ModuleAnalysisManager::Invalidator &Inv); + LLVM_ABI bool invalidate(Module &M, const PreservedAnalyses &PA, + ModuleAnalysisManager::Invalidator &Inv); using iterator = MapT::iterator; using const_iterator = MapT::const_iterator; @@ -205,7 +205,7 @@ class CollectorMetadataAnalysis public: using Result = GCStrategyMap; - Result run(Module &M, ModuleAnalysisManager &MAM); + LLVM_ABI Result run(Module &M, ModuleAnalysisManager &MAM); }; /// An analysis pass which caches information about the Function. @@ -217,7 +217,7 @@ class GCFunctionAnalysis : public AnalysisInfoMixin { public: using Result = GCFunctionInfo; - Result run(Function &F, FunctionAnalysisManager &FAM); + LLVM_ABI Result run(Function &F, FunctionAnalysisManager &FAM); }; /// LowerIntrinsics - This pass rewrites calls to the llvm.gcread or @@ -228,7 +228,7 @@ class GCFunctionAnalysis : public AnalysisInfoMixin { /// This pass requires `CollectorMetadataAnalysis`. class GCLoweringPass : public PassInfoMixin { public: - PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM); + LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM); }; /// An analysis pass which caches information about the entire Module. @@ -244,7 +244,7 @@ class GCModuleInfo : public ImmutablePass { /// Lookup the GCStrategy object associated with the given gc name. /// Objects are owned internally; No caller should attempt to delete the /// returned objects. - GCStrategy *getGCStrategy(const StringRef Name); + LLVM_ABI GCStrategy *getGCStrategy(const StringRef Name); /// List of per function info objects. In theory, Each of these /// may be associated with a different GC. @@ -265,14 +265,14 @@ class GCModuleInfo : public ImmutablePass { public: using iterator = SmallVector, 1>::const_iterator; - static char ID; + LLVM_ABI static char ID; - GCModuleInfo(); + LLVM_ABI GCModuleInfo(); /// clear - Resets the pass. Any pass, which uses GCModuleInfo, should /// call it in doFinalization(). /// - void clear(); + LLVM_ABI void clear(); /// begin/end - Iterators for used strategies. /// @@ -282,7 +282,7 @@ class GCModuleInfo : public ImmutablePass { /// get - Look up function metadata. This is currently assumed /// have the side effect of initializing the associated GCStrategy. That /// will soon change. - GCFunctionInfo &getFunctionInfo(const Function &F); + LLVM_ABI GCFunctionInfo &getFunctionInfo(const Function &F); }; } // end namespace llvm diff --git a/llvm/include/llvm/ExecutionEngine/Orc/EPCIndirectionUtils.h b/llvm/include/llvm/ExecutionEngine/Orc/EPCIndirectionUtils.h index 2834331b21f20..b865e0205b672 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/EPCIndirectionUtils.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/EPCIndirectionUtils.h @@ -17,6 +17,7 @@ #include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h" #include "llvm/ExecutionEngine/Orc/IndirectionUtils.h" #include "llvm/ExecutionEngine/Orc/LazyReexports.h" +#include "llvm/Support/Compiler.h" #include @@ -33,7 +34,7 @@ class EPCIndirectionUtils { public: /// ABI support base class. Used to write resolver, stub, and trampoline /// blocks. - class ABISupport { + class LLVM_ABI ABISupport { protected: ABISupport(unsigned PointerSize, unsigned TrampolineSize, unsigned StubSize, unsigned StubToPointerMaxDisplacement, unsigned ResolverCodeSize) @@ -81,7 +82,7 @@ class EPCIndirectionUtils { CreateWithABI(ExecutorProcessControl &EPC); /// Create based on the ExecutorProcessControl triple. - static Expected> + LLVM_ABI static Expected> Create(ExecutorProcessControl &EPC); /// Create based on the ExecutorProcessControl triple. @@ -98,27 +99,27 @@ class EPCIndirectionUtils { /// Release memory for resources held by this instance. This *must* be called /// prior to destruction of the class. - Error cleanup(); + LLVM_ABI Error cleanup(); /// Write resolver code to the executor process and return its address. /// This must be called before any call to createTrampolinePool or /// createLazyCallThroughManager. - Expected writeResolverBlock(ExecutorAddr ReentryFnAddr, - ExecutorAddr ReentryCtxAddr); + LLVM_ABI Expected + writeResolverBlock(ExecutorAddr ReentryFnAddr, ExecutorAddr ReentryCtxAddr); /// Returns the address of the Resolver block. Returns zero if the /// writeResolverBlock method has not previously been called. ExecutorAddr getResolverBlockAddress() const { return ResolverBlockAddr; } /// Create an IndirectStubsManager for the executor process. - std::unique_ptr createIndirectStubsManager(); + LLVM_ABI std::unique_ptr createIndirectStubsManager(); /// Create a TrampolinePool for the executor process. - TrampolinePool &getTrampolinePool(); + LLVM_ABI TrampolinePool &getTrampolinePool(); /// Create a LazyCallThroughManager. /// This function should only be called once. - LazyCallThroughManager & + LLVM_ABI LazyCallThroughManager & createLazyCallThroughManager(ExecutionSession &ES, ExecutorAddr ErrorHandlerAddr); @@ -170,7 +171,7 @@ class EPCIndirectionUtils { /// called. /// /// This function is experimental and likely subject to revision. -Error setUpInProcessLCTMReentryViaEPCIU(EPCIndirectionUtils &EPCIU); +LLVM_ABI Error setUpInProcessLCTMReentryViaEPCIU(EPCIndirectionUtils &EPCIU); namespace detail { diff --git a/llvm/include/llvm/ExecutionEngine/Orc/SpeculateAnalyses.h b/llvm/include/llvm/ExecutionEngine/Orc/SpeculateAnalyses.h index c92719e9f5296..a9f5c45f8b116 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/SpeculateAnalyses.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/SpeculateAnalyses.h @@ -16,6 +16,7 @@ #include "llvm/Analysis/BranchProbabilityInfo.h" #include "llvm/ExecutionEngine/Orc/Core.h" #include "llvm/ExecutionEngine/Orc/Speculation.h" +#include "llvm/Support/Compiler.h" namespace llvm { @@ -24,8 +25,8 @@ namespace orc { // Provides common code. class SpeculateQuery { protected: - void findCalles(const BasicBlock *, DenseSet &); - bool isStraightLine(const Function &F); + LLVM_ABI void findCalles(const BasicBlock *, DenseSet &); + LLVM_ABI bool isStraightLine(const Function &F); public: using ResultTy = std::optional>>; @@ -37,7 +38,7 @@ class BlockFreqQuery : public SpeculateQuery { public: // Find likely next executables based on IR Block Frequency - ResultTy operator()(Function &F); + LLVM_ABI ResultTy operator()(Function &F); }; // This Query generates a sequence of basic blocks which follows the order of @@ -73,7 +74,7 @@ class SequenceBBQuery : public SpeculateQuery { VisitedBlocksInfoTy &); public: - ResultTy operator()(Function &F); + LLVM_ABI ResultTy operator()(Function &F); }; } // namespace orc diff --git a/llvm/include/llvm/IR/GCStrategy.h b/llvm/include/llvm/IR/GCStrategy.h index 6b813554d6544..44e46e448b3e3 100644 --- a/llvm/include/llvm/IR/GCStrategy.h +++ b/llvm/include/llvm/IR/GCStrategy.h @@ -47,6 +47,7 @@ #ifndef LLVM_IR_GCSTRATEGY_H #define LLVM_IR_GCSTRATEGY_H +#include "llvm/Support/Compiler.h" #include "llvm/Support/Registry.h" #include #include @@ -81,7 +82,7 @@ class GCStrategy { bool UsesMetadata = false; ///< If set, backend must emit metadata tables. public: - GCStrategy(); + LLVM_ABI GCStrategy(); virtual ~GCStrategy() = default; /// Return the name of the GC strategy. This is the value of the collector @@ -145,7 +146,7 @@ using GCRegistry = Registry; extern template class LLVM_TEMPLATE_ABI Registry; /// Lookup the GCStrategy object associated with the given gc name. -std::unique_ptr getGCStrategy(const StringRef Name); +LLVM_ABI std::unique_ptr getGCStrategy(const StringRef Name); } // end namespace llvm diff --git a/llvm/include/llvm/MC/DXContainerRootSignature.h b/llvm/include/llvm/MC/DXContainerRootSignature.h index 4b6b42f7d74f7..9fb40c6b578e2 100644 --- a/llvm/include/llvm/MC/DXContainerRootSignature.h +++ b/llvm/include/llvm/MC/DXContainerRootSignature.h @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "llvm/BinaryFormat/DXContainer.h" +#include "llvm/Support/Compiler.h" #include #include @@ -110,9 +111,9 @@ struct RootSignatureDesc { mcdxbc::RootParametersContainer ParametersContainer; SmallVector StaticSamplers; - void write(raw_ostream &OS) const; + LLVM_ABI void write(raw_ostream &OS) const; - size_t getSize() const; + LLVM_ABI size_t getSize() const; }; } // namespace mcdxbc } // namespace llvm diff --git a/llvm/include/llvm/TextAPI/SymbolSet.h b/llvm/include/llvm/TextAPI/SymbolSet.h index a04cb350b8f58..42c411acb6f9d 100644 --- a/llvm/include/llvm/TextAPI/SymbolSet.h +++ b/llvm/include/llvm/TextAPI/SymbolSet.h @@ -92,7 +92,7 @@ class SymbolSet { public: SymbolSet() = default; - ~SymbolSet(); + LLVM_ABI ~SymbolSet(); LLVM_ABI Symbol *addGlobal(EncodeKind Kind, StringRef Name, SymbolFlags Flags, const Target &Targ); size_t size() const { return Symbols.size(); } diff --git a/llvm/include/llvm/Transforms/Scalar/Reassociate.h b/llvm/include/llvm/Transforms/Scalar/Reassociate.h index a5d137661e11e..749f6ee34346d 100644 --- a/llvm/include/llvm/Transforms/Scalar/Reassociate.h +++ b/llvm/include/llvm/Transforms/Scalar/Reassociate.h @@ -28,6 +28,7 @@ #include "llvm/IR/BasicBlock.h" #include "llvm/IR/PassManager.h" #include "llvm/IR/ValueHandle.h" +#include "llvm/Support/Compiler.h" #include namespace llvm { @@ -96,7 +97,7 @@ class ReassociatePass : public PassInfoMixin { bool MadeChange; public: - PreservedAnalyses run(Function &F, FunctionAnalysisManager &); + LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &); private: void BuildRankMap(Function &F, ReversePostOrderTraversal &RPOT); diff --git a/llvm/include/llvm/Transforms/Utils/Mem2Reg.h b/llvm/include/llvm/Transforms/Utils/Mem2Reg.h index 76c1c2c5bffec..d0006bf162f25 100644 --- a/llvm/include/llvm/Transforms/Utils/Mem2Reg.h +++ b/llvm/include/llvm/Transforms/Utils/Mem2Reg.h @@ -15,6 +15,7 @@ #define LLVM_TRANSFORMS_UTILS_MEM2REG_H #include "llvm/IR/PassManager.h" +#include "llvm/Support/Compiler.h" namespace llvm { @@ -22,7 +23,7 @@ class Function; class PromotePass : public PassInfoMixin { public: - PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); + LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); }; } // end namespace llvm