зеркало из https://github.com/mozilla/gecko-dev.git
322 строки
13 KiB
Diff
322 строки
13 KiB
Diff
|
commit eca7f4535bffb1c86cb1620b9d9425ff3ce31ab9
|
||
|
Author: John Brawn <john.brawn@arm.com>
|
||
|
Date: Fri Aug 5 11:01:08 2016 +0000
|
||
|
|
||
|
Reapply r276973 "Adjust Registry interface to not require plugins to export a registry"
|
||
|
|
||
|
This differs from the previous version by being more careful about template
|
||
|
instantiation/specialization in order to prevent errors when building with
|
||
|
clang -Werror. Specifically:
|
||
|
* begin is not defined in the template and is instead instantiated when Head
|
||
|
is. I think the warning when we don't do that is wrong (PR28815) but for now
|
||
|
at least do it this way to avoid the warning.
|
||
|
* Instead of performing template specializations in LLVM_INSTANTIATE_REGISTRY
|
||
|
instead provide a template definition then do explicit instantiation. No
|
||
|
compiler I've tried has problems with doing it the other way, but strictly
|
||
|
speaking it's not permitted by the C++ standard so better safe than sorry.
|
||
|
|
||
|
Original commit message:
|
||
|
|
||
|
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.
|
||
|
|
||
|
|
||
|
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@277806 91177308-0d34-0410-b5e6-96231b3b80d8
|
||
|
|
||
|
diff --git a/llvm/include/llvm/Support/Registry.h b/llvm/include/llvm/Support/Registry.h
|
||
|
index 27f025fcd08..9557f56093b 100644
|
||
|
--- a/llvm/include/llvm/Support/Registry.h
|
||
|
+++ b/llvm/include/llvm/Support/Registry.h
|
||
|
@@ -44,6 +44,7 @@ namespace llvm {
|
||
|
template <typename T>
|
||
|
class Registry {
|
||
|
public:
|
||
|
+ typedef T type;
|
||
|
typedef SimpleRegistryEntry<T> entry;
|
||
|
|
||
|
class node;
|
||
|
@@ -69,13 +70,14 @@ namespace llvm {
|
||
|
node(const entry &V) : Next(nullptr), Val(V) {}
|
||
|
};
|
||
|
|
||
|
- static void add_node(node *N) {
|
||
|
- if (Tail)
|
||
|
- Tail->Next = N;
|
||
|
- else
|
||
|
- Head = N;
|
||
|
- Tail = N;
|
||
|
- }
|
||
|
+ /// Add a node to the Registry: this is the interface between the plugin and
|
||
|
+ /// the executable.
|
||
|
+ ///
|
||
|
+ /// This function is exported by the executable and called by the plugin to
|
||
|
+ /// 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);
|
||
|
|
||
|
/// Iterators for registry entries.
|
||
|
///
|
||
|
@@ -92,7 +94,9 @@ namespace llvm {
|
||
|
const entry *operator->() const { return &Cur->Val; }
|
||
|
};
|
||
|
|
||
|
- static iterator begin() { return iterator(Head); }
|
||
|
+ // 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 end() { return iterator(nullptr); }
|
||
|
|
||
|
static iterator_range<iterator> entries() {
|
||
|
@@ -120,61 +124,37 @@ namespace llvm {
|
||
|
add_node(&Node);
|
||
|
}
|
||
|
};
|
||
|
-
|
||
|
- /// A dynamic import facility. This is used on Windows to
|
||
|
- /// import the entries added in the plugin.
|
||
|
- static void import(sys::DynamicLibrary &DL, const char *RegistryName) {
|
||
|
- typedef void *(*GetRegistry)();
|
||
|
- std::string Name("LLVMGetRegistry_");
|
||
|
- Name.append(RegistryName);
|
||
|
- GetRegistry Getter =
|
||
|
- (GetRegistry)(intptr_t)DL.getAddressOfSymbol(Name.c_str());
|
||
|
- if (Getter) {
|
||
|
- // Call the getter function in order to get the full copy of the
|
||
|
- // registry defined in the plugin DLL, and copy them over to the
|
||
|
- // current Registry.
|
||
|
- typedef std::pair<const node *, const node *> Info;
|
||
|
- Info *I = static_cast<Info *>(Getter());
|
||
|
- iterator begin(I->first);
|
||
|
- iterator end(I->second);
|
||
|
- for (++end; begin != end; ++begin) {
|
||
|
- // This Node object needs to remain alive for the
|
||
|
- // duration of the program.
|
||
|
- add_node(new node(*begin));
|
||
|
- }
|
||
|
- }
|
||
|
- }
|
||
|
-
|
||
|
- /// Retrieve the data to be passed across DLL boundaries when
|
||
|
- /// importing registries from another DLL on Windows.
|
||
|
- static void *exportRegistry() {
|
||
|
- static std::pair<const node *, const node *> Info(Head, Tail);
|
||
|
- return &Info;
|
||
|
- }
|
||
|
};
|
||
|
-
|
||
|
-
|
||
|
- // Since these are defined in a header file, plugins must be sure to export
|
||
|
- // these symbols.
|
||
|
- template <typename T>
|
||
|
- typename Registry<T>::node *Registry<T>::Head;
|
||
|
-
|
||
|
- template <typename T>
|
||
|
- typename Registry<T>::node *Registry<T>::Tail;
|
||
|
} // end namespace llvm
|
||
|
|
||
|
-#ifdef LLVM_ON_WIN32
|
||
|
-#define LLVM_EXPORT_REGISTRY(REGISTRY_CLASS) \
|
||
|
- extern "C" { \
|
||
|
- __declspec(dllexport) void *__cdecl LLVMGetRegistry_##REGISTRY_CLASS() { \
|
||
|
- return REGISTRY_CLASS::exportRegistry(); \
|
||
|
- } \
|
||
|
+/// 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 \
|
||
|
+ void Registry<REGISTRY_CLASS::type>::add_node(REGISTRY_CLASS::node*); \
|
||
|
+ template REGISTRY_CLASS::iterator Registry<REGISTRY_CLASS::type>::begin(); \
|
||
|
}
|
||
|
-#define LLVM_IMPORT_REGISTRY(REGISTRY_CLASS, DL) \
|
||
|
- REGISTRY_CLASS::import(DL, #REGISTRY_CLASS)
|
||
|
-#else
|
||
|
-#define LLVM_EXPORT_REGISTRY(REGISTRY_CLASS)
|
||
|
-#define LLVM_IMPORT_REGISTRY(REGISTRY_CLASS, DL)
|
||
|
-#endif
|
||
|
|
||
|
#endif // LLVM_SUPPORT_REGISTRY_H
|
||
|
diff --git a/llvm/lib/CodeGen/GCMetadataPrinter.cpp b/llvm/lib/CodeGen/GCMetadataPrinter.cpp
|
||
|
index bb8cfa1cc80..d183c7f2980 100644
|
||
|
--- a/llvm/lib/CodeGen/GCMetadataPrinter.cpp
|
||
|
+++ b/llvm/lib/CodeGen/GCMetadataPrinter.cpp
|
||
|
@@ -14,6 +14,8 @@
|
||
|
#include "llvm/CodeGen/GCMetadataPrinter.h"
|
||
|
using namespace llvm;
|
||
|
|
||
|
+LLVM_INSTANTIATE_REGISTRY(GCMetadataPrinterRegistry)
|
||
|
+
|
||
|
GCMetadataPrinter::GCMetadataPrinter() {}
|
||
|
|
||
|
GCMetadataPrinter::~GCMetadataPrinter() {}
|
||
|
diff --git a/llvm/lib/CodeGen/GCStrategy.cpp b/llvm/lib/CodeGen/GCStrategy.cpp
|
||
|
index 554d326942e..31ab86fdf27 100644
|
||
|
--- a/llvm/lib/CodeGen/GCStrategy.cpp
|
||
|
+++ b/llvm/lib/CodeGen/GCStrategy.cpp
|
||
|
@@ -16,6 +16,8 @@
|
||
|
|
||
|
using namespace llvm;
|
||
|
|
||
|
+LLVM_INSTANTIATE_REGISTRY(GCRegistry)
|
||
|
+
|
||
|
GCStrategy::GCStrategy()
|
||
|
: UseStatepoints(false), NeededSafePoints(0), CustomReadBarriers(false),
|
||
|
CustomWriteBarriers(false), CustomRoots(false), InitRoots(true),
|
||
|
|
||
|
commit 0cfb8c87dfc0a8366d6db83f93aa50e9514dbf9d
|
||
|
Author: John Brawn <john.brawn@arm.com>
|
||
|
Date: Fri Aug 5 11:01:08 2016 +0000
|
||
|
|
||
|
Reapply r276973 "Adjust Registry interface to not require plugins to export a registry"
|
||
|
|
||
|
This differs from the previous version by being more careful about template
|
||
|
instantiation/specialization in order to prevent errors when building with
|
||
|
clang -Werror. Specifically:
|
||
|
* begin is not defined in the template and is instead instantiated when Head
|
||
|
is. I think the warning when we don't do that is wrong (PR28815) but for now
|
||
|
at least do it this way to avoid the warning.
|
||
|
* Instead of performing template specializations in LLVM_INSTANTIATE_REGISTRY
|
||
|
instead provide a template definition then do explicit instantiation. No
|
||
|
compiler I've tried has problems with doing it the other way, but strictly
|
||
|
speaking it's not permitted by the C++ standard so better safe than sorry.
|
||
|
|
||
|
Original commit message:
|
||
|
|
||
|
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.
|
||
|
|
||
|
|
||
|
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@277806 91177308-0d34-0410-b5e6-96231b3b80d8
|
||
|
|
||
|
diff --git a/clang/examples/AnnotateFunctions/CMakeLists.txt b/clang/examples/AnnotateFunctions/CMakeLists.txt
|
||
|
index cf564d527d..5684abf238 100644
|
||
|
--- a/clang/examples/AnnotateFunctions/CMakeLists.txt
|
||
|
+++ b/clang/examples/AnnotateFunctions/CMakeLists.txt
|
||
|
@@ -1,4 +1,4 @@
|
||
|
-add_llvm_loadable_module(AnnotateFunctions AnnotateFunctions.cpp)
|
||
|
+add_llvm_loadable_module(AnnotateFunctions AnnotateFunctions.cpp PLUGIN_TOOL clang)
|
||
|
|
||
|
if(LLVM_ENABLE_PLUGINS AND (WIN32 OR CYGWIN))
|
||
|
target_link_libraries(AnnotateFunctions PRIVATE
|
||
|
diff --git a/clang/examples/PrintFunctionNames/CMakeLists.txt b/clang/examples/PrintFunctionNames/CMakeLists.txt
|
||
|
index 5a00d5036f..f5f818866c 100644
|
||
|
--- a/clang/examples/PrintFunctionNames/CMakeLists.txt
|
||
|
+++ b/clang/examples/PrintFunctionNames/CMakeLists.txt
|
||
|
@@ -9,7 +9,7 @@ if( NOT MSVC ) # MSVC mangles symbols differently, and
|
||
|
endif()
|
||
|
endif()
|
||
|
|
||
|
-add_llvm_loadable_module(PrintFunctionNames PrintFunctionNames.cpp)
|
||
|
+add_llvm_loadable_module(PrintFunctionNames PrintFunctionNames.cpp PLUGIN_TOOL clang)
|
||
|
|
||
|
if(LLVM_ENABLE_PLUGINS AND (WIN32 OR CYGWIN))
|
||
|
target_link_libraries(PrintFunctionNames PRIVATE
|
||
|
diff --git a/clang/include/clang/Frontend/FrontendPluginRegistry.h b/clang/include/clang/Frontend/FrontendPluginRegistry.h
|
||
|
index ecab630c12..9d7ee08d95 100644
|
||
|
--- a/clang/include/clang/Frontend/FrontendPluginRegistry.h
|
||
|
+++ b/clang/include/clang/Frontend/FrontendPluginRegistry.h
|
||
|
@@ -13,9 +13,6 @@
|
||
|
#include "clang/Frontend/FrontendAction.h"
|
||
|
#include "llvm/Support/Registry.h"
|
||
|
|
||
|
-// Instantiated in FrontendAction.cpp.
|
||
|
-extern template class llvm::Registry<clang::PluginASTAction>;
|
||
|
-
|
||
|
namespace clang {
|
||
|
|
||
|
/// The frontend plugin registry.
|
||
|
diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h
|
||
|
index c9b712504e..000df6647f 100644
|
||
|
--- a/clang/include/clang/Lex/Preprocessor.h
|
||
|
+++ b/clang/include/clang/Lex/Preprocessor.h
|
||
|
@@ -1972,6 +1972,4 @@ typedef llvm::Registry<PragmaHandler> PragmaHandlerRegistry;
|
||
|
|
||
|
} // end namespace clang
|
||
|
|
||
|
-extern template class llvm::Registry<clang::PragmaHandler>;
|
||
|
-
|
||
|
#endif
|
||
|
diff --git a/clang/lib/Frontend/FrontendAction.cpp b/clang/lib/Frontend/FrontendAction.cpp
|
||
|
index d2c2a80394..2945b8925f 100644
|
||
|
--- a/clang/lib/Frontend/FrontendAction.cpp
|
||
|
+++ b/clang/lib/Frontend/FrontendAction.cpp
|
||
|
@@ -33,7 +33,7 @@
|
||
|
#include <system_error>
|
||
|
using namespace clang;
|
||
|
|
||
|
-template class llvm::Registry<clang::PluginASTAction>;
|
||
|
+LLVM_INSTANTIATE_REGISTRY(FrontendPluginRegistry)
|
||
|
|
||
|
namespace {
|
||
|
|
||
|
diff --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp
|
||
|
index 8832c7f80c..f0d6872546 100644
|
||
|
--- a/clang/lib/Lex/Preprocessor.cpp
|
||
|
+++ b/clang/lib/Lex/Preprocessor.cpp
|
||
|
@@ -54,7 +54,7 @@
|
||
|
#include <utility>
|
||
|
using namespace clang;
|
||
|
|
||
|
-template class llvm::Registry<clang::PragmaHandler>;
|
||
|
+LLVM_INSTANTIATE_REGISTRY(PragmaHandlerRegistry)
|
||
|
|
||
|
//===----------------------------------------------------------------------===//
|
||
|
ExternalPreprocessorSource::~ExternalPreprocessorSource() { }
|
||
|
diff --git a/clang/lib/Tooling/CompilationDatabase.cpp b/clang/lib/Tooling/CompilationDatabase.cpp
|
||
|
index 8fc4a1fe5b..6f95bf01f6 100644
|
||
|
--- a/clang/lib/Tooling/CompilationDatabase.cpp
|
||
|
+++ b/clang/lib/Tooling/CompilationDatabase.cpp
|
||
|
@@ -32,6 +32,8 @@
|
||
|
using namespace clang;
|
||
|
using namespace tooling;
|
||
|
|
||
|
+LLVM_INSTANTIATE_REGISTRY(CompilationDatabasePluginRegistry)
|
||
|
+
|
||
|
CompilationDatabase::~CompilationDatabase() {}
|
||
|
|
||
|
std::unique_ptr<CompilationDatabase>
|