Skip to content

Commit 63aff61

Browse files
committedJul 27, 2016
Adjust Registry interface to not require plugins to export a registry
Currently the Registry class contains the vestiges of a previous attempt to allow plugins to be used on Windows without using BUILD_SHARED_LIBS, where a plugin would have its own copy of a registry and export it to be imported by the tool that's loading the plugin. This only works if the plugin is entirely self-contained with the only interface between the plugin and tool being the registry, and in particular this conflicts with how IR pass plugins work. This patch changes things so that instead the add_node function of the registry is exported by the tool and then imported by the plugin, which solves this problem and also means that instead of every plugin having to export every registry they use instead LLVM only has to export the add_node functions. This allows plugins that use a registry to work on Windows if LLVM_EXPORT_SYMBOLS_FOR_PLUGINS is used. Differential Revision: http://reviews.llvm.org/D21385 llvm-svn: 276856
1 parent 10bf0ff commit 63aff61

File tree

10 files changed

+32
-68
lines changed

10 files changed

+32
-68
lines changed
 

‎clang/examples/AnnotateFunctions/CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
add_llvm_loadable_module(AnnotateFunctions AnnotateFunctions.cpp)
1+
add_llvm_loadable_module(AnnotateFunctions AnnotateFunctions.cpp PLUGIN_TOOL clang)
22

33
if(LLVM_ENABLE_PLUGINS AND (WIN32 OR CYGWIN))
44
target_link_libraries(AnnotateFunctions PRIVATE

‎clang/examples/PrintFunctionNames/CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ if( NOT MSVC ) # MSVC mangles symbols differently, and
99
endif()
1010
endif()
1111

12-
add_llvm_loadable_module(PrintFunctionNames PrintFunctionNames.cpp)
12+
add_llvm_loadable_module(PrintFunctionNames PrintFunctionNames.cpp PLUGIN_TOOL clang)
1313

1414
if(LLVM_ENABLE_PLUGINS AND (WIN32 OR CYGWIN))
1515
target_link_libraries(PrintFunctionNames PRIVATE

‎clang/include/clang/Frontend/FrontendPluginRegistry.h

-3
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,6 @@
1313
#include "clang/Frontend/FrontendAction.h"
1414
#include "llvm/Support/Registry.h"
1515

16-
// Instantiated in FrontendAction.cpp.
17-
extern template class llvm::Registry<clang::PluginASTAction>;
18-
1916
namespace clang {
2017

2118
/// The frontend plugin registry.

‎clang/include/clang/Lex/Preprocessor.h

-2
Original file line numberDiff line numberDiff line change
@@ -1956,6 +1956,4 @@ typedef llvm::Registry<PragmaHandler> PragmaHandlerRegistry;
19561956

19571957
} // end namespace clang
19581958

1959-
extern template class llvm::Registry<clang::PragmaHandler>;
1960-
19611959
#endif

‎clang/lib/Frontend/FrontendAction.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
#include <system_error>
3434
using namespace clang;
3535

36-
template class llvm::Registry<clang::PluginASTAction>;
36+
LLVM_INSTANTIATE_REGISTRY(FrontendPluginRegistry)
3737

3838
namespace {
3939

‎clang/lib/Lex/Preprocessor.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
#include <utility>
5555
using namespace clang;
5656

57-
template class llvm::Registry<clang::PragmaHandler>;
57+
LLVM_INSTANTIATE_REGISTRY(PragmaHandlerRegistry)
5858

5959
//===----------------------------------------------------------------------===//
6060
ExternalPreprocessorSource::~ExternalPreprocessorSource() { }

‎clang/lib/Tooling/CompilationDatabase.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
using namespace clang;
3333
using namespace tooling;
3434

35+
LLVM_INSTANTIATE_REGISTRY(CompilationDatabasePluginRegistry)
36+
3537
CompilationDatabase::~CompilationDatabase() {}
3638

3739
std::unique_ptr<CompilationDatabase>

‎llvm/include/llvm/Support/Registry.h

+22-59
Original file line numberDiff line numberDiff line change
@@ -69,13 +69,14 @@ namespace llvm {
6969
node(const entry &V) : Next(nullptr), Val(V) {}
7070
};
7171

72-
static void add_node(node *N) {
73-
if (Tail)
74-
Tail->Next = N;
75-
else
76-
Head = N;
77-
Tail = N;
78-
}
72+
/// Add a node to the Registry: this is the interface between the plugin and
73+
/// the executable.
74+
///
75+
/// This function is exported by the executable and called by the plugin to
76+
/// add a node to the executable's registry. Therefore it's not defined here
77+
/// to avoid it being instantiated in the plugin and is instead defined in
78+
/// the executable (see LLVM_INSTANTIATE_REGISTRY below).
79+
static void add_node(node *N);
7980

8081
/// Iterators for registry entries.
8182
///
@@ -120,61 +121,23 @@ namespace llvm {
120121
add_node(&Node);
121122
}
122123
};
123-
124-
/// A dynamic import facility. This is used on Windows to
125-
/// import the entries added in the plugin.
126-
static void import(sys::DynamicLibrary &DL, const char *RegistryName) {
127-
typedef void *(*GetRegistry)();
128-
std::string Name("LLVMGetRegistry_");
129-
Name.append(RegistryName);
130-
GetRegistry Getter =
131-
(GetRegistry)(intptr_t)DL.getAddressOfSymbol(Name.c_str());
132-
if (Getter) {
133-
// Call the getter function in order to get the full copy of the
134-
// registry defined in the plugin DLL, and copy them over to the
135-
// current Registry.
136-
typedef std::pair<const node *, const node *> Info;
137-
Info *I = static_cast<Info *>(Getter());
138-
iterator begin(I->first);
139-
iterator end(I->second);
140-
for (++end; begin != end; ++begin) {
141-
// This Node object needs to remain alive for the
142-
// duration of the program.
143-
add_node(new node(*begin));
144-
}
145-
}
146-
}
147-
148-
/// Retrieve the data to be passed across DLL boundaries when
149-
/// importing registries from another DLL on Windows.
150-
static void *exportRegistry() {
151-
static std::pair<const node *, const node *> Info(Head, Tail);
152-
return &Info;
153-
}
154124
};
155-
156-
157-
// Since these are defined in a header file, plugins must be sure to export
158-
// these symbols.
159-
template <typename T>
160-
typename Registry<T>::node *Registry<T>::Head;
161-
162-
template <typename T>
163-
typename Registry<T>::node *Registry<T>::Tail;
164125
} // end namespace llvm
165126

