https://github.com/Steelskin updated https://github.com/llvm/llvm-project/pull/206750
>From 0ce298ac58208671a78f65bba7d10e44c77642a1 Mon Sep 17 00:00:00 2001 From: Fabrice de Gans <[email protected]> Date: Thu, 25 Jun 2026 11:45:34 +0200 Subject: [PATCH] [Registry] Support static clang registries The plugin Registry macros hard-code `LLVM_ABI_EXPORT` (unconditional dllexport) on `getRegistryLinkListInstance`. When clang is built statically (`CLANG_LINK_CLANG_DYLIB=OFF`) and embedded into `libclang.dll`, that forces the accessor into the DLL's export table, where it collides with the same symbol from the static clang libraries on any tool linking both. Summary of changes: * Add `LLVM_{DECLARE,DEFINE,INSTANTIATE}_REGISTRY_EX` variants taking the export annotation as a parameter. * Add `CLANG_ABI_EXPORT` macro as an equivalent to `LLVM_ALWAYS_EXPORT` for libclang. * Route clang's registries through the `*_EX` macros with `CLANG_ABI_EXPORT`. As a result, the static clang build no longer exports the accessor and the clang dylib build is unaffected. The effort to build LLVM as a dylib on Windows is tracked in #109483. --- .../Core/Serialization/JSONFormat.h | 6 ++- .../SerializationFormatRegistry.h | 3 +- .../SummaryData/SummaryDataBuilderRegistry.h | 4 +- .../Core/TUSummary/ExtractorRegistry.h | 3 +- .../WholeProgramAnalysis/AnalysisRegistry.h | 4 +- .../TransformationRegistry.h | 2 +- clang/include/clang/Support/Compiler.h | 9 ++++ clang/lib/Basic/ParsedAttrInfo.cpp | 3 +- clang/lib/Frontend/FrontendAction.cpp | 3 +- clang/lib/Lex/Preprocessor.cpp | 3 +- .../JSONFormat/JSONFormatImpl.cpp | 6 ++- .../SerializationFormatRegistry.cpp | 2 +- .../SummaryDataBuilderRegistry.cpp | 2 +- .../Core/TUSummary/ExtractorRegistry.cpp | 3 +- .../WholeProgramAnalysis/AnalysisRegistry.cpp | 2 +- .../TransformationRegistry.cpp | 2 +- clang/lib/Tooling/CompilationDatabase.cpp | 4 +- clang/lib/Tooling/Execution.cpp | 4 +- llvm/include/llvm/Support/Registry.h | 49 +++++++++++++++++++ 19 files changed, 95 insertions(+), 19 deletions(-) diff --git a/clang/include/clang/ScalableStaticAnalysis/Core/Serialization/JSONFormat.h b/clang/include/clang/ScalableStaticAnalysis/Core/Serialization/JSONFormat.h index 9d9b1ff0bbb51..0ba0ed136b53f 100644 --- a/clang/include/clang/ScalableStaticAnalysis/Core/Serialization/JSONFormat.h +++ b/clang/include/clang/ScalableStaticAnalysis/Core/Serialization/JSONFormat.h @@ -261,8 +261,10 @@ class JSONFormat final : public SerializationFormat { } // namespace clang::ssaf -LLVM_DECLARE_REGISTRY(llvm::Registry<clang::ssaf::JSONFormat::FormatInfo>) -LLVM_DECLARE_REGISTRY( +LLVM_DECLARE_REGISTRY_EX(CLANG_ABI_EXPORT, + llvm::Registry<clang::ssaf::JSONFormat::FormatInfo>) +LLVM_DECLARE_REGISTRY_EX( + CLANG_ABI_EXPORT, llvm::Registry<clang::ssaf::JSONFormat::AnalysisResultRegistry::Codec>) #endif // LLVM_CLANG_SCALABLESTATICANALYSIS_CORE_SERIALIZATION_JSONFORMAT_H diff --git a/clang/include/clang/ScalableStaticAnalysis/Core/Serialization/SerializationFormatRegistry.h b/clang/include/clang/ScalableStaticAnalysis/Core/Serialization/SerializationFormatRegistry.h index bcb926903d664..bf302804f7b51 100644 --- a/clang/include/clang/ScalableStaticAnalysis/Core/Serialization/SerializationFormatRegistry.h +++ b/clang/include/clang/ScalableStaticAnalysis/Core/Serialization/SerializationFormatRegistry.h @@ -84,6 +84,7 @@ using SerializationFormatRegistry = llvm::Registry<SerializationFormat>; } // namespace clang::ssaf -LLVM_DECLARE_REGISTRY(clang::ssaf::SerializationFormatRegistry) +LLVM_DECLARE_REGISTRY_EX(CLANG_ABI_EXPORT, + clang::ssaf::SerializationFormatRegistry) #endif // LLVM_CLANG_SCALABLESTATICANALYSIS_CORE_SERIALIZATION_SERIALIZATIONFORMATREGISTRY_H diff --git a/clang/include/clang/ScalableStaticAnalysis/Core/SummaryData/SummaryDataBuilderRegistry.h b/clang/include/clang/ScalableStaticAnalysis/Core/SummaryData/SummaryDataBuilderRegistry.h index f869985779b1a..2d5a29fb3aedd 100644 --- a/clang/include/clang/ScalableStaticAnalysis/Core/SummaryData/SummaryDataBuilderRegistry.h +++ b/clang/include/clang/ScalableStaticAnalysis/Core/SummaryData/SummaryDataBuilderRegistry.h @@ -23,11 +23,13 @@ #define LLVM_CLANG_SCALABLESTATICANALYSIS_CORE_SUMMARYDATA_SUMMARYDATABUILDERREGISTRY_H #include "clang/ScalableStaticAnalysis/Core/SummaryData/SummaryDataBuilder.h" +#include "clang/Support/Compiler.h" #include "llvm/Support/Registry.h" #include <memory> #include <string> -LLVM_DECLARE_REGISTRY(llvm::Registry<clang::ssaf::SummaryDataBuilderBase>) +LLVM_DECLARE_REGISTRY_EX(CLANG_ABI_EXPORT, + llvm::Registry<clang::ssaf::SummaryDataBuilderBase>) namespace clang::ssaf { diff --git a/clang/include/clang/ScalableStaticAnalysis/Core/TUSummary/ExtractorRegistry.h b/clang/include/clang/ScalableStaticAnalysis/Core/TUSummary/ExtractorRegistry.h index de0fd85f2a023..3bf5e26950213 100644 --- a/clang/include/clang/ScalableStaticAnalysis/Core/TUSummary/ExtractorRegistry.h +++ b/clang/include/clang/ScalableStaticAnalysis/Core/TUSummary/ExtractorRegistry.h @@ -51,6 +51,7 @@ using TUSummaryExtractorRegistry = } // namespace clang::ssaf -LLVM_DECLARE_REGISTRY(clang::ssaf::TUSummaryExtractorRegistry) +LLVM_DECLARE_REGISTRY_EX(CLANG_ABI_EXPORT, + clang::ssaf::TUSummaryExtractorRegistry) #endif // LLVM_CLANG_SCALABLESTATICANALYSIS_CORE_TUSUMMARY_EXTRACTORREGISTRY_H diff --git a/clang/include/clang/ScalableStaticAnalysis/Core/WholeProgramAnalysis/AnalysisRegistry.h b/clang/include/clang/ScalableStaticAnalysis/Core/WholeProgramAnalysis/AnalysisRegistry.h index 9672b62d1e05f..c07e6469f14c7 100644 --- a/clang/include/clang/ScalableStaticAnalysis/Core/WholeProgramAnalysis/AnalysisRegistry.h +++ b/clang/include/clang/ScalableStaticAnalysis/Core/WholeProgramAnalysis/AnalysisRegistry.h @@ -35,13 +35,15 @@ #include "clang/ScalableStaticAnalysis/Core/WholeProgramAnalysis/AnalysisName.h" #include "clang/ScalableStaticAnalysis/Core/WholeProgramAnalysis/DerivedAnalysis.h" #include "clang/ScalableStaticAnalysis/Core/WholeProgramAnalysis/SummaryAnalysis.h" +#include "clang/Support/Compiler.h" #include "llvm/Support/Error.h" #include "llvm/Support/Registry.h" #include <memory> #include <string> #include <vector> -LLVM_DECLARE_REGISTRY(llvm::Registry<clang::ssaf::AnalysisBase>) +LLVM_DECLARE_REGISTRY_EX(CLANG_ABI_EXPORT, + llvm::Registry<clang::ssaf::AnalysisBase>) namespace clang::ssaf { diff --git a/clang/include/clang/ScalableStaticAnalysis/SourceTransformation/TransformationRegistry.h b/clang/include/clang/ScalableStaticAnalysis/SourceTransformation/TransformationRegistry.h index 97301d005e496..eefb841af4fe3 100644 --- a/clang/include/clang/ScalableStaticAnalysis/SourceTransformation/TransformationRegistry.h +++ b/clang/include/clang/ScalableStaticAnalysis/SourceTransformation/TransformationRegistry.h @@ -61,6 +61,6 @@ using TransformationRegistry = } // namespace clang::ssaf -LLVM_DECLARE_REGISTRY(clang::ssaf::TransformationRegistry) +LLVM_DECLARE_REGISTRY_EX(CLANG_ABI_EXPORT, clang::ssaf::TransformationRegistry) #endif // LLVM_CLANG_SCALABLESTATICANALYSIS_SOURCETRANSFORMATION_TRANSFORMATIONREGISTRY_H diff --git a/clang/include/clang/Support/Compiler.h b/clang/include/clang/Support/Compiler.h index e1ae3eda4ccc2..d7f7a0b092fbb 100644 --- a/clang/include/clang/Support/Compiler.h +++ b/clang/include/clang/Support/Compiler.h @@ -27,6 +27,11 @@ /// CLANG_TEMPLATE_ABI is for annotating extern template declarations in headers /// for both functions and classes. On windows its turned in to dllimport for /// library consumers, for other platforms its a default visibility attribute. +/// +/// CLANG_ABI_EXPORT always exports (or, in a static build, does nothing), it +/// never expands to dllimport. It is the clang analogue of LLVM_ABI_EXPORT and +/// is used where a symbol must be exported by the defining library but must not +/// be imported by consumers. #ifndef CLANG_ABI_GENERATING_ANNOTATIONS // Marker to add to classes or functions in public headers that should not have // export macros added to them by the clang tool @@ -37,6 +42,7 @@ // missing symbol linker errors on windows. #if defined(CLANG_BUILD_STATIC) #define CLANG_ABI +#define CLANG_ABI_EXPORT #define CLANG_TEMPLATE_ABI #define CLANG_EXPORT_TEMPLATE #elif defined(_WIN32) && !defined(__MINGW32__) @@ -49,13 +55,16 @@ #define CLANG_TEMPLATE_ABI __declspec(dllimport) #define CLANG_EXPORT_TEMPLATE #endif +#define CLANG_ABI_EXPORT __declspec(dllexport) #elif defined(__ELF__) || defined(__MINGW32__) || defined(_AIX) || \ defined(__MVS__) || defined(__CYGWIN__) #define CLANG_ABI LLVM_ATTRIBUTE_VISIBILITY_DEFAULT +#define CLANG_ABI_EXPORT LLVM_ATTRIBUTE_VISIBILITY_DEFAULT #define CLANG_TEMPLATE_ABI LLVM_ATTRIBUTE_VISIBILITY_DEFAULT #define CLANG_EXPORT_TEMPLATE #elif defined(__MACH__) || defined(__WASM__) || defined(__EMSCRIPTEN__) #define CLANG_ABI LLVM_ATTRIBUTE_VISIBILITY_DEFAULT +#define CLANG_ABI_EXPORT LLVM_ATTRIBUTE_VISIBILITY_DEFAULT #define CLANG_TEMPLATE_ABI #define CLANG_EXPORT_TEMPLATE #endif diff --git a/clang/lib/Basic/ParsedAttrInfo.cpp b/clang/lib/Basic/ParsedAttrInfo.cpp index d5b17b34b6e3a..4c82fad98478f 100644 --- a/clang/lib/Basic/ParsedAttrInfo.cpp +++ b/clang/lib/Basic/ParsedAttrInfo.cpp @@ -12,13 +12,14 @@ //===----------------------------------------------------------------------===// #include "clang/Basic/ParsedAttrInfo.h" +#include "clang/Support/Compiler.h" #include "llvm/Support/ManagedStatic.h" #include <list> #include <memory> using namespace clang; -LLVM_INSTANTIATE_REGISTRY(ParsedAttrInfoRegistry) +LLVM_INSTANTIATE_REGISTRY_EX(CLANG_ABI_EXPORT, ParsedAttrInfoRegistry) static std::list<std::unique_ptr<ParsedAttrInfo>> instantiateEntries() { std::list<std::unique_ptr<ParsedAttrInfo>> Instances; diff --git a/clang/lib/Frontend/FrontendAction.cpp b/clang/lib/Frontend/FrontendAction.cpp index 7754861fabaf0..6030c17efeab5 100644 --- a/clang/lib/Frontend/FrontendAction.cpp +++ b/clang/lib/Frontend/FrontendAction.cpp @@ -39,6 +39,7 @@ #include "clang/Serialization/ASTDeserializationListener.h" #include "clang/Serialization/ASTReader.h" #include "clang/Serialization/GlobalModuleIndex.h" +#include "clang/Support/Compiler.h" #include "llvm/ADT/ScopeExit.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/StringRef.h" @@ -52,7 +53,7 @@ #include <system_error> using namespace clang; -LLVM_INSTANTIATE_REGISTRY(FrontendPluginRegistry) +LLVM_INSTANTIATE_REGISTRY_EX(CLANG_ABI_EXPORT, FrontendPluginRegistry) namespace { diff --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp index c69d084d6514f..0424d0ef9d3bd 100644 --- a/clang/lib/Lex/Preprocessor.cpp +++ b/clang/lib/Lex/Preprocessor.cpp @@ -52,6 +52,7 @@ #include "clang/Lex/ScratchBuffer.h" #include "clang/Lex/Token.h" #include "clang/Lex/TokenLexer.h" +#include "clang/Support/Compiler.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" @@ -79,7 +80,7 @@ using namespace clang; /// Minimum distance between two check points, in tokens. static constexpr unsigned CheckPointStepSize = 1024; -LLVM_INSTANTIATE_REGISTRY(PragmaHandlerRegistry) +LLVM_INSTANTIATE_REGISTRY_EX(CLANG_ABI_EXPORT, PragmaHandlerRegistry) ExternalPreprocessorSource::~ExternalPreprocessorSource() = default; diff --git a/clang/lib/ScalableStaticAnalysis/Core/Serialization/JSONFormat/JSONFormatImpl.cpp b/clang/lib/ScalableStaticAnalysis/Core/Serialization/JSONFormat/JSONFormatImpl.cpp index 8dcbb707c3a22..f935761b3c476 100644 --- a/clang/lib/ScalableStaticAnalysis/Core/Serialization/JSONFormat/JSONFormatImpl.cpp +++ b/clang/lib/ScalableStaticAnalysis/Core/Serialization/JSONFormat/JSONFormatImpl.cpp @@ -15,8 +15,10 @@ using namespace clang; using namespace ssaf; -LLVM_DEFINE_REGISTRY(llvm::Registry<JSONFormat::FormatInfo>) -LLVM_DEFINE_REGISTRY(llvm::Registry<JSONFormat::AnalysisResultRegistry::Codec>) +LLVM_DEFINE_REGISTRY_EX(CLANG_ABI_EXPORT, + llvm::Registry<JSONFormat::FormatInfo>) +LLVM_DEFINE_REGISTRY_EX( + CLANG_ABI_EXPORT, llvm::Registry<JSONFormat::AnalysisResultRegistry::Codec>) static SerializationFormatRegistry::Add<JSONFormat> RegisterJSONFormat("json", "JSON serialization format"); diff --git a/clang/lib/ScalableStaticAnalysis/Core/Serialization/SerializationFormatRegistry.cpp b/clang/lib/ScalableStaticAnalysis/Core/Serialization/SerializationFormatRegistry.cpp index 7f7791922bbee..8059d1e3ec5d3 100644 --- a/clang/lib/ScalableStaticAnalysis/Core/Serialization/SerializationFormatRegistry.cpp +++ b/clang/lib/ScalableStaticAnalysis/Core/Serialization/SerializationFormatRegistry.cpp @@ -12,7 +12,7 @@ using namespace clang; using namespace ssaf; -LLVM_DEFINE_REGISTRY(SerializationFormatRegistry) +LLVM_DEFINE_REGISTRY_EX(CLANG_ABI_EXPORT, SerializationFormatRegistry) bool ssaf::isFormatRegistered(llvm::StringRef FormatName) { for (const auto &Entry : SerializationFormatRegistry::entries()) diff --git a/clang/lib/ScalableStaticAnalysis/Core/SummaryData/SummaryDataBuilderRegistry.cpp b/clang/lib/ScalableStaticAnalysis/Core/SummaryData/SummaryDataBuilderRegistry.cpp index 98624bb9e2a08..8e05917c99a4b 100644 --- a/clang/lib/ScalableStaticAnalysis/Core/SummaryData/SummaryDataBuilderRegistry.cpp +++ b/clang/lib/ScalableStaticAnalysis/Core/SummaryData/SummaryDataBuilderRegistry.cpp @@ -12,7 +12,7 @@ using namespace clang; using namespace ssaf; using RegistryT = llvm::Registry<SummaryDataBuilderBase>; -LLVM_DEFINE_REGISTRY(RegistryT) +LLVM_DEFINE_REGISTRY_EX(CLANG_ABI_EXPORT, RegistryT) namespace { const RegistryT::entry *findEntry(llvm::StringRef Name) { diff --git a/clang/lib/ScalableStaticAnalysis/Core/TUSummary/ExtractorRegistry.cpp b/clang/lib/ScalableStaticAnalysis/Core/TUSummary/ExtractorRegistry.cpp index 1456d363625ad..73637249bd1a1 100644 --- a/clang/lib/ScalableStaticAnalysis/Core/TUSummary/ExtractorRegistry.cpp +++ b/clang/lib/ScalableStaticAnalysis/Core/TUSummary/ExtractorRegistry.cpp @@ -13,7 +13,8 @@ using namespace clang; using namespace ssaf; -LLVM_DEFINE_REGISTRY(clang::ssaf::TUSummaryExtractorRegistry) +LLVM_DEFINE_REGISTRY_EX(CLANG_ABI_EXPORT, + clang::ssaf::TUSummaryExtractorRegistry) bool ssaf::isTUSummaryExtractorRegistered(llvm::StringRef SummaryName) { for (const auto &Entry : TUSummaryExtractorRegistry::entries()) diff --git a/clang/lib/ScalableStaticAnalysis/Core/WholeProgramAnalysis/AnalysisRegistry.cpp b/clang/lib/ScalableStaticAnalysis/Core/WholeProgramAnalysis/AnalysisRegistry.cpp index 71779e800f612..3137e7fd367ba 100644 --- a/clang/lib/ScalableStaticAnalysis/Core/WholeProgramAnalysis/AnalysisRegistry.cpp +++ b/clang/lib/ScalableStaticAnalysis/Core/WholeProgramAnalysis/AnalysisRegistry.cpp @@ -18,7 +18,7 @@ namespace clang::ssaf { volatile int AnalysisRegistryAnchorSource = 0; } // namespace clang::ssaf -LLVM_DEFINE_REGISTRY(llvm::Registry<AnalysisBase>) +LLVM_DEFINE_REGISTRY_EX(CLANG_ABI_EXPORT, llvm::Registry<AnalysisBase>) std::vector<AnalysisName> &AnalysisRegistry::getAnalysisNames() { static std::vector<AnalysisName> Names; diff --git a/clang/lib/ScalableStaticAnalysis/SourceTransformation/TransformationRegistry.cpp b/clang/lib/ScalableStaticAnalysis/SourceTransformation/TransformationRegistry.cpp index 505b0ee4f9e51..6be42cc75b4d8 100644 --- a/clang/lib/ScalableStaticAnalysis/SourceTransformation/TransformationRegistry.cpp +++ b/clang/lib/ScalableStaticAnalysis/SourceTransformation/TransformationRegistry.cpp @@ -17,7 +17,7 @@ namespace clang::ssaf { volatile int SSAFSourceTransformationAnchorSource = 0; } // namespace clang::ssaf -LLVM_DEFINE_REGISTRY(clang::ssaf::TransformationRegistry) +LLVM_DEFINE_REGISTRY_EX(CLANG_ABI_EXPORT, clang::ssaf::TransformationRegistry) bool ssaf::isTransformationRegistered(llvm::StringRef Name) { for (const auto &Entry : TransformationRegistry::entries()) diff --git a/clang/lib/Tooling/CompilationDatabase.cpp b/clang/lib/Tooling/CompilationDatabase.cpp index 51079b4dcd543..77d19ac8975cc 100644 --- a/clang/lib/Tooling/CompilationDatabase.cpp +++ b/clang/lib/Tooling/CompilationDatabase.cpp @@ -24,6 +24,7 @@ #include "clang/Driver/Driver.h" #include "clang/Driver/Job.h" #include "clang/Frontend/TextDiagnosticPrinter.h" +#include "clang/Support/Compiler.h" #include "clang/Tooling/CompilationDatabasePluginRegistry.h" #include "clang/Tooling/Tooling.h" #include "llvm/ADT/STLExtras.h" @@ -50,7 +51,8 @@ using namespace clang; using namespace tooling; -LLVM_INSTANTIATE_REGISTRY(CompilationDatabasePluginRegistry) +LLVM_INSTANTIATE_REGISTRY_EX(CLANG_ABI_EXPORT, + CompilationDatabasePluginRegistry) CompilationDatabase::~CompilationDatabase() = default; diff --git a/clang/lib/Tooling/Execution.cpp b/clang/lib/Tooling/Execution.cpp index d0499fa364cfe..f5d5896e2c918 100644 --- a/clang/lib/Tooling/Execution.cpp +++ b/clang/lib/Tooling/Execution.cpp @@ -7,10 +7,12 @@ //===----------------------------------------------------------------------===// #include "clang/Tooling/Execution.h" +#include "clang/Support/Compiler.h" #include "clang/Tooling/ToolExecutorPluginRegistry.h" #include "clang/Tooling/Tooling.h" -LLVM_INSTANTIATE_REGISTRY(clang::tooling::ToolExecutorPluginRegistry) +LLVM_INSTANTIATE_REGISTRY_EX(CLANG_ABI_EXPORT, + clang::tooling::ToolExecutorPluginRegistry) namespace clang { namespace tooling { diff --git a/llvm/include/llvm/Support/Registry.h b/llvm/include/llvm/Support/Registry.h index 5584c90ece459..53f84396edf33 100644 --- a/llvm/include/llvm/Support/Registry.h +++ b/llvm/include/llvm/Support/Registry.h @@ -270,4 +270,53 @@ template <typename T, typename... CtorParamTypes> class Registry { LLVM_DETAIL_INSTANTIATE_REGISTRY_1(, REGISTRY_CLASS) #endif +/// Variants of the registration macros that take an explicit export annotation +/// (EXPORT_ABI) in place of the hard-coded `LLVM_ABI_EXPORT`. Use these when a +/// registry is owned by a component that is NOT part of the LLVM dylib. For +/// example, a clang library that is statically linked (`CLANG_LINK_CLANG_DYLIB` +/// OFF). With `LLVM_ABI_EXPORT` the `getRegistryLinkListInstance` accessor is +/// unconditionally `dllexport`ed; when such a static component is embedded in a +/// DLL that should only export its own API surface (e.g. libclang.dll), the +/// accessor leaks into that DLL's export table and then collides on the link +/// line of any tool that also links the static component directly. +/// +/// EXPORT_ABI must export-or-be-empty, NEVER dllimport, for the same reason +/// `LLVM_ABI_EXPORT` is used here rather than `LLVM_ABI`: the definition may be +/// in the same object, a static library, or an import library. +/// `CLANG_ABI_EXPORT` satisfies this (it is empty under `CLANG_BUILD_STATIC`). +#define LLVM_DECLARE_REGISTRY_EX(EXPORT_ABI, REGISTRY_CLASS) \ + namespace llvm::detail { \ + template <> \ + struct RegistryLinkListDeclarationMarker<REGISTRY_CLASS> : std::true_type { \ + }; \ + template <> \ + EXPORT_ABI RegistryLinkListStorage<REGISTRY_CLASS> & \ + getRegistryLinkListInstance<REGISTRY_CLASS>(); \ + } + +#define LLVM_DEFINE_REGISTRY_EX(EXPORT_ABI, REGISTRY_CLASS) \ + namespace llvm::detail { \ + static_assert(RegistryLinkListDeclarationMarker<REGISTRY_CLASS>::value, \ + "Missing matching registry declaration of " #REGISTRY_CLASS \ + ". Place `LLVM_DECLARE_REGISTRY(" #REGISTRY_CLASS \ + ")` in a header."); \ + template <> \ + EXPORT_ABI RegistryLinkListStorage<REGISTRY_CLASS> & \ + getRegistryLinkListInstance<REGISTRY_CLASS>() { \ + static RegistryLinkListStorage<REGISTRY_CLASS> Instance; \ + return Instance; \ + } \ + } + +#define LLVM_INSTANTIATE_REGISTRY_EX(EXPORT_ABI, REGISTRY_CLASS) \ + LLVM_DECLARE_REGISTRY_EX(EXPORT_ABI, REGISTRY_CLASS) \ + LLVM_DEFINE_REGISTRY_EX(EXPORT_ABI, REGISTRY_CLASS) \ + namespace llvm { \ + template class EXPORT_ABI Registry<REGISTRY_CLASS::type>; \ + static_assert(!REGISTRY_CLASS::HasCtorParamTypes, \ + "LLVM_INSTANTIATE_REGISTRY can't be used with extra " \ + "constructor parameter types. Use " \ + "LLVM_DECLARE/DEFINE_REGISTRY istead."); \ + } + #endif // LLVM_SUPPORT_REGISTRY_H _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
