Convert llvmc2 plugins to use llvm/Support/Registry.h machinery.
authorMikhail Glushenkov <foldr@codedgers.com>
Mon, 22 Sep 2008 20:51:19 +0000 (20:51 +0000)
committerMikhail Glushenkov <foldr@codedgers.com>
Mon, 22 Sep 2008 20:51:19 +0000 (20:51 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@56467 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CompilerDriver/Plugin.h
tools/llvmc2/Plugin.cpp
tools/llvmc2/llvmc.cpp
tools/llvmc2/plugins/Hello/Hello.cpp

index ba22450697b31a33696348e1b6a3d89dd50d8b20..bfaabee77bf36a67a49382b78123524f95a03f5a 100644 (file)
@@ -14,6 +14,8 @@
 #ifndef LLVM_TOOLS_LLVMC2_PLUGIN_H
 #define LLVM_TOOLS_LLVMC2_PLUGIN_H
 
+#include "llvm/Support/Registry.h"
+
 namespace llvmc {
 
   class LanguageMap;
@@ -31,25 +33,38 @@ namespace llvmc {
     virtual void PopulateCompilationGraph(CompilationGraph&) const = 0;
   };
 
-  // Helper class for RegisterPlugin.
-  class RegisterPluginImpl {
-  protected:
-    RegisterPluginImpl(BasePlugin*);
-  };
+  typedef llvm::Registry<BasePlugin> PluginRegistry;
 
-  /// RegisterPlugin<T> template - Used to register LLVMC plugins.
-  template <class T>
-  struct RegisterPlugin : RegisterPluginImpl {
-    RegisterPlugin() : RegisterPluginImpl (new T()) {}
+  template <class P>
+  struct RegisterPlugin
+    : public PluginRegistry::Add<P> {
+    typedef PluginRegistry::Add<P> Base;
+
+    RegisterPlugin(const char* Name = "Nameless",
+                   const char* Desc = "Auto-generated plugin")
+      : Base(Name, Desc) {}
   };
 
-  /// PopulateLanguageMap - Fills in the language map by calling
-  /// PopulateLanguageMap methods of all plugins.
-  void PopulateLanguageMap(LanguageMap& langMap);
 
-  /// PopulateCompilationGraph - Populates the compilation graph by
-  /// calling PopulateCompilationGraph methods of all plugins.
-  void PopulateCompilationGraph(CompilationGraph& tools);
+  /// PluginLoader - Helper class used by the main program for
+  /// lifetime management.
+  struct PluginLoader {
+    PluginLoader();
+    ~PluginLoader();
+
+    /// PopulateLanguageMap - Fills in the language map by calling
+    /// PopulateLanguageMap methods of all plugins.
+    void PopulateLanguageMap(LanguageMap& langMap);
+
+    /// PopulateCompilationGraph - Populates the compilation graph by
+    /// calling PopulateCompilationGraph methods of all plugins.
+    void PopulateCompilationGraph(CompilationGraph& tools);
+
+  private:
+    // noncopyable
+    PluginLoader(const PluginLoader& other);
+    const PluginLoader& operator=(const PluginLoader& other);
+  };
 
 }
 
index cd94a013205141897bf9ffecc676f035c693cf5f..c9b3960c1e75c2fbbdc0e227e047ff5c9420ae58 100644 (file)
 #include <vector>
 
 namespace {
-  typedef std::vector<llvmc::BasePlugin*> PluginRegistry;
-  static PluginRegistry GlobalPluginRegistry;
+
+  // Registry::Add<> does not do lifetime management (probably issues
+  // with static constructor/destructor ordering), so we have to
+  // implement it here.
+  //
+  // All this static registration/life-before-main model seems
+  // unnecessary convoluted to me.
+
+  static bool pluginListInitialized = false;
+  typedef std::vector<const llvmc::BasePlugin*> PluginList;
+  static PluginList Plugins;
 }
 
 namespace llvmc {
 
-  RegisterPluginImpl::RegisterPluginImpl(BasePlugin* plugin) {
-    GlobalPluginRegistry.push_back(plugin);
+  PluginLoader::PluginLoader() {
+    if (!pluginListInitialized) {
+      for (PluginRegistry::iterator B = PluginRegistry::begin(),
+             E = PluginRegistry::end(); B != E; ++B)
+        Plugins.push_back(B->instantiate());
+    }
+    pluginListInitialized = true;
+  }
+
+  PluginLoader::~PluginLoader() {
+    if (pluginListInitialized) {
+      for (PluginList::iterator B = Plugins.begin(), E = Plugins.end();
+           B != E; ++B)
+        delete (*B);
+    }
+    pluginListInitialized = false;
   }
 
-  void PopulateLanguageMap(LanguageMap& langMap) {
-    for (PluginRegistry::const_iterator B = GlobalPluginRegistry.begin(),
-           E = GlobalPluginRegistry.end(); B != E; ++B)
+  void PluginLoader::PopulateLanguageMap(LanguageMap& langMap) {
+    for (PluginList::iterator B = Plugins.begin(), E = Plugins.end();
+         B != E; ++B)
       (*B)->PopulateLanguageMap(langMap);
   }
 
-  void PopulateCompilationGraph(CompilationGraph& graph) {
-    for (PluginRegistry::const_iterator B = GlobalPluginRegistry.begin(),
-           E = GlobalPluginRegistry.end(); B != E; ++B)
+  void PluginLoader::PopulateCompilationGraph(CompilationGraph& graph) {
+    for (PluginList::iterator B = Plugins.begin(), E = Plugins.end();
+         B != E; ++B)
       (*B)->PopulateCompilationGraph(graph);
   }
 
index 592a1333f3aa1cbfedc6bdba20d15a49ef4892f4..f3a1e57192659e97186b610af4b9d8c48b3a6ff6 100644 (file)
@@ -85,8 +85,9 @@ int main(int argc, char** argv) {
     cl::ParseCommandLineOptions
       (argc, argv, "LLVM Compiler Driver (Work In Progress)", true);
 
-    PopulateLanguageMap(langMap);
-    PopulateCompilationGraph(graph);
+    PluginLoader Plugins;
+    Plugins.PopulateLanguageMap(langMap);
+    Plugins.PopulateCompilationGraph(graph);
 
     if (WriteGraph) {
       graph.writeGraph();
index a243dd86f7eb8e9a9908aab2c3571a1ebf8f3188..eb52d249f0b43d3c4872de3de94fc418db7e1293 100644 (file)
@@ -25,7 +25,7 @@ struct MyPlugin : public llvmc::BasePlugin {
   {}
 };
 
-static llvmc::RegisterPlugin<MyPlugin> RP;
+static llvmc::RegisterPlugin<MyPlugin> RP("Hello", "Hello World plugin");
 
 }