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/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/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; 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..912c9b869bf7d 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 @@ -94,4 +97,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: 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/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/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 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;