https://github.com/Steelskin created
https://github.com/llvm/llvm-project/pull/206750
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.
>From 0022838b248930b5bd0659ebeec85ec897b88110 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.
---
.../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