166-
#ifdef LLVM_ON_WIN32
167-
#define LLVM_EXPORT_REGISTRY(REGISTRY_CLASS) \
168-
extern "C" { \
169-
__declspec(dllexport) void *__cdecl LLVMGetRegistry_##REGISTRY_CLASS() { \
170-
return REGISTRY_CLASS::exportRegistry(); \
171-
} \
127+
/// Instantiate a registry class.
128+
///
129+
/// This instantiates add_node and the Head and Tail pointers.
130+
#define LLVM_INSTANTIATE_REGISTRY(REGISTRY_CLASS) \
131+
namespace llvm { \
132+
template<> void REGISTRY_CLASS::add_node(REGISTRY_CLASS::node *N) { \
133+
if (Tail) \
134+
Tail->Next = N; \
135+
else \
136+
Head = N; \
137+
Tail = N; \
138+
} \
139+
template<> typename REGISTRY_CLASS::node *REGISTRY_CLASS::Head = nullptr; \
140+
template<> typename REGISTRY_CLASS::node *REGISTRY_CLASS::Tail = nullptr; \
172141
}
173-
#define LLVM_IMPORT_REGISTRY(REGISTRY_CLASS, DL) \
174-
REGISTRY_CLASS::import(DL, #REGISTRY_CLASS)
175-
#else
176-
#define LLVM_EXPORT_REGISTRY(REGISTRY_CLASS)
177-
#define LLVM_IMPORT_REGISTRY(REGISTRY_CLASS, DL)
178-
#endif
179142

180143
#endif // LLVM_SUPPORT_REGISTRY_H

‎llvm/lib/CodeGen/GCMetadataPrinter.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
#include "llvm/CodeGen/GCMetadataPrinter.h"
1515
using namespace llvm;
1616

17+
LLVM_INSTANTIATE_REGISTRY(GCMetadataPrinterRegistry)
18+
1719
GCMetadataPrinter::GCMetadataPrinter() {}
1820

1921
GCMetadataPrinter::~GCMetadataPrinter() {}

‎llvm/lib/CodeGen/GCStrategy.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
using namespace llvm;
1818

19+
LLVM_INSTANTIATE_REGISTRY(GCRegistry)
20+
1921
GCStrategy::GCStrategy()
2022
: UseStatepoints(false), NeededSafePoints(0), CustomReadBarriers(false),
2123
CustomWriteBarriers(false), CustomRoots(false), InitRoots(true),

0 commit comments

Comments
 (0)
Please sign in to comment.