DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321
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>