diff --git a/include/llvm/CompilerDriver/Plugin.h b/include/llvm/CompilerDriver/Plugin.h index ba22450697b..bfaabee77bf 100644 --- a/include/llvm/CompilerDriver/Plugin.h +++ b/include/llvm/CompilerDriver/Plugin.h @@ -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,26 +33,39 @@ namespace llvmc { virtual void PopulateCompilationGraph(CompilationGraph&) const = 0; }; - // Helper class for RegisterPlugin. - class RegisterPluginImpl { - protected: - RegisterPluginImpl(BasePlugin*); + typedef llvm::Registry PluginRegistry; + + template + struct RegisterPlugin + : public PluginRegistry::Add

{ + typedef PluginRegistry::Add

Base; + + RegisterPlugin(const char* Name = "Nameless", + const char* Desc = "Auto-generated plugin") + : Base(Name, Desc) {} }; - /// RegisterPlugin template - Used to register LLVMC plugins. - template - struct RegisterPlugin : RegisterPluginImpl { - RegisterPlugin() : RegisterPluginImpl (new T()) {} + + /// 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); }; - /// 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); - } #endif // LLVM_TOOLS_LLVMC2_PLUGIN_H diff --git a/tools/llvmc2/Plugin.cpp b/tools/llvmc2/Plugin.cpp index cd94a013205..c9b3960c1e7 100644 --- a/tools/llvmc2/Plugin.cpp +++ b/tools/llvmc2/Plugin.cpp @@ -16,25 +16,48 @@ #include namespace { - typedef std::vector 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 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; } - void PopulateLanguageMap(LanguageMap& langMap) { - for (PluginRegistry::const_iterator B = GlobalPluginRegistry.begin(), - E = GlobalPluginRegistry.end(); B != E; ++B) + PluginLoader::~PluginLoader() { + if (pluginListInitialized) { + for (PluginList::iterator B = Plugins.begin(), E = Plugins.end(); + B != E; ++B) + delete (*B); + } + pluginListInitialized = false; + } + + 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); } diff --git a/tools/llvmc2/llvmc.cpp b/tools/llvmc2/llvmc.cpp index 592a1333f3a..f3a1e571926 100644 --- a/tools/llvmc2/llvmc.cpp +++ b/tools/llvmc2/llvmc.cpp @@ -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(); diff --git a/tools/llvmc2/plugins/Hello/Hello.cpp b/tools/llvmc2/plugins/Hello/Hello.cpp index a243dd86f7e..eb52d249f0b 100644 --- a/tools/llvmc2/plugins/Hello/Hello.cpp +++ b/tools/llvmc2/plugins/Hello/Hello.cpp @@ -25,7 +25,7 @@ struct MyPlugin : public llvmc::BasePlugin { {} }; -static llvmc::RegisterPlugin RP; +static llvmc::RegisterPlugin RP("Hello", "Hello World plugin"); }