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

Reply via email to