[clang] [llvm] Update llvm::Registry to work for LLVM shared library builds on windows (PR #109024)
Thomas Fransham via cfe-commits
cfe-commits at lists.llvm.org
Mon Oct 14 13:39:10 PDT 2024
https://github.com/fsfod updated https://github.com/llvm/llvm-project/pull/109024
>From beef0d9f53f05c31041677101577929281e908b1 Mon Sep 17 00:00:00 2001
From: Thomas Fransham <tfransham at gmail.com>
Date: Wed, 28 Aug 2024 16:08:52 +0100
Subject: [PATCH 1/8] Update llvm::Registry to work for LLVM shared library
builds on windows
Windows doesn't implicitly import and merge exported symbols across shared libraries
like Linux does so we need to explicitly export/import each instantiation of llvm::Registry.
Updated LLVM_INSTANTIATE_REGISTRY macro to export Registry::add_node and
Registry::begin() and add extern template declarations for the all instantiations of llvm::Registry.
---
clang/include/clang/Basic/ParsedAttrInfo.h | 5 +++
.../clang/Frontend/FrontendPluginRegistry.h | 5 +++
llvm/include/llvm/CodeGen/GCMetadataPrinter.h | 2 +
llvm/include/llvm/IR/GCStrategy.h | 2 +
llvm/include/llvm/Support/Compiler.h | 5 +++
llvm/include/llvm/Support/Registry.h | 43 ++++++++++---------
6 files changed, 42 insertions(+), 20 deletions(-)
diff --git a/clang/include/clang/Basic/ParsedAttrInfo.h b/clang/include/clang/Basic/ParsedAttrInfo.h
index fab5c6f1377d27..c87adabfcd200f 100644
--- a/clang/include/clang/Basic/ParsedAttrInfo.h
+++ b/clang/include/clang/Basic/ParsedAttrInfo.h
@@ -17,6 +17,7 @@
#include "clang/Basic/AttrSubjectMatchRules.h"
#include "clang/Basic/AttributeCommonInfo.h"
+#include "clang/Support/Compiler.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/Registry.h"
#include <climits>
@@ -175,4 +176,8 @@ const std::list<std::unique_ptr<ParsedAttrInfo>> &getAttributePluginInstances();
} // namespace clang
+namespace llvm {
+extern template class CLANG_TEMPLATE_ABI llvm::Registry<clang::ParsedAttrInfo>;
+} // namespace llvm
+
#endif // LLVM_CLANG_BASIC_PARSEDATTRINFO_H
diff --git a/clang/include/clang/Frontend/FrontendPluginRegistry.h b/clang/include/clang/Frontend/FrontendPluginRegistry.h
index 810578534acb45..5eea9c2fd89a32 100644
--- a/clang/include/clang/Frontend/FrontendPluginRegistry.h
+++ b/clang/include/clang/Frontend/FrontendPluginRegistry.h
@@ -14,6 +14,7 @@
#define LLVM_CLANG_FRONTEND_FRONTENDPLUGINREGISTRY_H
#include "clang/Frontend/FrontendAction.h"
+#include "clang/Support/Compiler.h"
#include "llvm/Support/Registry.h"
namespace clang {
@@ -23,4 +24,8 @@ using FrontendPluginRegistry = llvm::Registry<PluginASTAction>;
} // namespace clang
+namespace llvm {
+extern template class CLANG_TEMPLATE_ABI Registry<clang::PluginASTAction>;
+} // namespace llvm
+
#endif // LLVM_CLANG_FRONTEND_FRONTENDPLUGINREGISTRY_H
diff --git a/llvm/include/llvm/CodeGen/GCMetadataPrinter.h b/llvm/include/llvm/CodeGen/GCMetadataPrinter.h
index f9527c9f8752e9..9d421be8313f01 100644
--- a/llvm/include/llvm/CodeGen/GCMetadataPrinter.h
+++ b/llvm/include/llvm/CodeGen/GCMetadataPrinter.h
@@ -34,6 +34,8 @@ class StackMaps;
/// defaults from Registry.
using GCMetadataPrinterRegistry = Registry<GCMetadataPrinter>;
+extern template class LLVM_TEMPLATE_ABI Registry<GCMetadataPrinter>;
+
/// GCMetadataPrinter - Emits GC metadata as assembly code. Instances are
/// created, managed, and owned by the AsmPrinter.
class GCMetadataPrinter {
diff --git a/llvm/include/llvm/IR/GCStrategy.h b/llvm/include/llvm/IR/GCStrategy.h
index 3186465f001812..cbfbe23aaa0683 100644
--- a/llvm/include/llvm/IR/GCStrategy.h
+++ b/llvm/include/llvm/IR/GCStrategy.h
@@ -141,6 +141,8 @@ class GCStrategy {
/// GCMetadataPrinterRegistery as well.
using GCRegistry = Registry<GCStrategy>;
+extern template class LLVM_TEMPLATE_ABI Registry<GCStrategy>;
+
/// Lookup the GCStrategy object associated with the given gc name.
std::unique_ptr<GCStrategy> getGCStrategy(const StringRef Name);
diff --git a/llvm/include/llvm/Support/Compiler.h b/llvm/include/llvm/Support/Compiler.h
index 1d2d751d4dc11a..e893734b81fb7d 100644
--- a/llvm/include/llvm/Support/Compiler.h
+++ b/llvm/include/llvm/Support/Compiler.h
@@ -179,6 +179,7 @@
#define LLVM_ABI
#define LLVM_TEMPLATE_ABI
#define LLVM_EXPORT_TEMPLATE
+#define LLVM_ABI_EXPORT
#elif defined(_WIN32) && !defined(__MINGW32__)
#if defined(LLVM_EXPORTS)
#define LLVM_ABI __declspec(dllexport)
@@ -189,19 +190,23 @@
#define LLVM_TEMPLATE_ABI __declspec(dllimport)
#define LLVM_EXPORT_TEMPLATE
#endif
+#define LLVM_ABI_EXPORT __declspec(dllexport)
#elif defined(__ELF__) || defined(__MINGW32__) || defined(_AIX)
#define LLVM_ABI LLVM_ATTRIBUTE_VISIBILITY_DEFAULT
#define LLVM_TEMPLATE_ABI LLVM_ATTRIBUTE_VISIBILITY_DEFAULT
#define LLVM_EXPORT_TEMPLATE
+#define LLVM_ABI_EXPORT LLVM_ATTRIBUTE_VISIBILITY_DEFAULT
#elif defined(__MACH__) || defined(__WASM__)
#define LLVM_ABI LLVM_ATTRIBUTE_VISIBILITY_DEFAULT
#define LLVM_TEMPLATE_ABI
#define LLVM_EXPORT_TEMPLATE
+#define LLVM_ABI_EXPORT LLVM_ATTRIBUTE_VISIBILITY_DEFAULT
#endif
#else
#define LLVM_ABI
#define LLVM_TEMPLATE_ABI
#define LLVM_EXPORT_TEMPLATE
+#define LLVM_ABI_EXPORT
#endif
#define LLVM_C_ABI LLVM_ABI
#endif
diff --git a/llvm/include/llvm/Support/Registry.h b/llvm/include/llvm/Support/Registry.h
index 5bb6a254a47f4c..2dcbe0f2a28208 100644
--- a/llvm/include/llvm/Support/Registry.h
+++ b/llvm/include/llvm/Support/Registry.h
@@ -134,26 +134,29 @@ namespace llvm {
/// strictly speaking that's not allowed by the C++ standard (we would need to
/// have explicit specialization declarations in all translation units where the
/// specialization is used) so we don't.
-#define LLVM_INSTANTIATE_REGISTRY(REGISTRY_CLASS) \
- namespace llvm { \
- template<typename T> typename Registry<T>::node *Registry<T>::Head = nullptr;\
- template<typename T> typename Registry<T>::node *Registry<T>::Tail = nullptr;\
- template<typename T> \
- void Registry<T>::add_node(typename Registry<T>::node *N) { \
- if (Tail) \
- Tail->Next = N; \
- else \
- Head = N; \
- Tail = N; \
- } \
- template<typename T> typename Registry<T>::iterator Registry<T>::begin() { \
- return iterator(Head); \
- } \
- template REGISTRY_CLASS::node *Registry<REGISTRY_CLASS::type>::Head; \
- template REGISTRY_CLASS::node *Registry<REGISTRY_CLASS::type>::Tail; \
- template \
- void Registry<REGISTRY_CLASS::type>::add_node(REGISTRY_CLASS::node*); \
- template REGISTRY_CLASS::iterator Registry<REGISTRY_CLASS::type>::begin(); \
+#define LLVM_INSTANTIATE_REGISTRY(REGISTRY_CLASS) \
+ namespace llvm { \
+ template <typename T> \
+ typename Registry<T>::node *Registry<T>::Head = nullptr; \
+ template <typename T> \
+ typename Registry<T>::node *Registry<T>::Tail = nullptr; \
+ template <typename T> \
+ void Registry<T>::add_node(typename Registry<T>::node *N) { \
+ if (Tail) \
+ Tail->Next = N; \
+ else \
+ Head = N; \
+ Tail = N; \
+ } \
+ template <typename T> typename Registry<T>::iterator Registry<T>::begin() { \
+ return iterator(Head); \
+ } \
+ template REGISTRY_CLASS::node *Registry<REGISTRY_CLASS::type>::Head; \
+ template REGISTRY_CLASS::node *Registry<REGISTRY_CLASS::type>::Tail; \
+ template LLVM_ABI_EXPORT void \
+ Registry<REGISTRY_CLASS::type>::add_node(REGISTRY_CLASS::node *); \
+ template LLVM_ABI_EXPORT REGISTRY_CLASS::iterator \
+ Registry<REGISTRY_CLASS::type>::begin(); \
}
#endif // LLVM_SUPPORT_REGISTRY_H
>From d6beb7d9342636477d7c369715db4dc5f13bc7ed Mon Sep 17 00:00:00 2001
From: Thomas Fransham <tfransham at gmail.com>
Date: Mon, 16 Sep 2024 16:00:51 +0100
Subject: [PATCH 2/8] Workaround 20 year old MSVC compiler bug for static
fields of llvm::Registry
Fixes Tail': member of dll interface class may not be declared with dll interface
https://developercommunity.visualstudio.com/t/c2487-in-dllexport-class-with-static-members/69878
---
llvm/include/llvm/Support/Registry.h | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/llvm/include/llvm/Support/Registry.h b/llvm/include/llvm/Support/Registry.h
index 2dcbe0f2a28208..837cd1237fd38f 100644
--- a/llvm/include/llvm/Support/Registry.h
+++ b/llvm/include/llvm/Support/Registry.h
@@ -53,7 +53,13 @@ namespace llvm {
Registry() = delete;
friend class node;
- static node *Head, *Tail;
+ // These must be must two separate declarations to workaround a 20 year
+ // old MSVC bug with dllexport and multiple static fields in the same
+ // declaration causing error C2487 "member of dll interface class may not
+ // be declared with dll interface".
+ // https://developercommunity.visualstudio.com/t/c2487-in-dllexport-class-with-static-members/69878
+ static node *Head;
+ static node *Tail;
public:
/// Node in linked list of entries.
>From b603ef141f53ad7fa7419a1e4e5ceb218575eb23 Mon Sep 17 00:00:00 2001
From: Thomas Fransham <fsfod11 at gmail.com>
Date: Thu, 19 Sep 2024 18:02:13 +0100
Subject: [PATCH 3/8] Remove redundant llvm namespace prefix
Co-authored-by: Saleem Abdulrasool <compnerd at compnerd.org>
---
clang/include/clang/Basic/ParsedAttrInfo.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/include/clang/Basic/ParsedAttrInfo.h b/clang/include/clang/Basic/ParsedAttrInfo.h
index c87adabfcd200f..3b5f5d3c3f92ac 100644
--- a/clang/include/clang/Basic/ParsedAttrInfo.h
+++ b/clang/include/clang/Basic/ParsedAttrInfo.h
@@ -177,7 +177,7 @@ const std::list<std::unique_ptr<ParsedAttrInfo>> &getAttributePluginInstances();
} // namespace clang
namespace llvm {
-extern template class CLANG_TEMPLATE_ABI llvm::Registry<clang::ParsedAttrInfo>;
+extern template class CLANG_TEMPLATE_ABI Registry<clang::ParsedAttrInfo>;
} // namespace llvm
#endif // LLVM_CLANG_BASIC_PARSEDATTRINFO_H
>From e9d5a9b626592cc7c2863fa30a10dcfb5359bc44 Mon Sep 17 00:00:00 2001
From: Thomas Fransham <tfransham at gmail.com>
Date: Fri, 20 Sep 2024 17:52:35 +0100
Subject: [PATCH 4/8] Add a comment explaining LLVM_ABI_EXPORT
---
llvm/include/llvm/Support/Compiler.h | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/llvm/include/llvm/Support/Compiler.h b/llvm/include/llvm/Support/Compiler.h
index e893734b81fb7d..ab0cbff43d749c 100644
--- a/llvm/include/llvm/Support/Compiler.h
+++ b/llvm/include/llvm/Support/Compiler.h
@@ -153,6 +153,12 @@
/// exported when llvm is built as a shared library with everything else that is
/// unannotated will have internal visibility.
///
+/// LLVM_ABI_EXPORT is for the special case for things like plugin symbol
+/// declarations or definitions where we don't want the macro to be switching
+/// between dllexport and dllimport on windows based on what codebase is being
+/// built, it will only be dllexport. For non windows platforms this macro
+/// behaves the same as LLVM_ABI.
+///
/// LLVM_EXPORT_TEMPLATE is used on explicit template instantiations in source
/// files that were declared extern in a header. This macro is only set as a
/// compiler export attribute on windows, on other platforms it does nothing.
>From 1e66df438342c9b35a8d96dff12e57a09e8f0b1b Mon Sep 17 00:00:00 2001
From: Thomas Fransham <tfransham at gmail.com>
Date: Fri, 20 Sep 2024 18:17:36 +0100
Subject: [PATCH 5/8] Add extern template declarations for PragmaHandler,
ToolExecutorPlugin and CompilationDatabasePlugin registry in clang
---
clang/include/clang/Lex/Preprocessor.h | 5 +++++
.../clang/Tooling/CompilationDatabasePluginRegistry.h | 6 ++++++
clang/include/clang/Tooling/ToolExecutorPluginRegistry.h | 6 ++++++
3 files changed, 17 insertions(+)
diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h
index 4643b0213815f8..92749e4de44b57 100644
--- a/clang/include/clang/Lex/Preprocessor.h
+++ b/clang/include/clang/Lex/Preprocessor.h
@@ -32,6 +32,7 @@
#include "clang/Lex/PPEmbedParameters.h"
#include "clang/Lex/Token.h"
#include "clang/Lex/TokenLexer.h"
+#include "clang/Support/Compiler.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
@@ -3060,4 +3061,8 @@ using PragmaHandlerRegistry = llvm::Registry<PragmaHandler>;
} // namespace clang
+namespace llvm {
+extern template class CLANG_TEMPLATE_ABI Registry<clang::PragmaHandler>;
+} // namespace llvm
+
#endif // LLVM_CLANG_LEX_PREPROCESSOR_H
diff --git a/clang/include/clang/Tooling/CompilationDatabasePluginRegistry.h b/clang/include/clang/Tooling/CompilationDatabasePluginRegistry.h
index 8c58ad926a402a..e6bcac542b0ecb 100644
--- a/clang/include/clang/Tooling/CompilationDatabasePluginRegistry.h
+++ b/clang/include/clang/Tooling/CompilationDatabasePluginRegistry.h
@@ -9,6 +9,7 @@
#ifndef LLVM_CLANG_TOOLING_COMPILATIONDATABASEPLUGINREGISTRY_H
#define LLVM_CLANG_TOOLING_COMPILATIONDATABASEPLUGINREGISTRY_H
+#include "clang/Support/Compiler.h"
#include "clang/Tooling/CompilationDatabase.h"
#include "llvm/Support/Registry.h"
@@ -42,4 +43,9 @@ using CompilationDatabasePluginRegistry =
} // namespace tooling
} // namespace clang
+namespace llvm {
+extern template class CLANG_TEMPLATE_ABI
+ Registry<clang::tooling::CompilationDatabasePlugin>;
+} // namespace llvm
+
#endif // LLVM_CLANG_TOOLING_COMPILATIONDATABASEPLUGINREGISTRY_H
diff --git a/clang/include/clang/Tooling/ToolExecutorPluginRegistry.h b/clang/include/clang/Tooling/ToolExecutorPluginRegistry.h
index 5304ff26252def..8d54583234684e 100644
--- a/clang/include/clang/Tooling/ToolExecutorPluginRegistry.h
+++ b/clang/include/clang/Tooling/ToolExecutorPluginRegistry.h
@@ -9,6 +9,7 @@
#ifndef LLVM_CLANG_TOOLING_TOOLEXECUTORPLUGINREGISTRY_H
#define LLVM_CLANG_TOOLING_TOOLEXECUTORPLUGINREGISTRY_H
+#include "clang/Support/Compiler.h"
#include "clang/Tooling/Execution.h"
#include "llvm/Support/Registry.h"
@@ -20,4 +21,9 @@ using ToolExecutorPluginRegistry = llvm::Registry<ToolExecutorPlugin>;
} // namespace tooling
} // namespace clang
+namespace llvm {
+extern template class CLANG_TEMPLATE_ABI
+ Registry<clang::tooling::ToolExecutorPlugin>;
+} // namespace llvm
+
#endif // LLVM_CLANG_TOOLING_TOOLEXECUTORPLUGINREGISTRY_H
>From 0119a94aad4c108db75316524f27112809a23f55 Mon Sep 17 00:00:00 2001
From: Thomas Fransham <tfransham at gmail.com>
Date: Thu, 3 Oct 2024 19:58:59 +0100
Subject: [PATCH 6/8] Switch LLVM_INSTANTIATE_REGISTRY to just doing a full
class template explicit instantiation
---
llvm/include/llvm/Support/Registry.h | 53 +++++++++++-----------------
1 file changed, 21 insertions(+), 32 deletions(-)
diff --git a/llvm/include/llvm/Support/Registry.h b/llvm/include/llvm/Support/Registry.h
index 837cd1237fd38f..c80da1c5d3fea5 100644
--- a/llvm/include/llvm/Support/Registry.h
+++ b/llvm/include/llvm/Support/Registry.h
@@ -82,7 +82,13 @@ namespace llvm {
/// add a node to the executable's registry. Therefore it's not defined here
/// to avoid it being instantiated in the plugin and is instead defined in
/// the executable (see LLVM_INSTANTIATE_REGISTRY below).
- static void add_node(node *N);
+ static void add_node(node *N) {
+ if (Tail)
+ Tail->Next = N;
+ else
+ Head = N;
+ Tail = N;
+ }
/// Iterators for registry entries.
///
@@ -101,7 +107,7 @@ namespace llvm {
// begin is not defined here in order to avoid usage of an undefined static
// data member, instead it's instantiated by LLVM_INSTANTIATE_REGISTRY.
- static iterator begin();
+ static iterator begin() { return iterator(Head); }
static iterator end() { return iterator(nullptr); }
static iterator_range<iterator> entries() {
@@ -130,39 +136,22 @@ namespace llvm {
}
};
};
+
+ template<typename T> typename Registry<T>::node *Registry<T>::Head = nullptr;
+ template<typename T> typename Registry<T>::node *Registry<T>::Tail = nullptr;
} // end namespace llvm
+#ifdef _WIN32
/// Instantiate a registry class.
-///
-/// This provides template definitions of add_node, begin, and the Head and Tail
-/// pointers, then explicitly instantiates them. We could explicitly specialize
-/// them, instead of the two-step process of define then instantiate, but
-/// strictly speaking that's not allowed by the C++ standard (we would need to
-/// have explicit specialization declarations in all translation units where the
-/// specialization is used) so we don't.
-#define LLVM_INSTANTIATE_REGISTRY(REGISTRY_CLASS) \
- namespace llvm { \
- template <typename T> \
- typename Registry<T>::node *Registry<T>::Head = nullptr; \
- template <typename T> \
- typename Registry<T>::node *Registry<T>::Tail = nullptr; \
- template <typename T> \
- void Registry<T>::add_node(typename Registry<T>::node *N) { \
- if (Tail) \
- Tail->Next = N; \
- else \
- Head = N; \
- Tail = N; \
- } \
- template <typename T> typename Registry<T>::iterator Registry<T>::begin() { \
- return iterator(Head); \
- } \
- template REGISTRY_CLASS::node *Registry<REGISTRY_CLASS::type>::Head; \
- template REGISTRY_CLASS::node *Registry<REGISTRY_CLASS::type>::Tail; \
- template LLVM_ABI_EXPORT void \
- Registry<REGISTRY_CLASS::type>::add_node(REGISTRY_CLASS::node *); \
- template LLVM_ABI_EXPORT REGISTRY_CLASS::iterator \
- Registry<REGISTRY_CLASS::type>::begin(); \
+#define LLVM_INSTANTIATE_REGISTRY(REGISTRY_CLASS) \
+ namespace llvm { \
+ template class LLVM_ABI_EXPORT Registry<REGISTRY_CLASS::type>;\
+ }
+#else
+#define LLVM_INSTANTIATE_REGISTRY(REGISTRY_CLASS) \
+ namespace llvm { \
+ template class Registry<REGISTRY_CLASS>;\
}
+#endif
#endif // LLVM_SUPPORT_REGISTRY_H
>From b1147fa44dbffb2fec053f398c21ec67f664ee7e Mon Sep 17 00:00:00 2001
From: Thomas Fransham <tfransham at gmail.com>
Date: Thu, 3 Oct 2024 20:18:45 +0100
Subject: [PATCH 7/8] Fix formatting
---
llvm/include/llvm/Support/Registry.h | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/llvm/include/llvm/Support/Registry.h b/llvm/include/llvm/Support/Registry.h
index c80da1c5d3fea5..2a3519b1b43e11 100644
--- a/llvm/include/llvm/Support/Registry.h
+++ b/llvm/include/llvm/Support/Registry.h
@@ -107,7 +107,7 @@ namespace llvm {
// begin is not defined here in order to avoid usage of an undefined static
// data member, instead it's instantiated by LLVM_INSTANTIATE_REGISTRY.
- static iterator begin() { return iterator(Head); }
+ static iterator begin() { return iterator(Head); }
static iterator end() { return iterator(nullptr); }
static iterator_range<iterator> entries() {
@@ -137,20 +137,20 @@ namespace llvm {
};
};
- template<typename T> typename Registry<T>::node *Registry<T>::Head = nullptr;
- template<typename T> typename Registry<T>::node *Registry<T>::Tail = nullptr;
+ template <typename T> typename Registry<T>::node *Registry<T>::Head = nullptr;
+ template <typename T> typename Registry<T>::node *Registry<T>::Tail = nullptr;
} // end namespace llvm
#ifdef _WIN32
/// Instantiate a registry class.
-#define LLVM_INSTANTIATE_REGISTRY(REGISTRY_CLASS) \
- namespace llvm { \
- template class LLVM_ABI_EXPORT Registry<REGISTRY_CLASS::type>;\
+#define LLVM_INSTANTIATE_REGISTRY(REGISTRY_CLASS) \
+ namespace llvm { \
+ template class LLVM_ABI_EXPORT Registry<REGISTRY_CLASS::type>; \
}
#else
-#define LLVM_INSTANTIATE_REGISTRY(REGISTRY_CLASS) \
- namespace llvm { \
- template class Registry<REGISTRY_CLASS>;\
+#define LLVM_INSTANTIATE_REGISTRY(REGISTRY_CLASS) \
+ namespace llvm { \
+ template class Registry<REGISTRY_CLASS>; \
}
#endif
>From c25068a8d3737454adedc49daeaff39ee94604e6 Mon Sep 17 00:00:00 2001
From: Thomas Fransham <tfransham at gmail.com>
Date: Mon, 14 Oct 2024 20:55:56 +0100
Subject: [PATCH 8/8] Just put the definition for Registry head and tail back
in source files
---
llvm/include/llvm/Support/Registry.h | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/llvm/include/llvm/Support/Registry.h b/llvm/include/llvm/Support/Registry.h
index 2a3519b1b43e11..ff9226c39359c5 100644
--- a/llvm/include/llvm/Support/Registry.h
+++ b/llvm/include/llvm/Support/Registry.h
@@ -137,20 +137,26 @@ namespace llvm {
};
};
- template <typename T> typename Registry<T>::node *Registry<T>::Head = nullptr;
- template <typename T> typename Registry<T>::node *Registry<T>::Tail = nullptr;
} // end namespace llvm
#ifdef _WIN32
/// Instantiate a registry class.
#define LLVM_INSTANTIATE_REGISTRY(REGISTRY_CLASS) \
namespace llvm { \
+ template <typename T> \
+ typename Registry<T>::node *Registry<T>::Head = nullptr; \
+ template <typename T> \
+ typename Registry<T>::node *Registry<T>::Tail = nullptr; \
template class LLVM_ABI_EXPORT Registry<REGISTRY_CLASS::type>; \
}
#else
#define LLVM_INSTANTIATE_REGISTRY(REGISTRY_CLASS) \
namespace llvm { \
- template class Registry<REGISTRY_CLASS>; \
+ template <typename T> \
+ typename Registry<T>::node *Registry<T>::Head = nullptr; \
+ template <typename T> \
+ typename Registry<T>::node *Registry<T>::Tail = nullptr; \
+ template class Registry<REGISTRY_CLASS::type>; \
}
#endif
More information about the cfe-commits
mailing list