+/// EmitRegisterPlugin - Emit code to register this plugin.
+void EmitRegisterPlugin(int Priority, std::ostream& O) {
+ O << "namespace {\n\n"
+ << "struct Plugin : public llvmc::BasePlugin {\n\n"
+ << Indent1 << "int Priority() const { return " << Priority << "; }\n\n"
+ << Indent1 << "void PopulateLanguageMap(LanguageMap& langMap) const\n"
+ << Indent1 << "{ PopulateLanguageMapLocal(langMap); }\n\n"
+ << Indent1
+ << "void PopulateCompilationGraph(CompilationGraph& graph) const\n"
+ << Indent1 << "{ PopulateCompilationGraphLocal(graph); }\n"
+ << "};\n\n"
+
+ << "static llvmc::RegisterPlugin<Plugin> RP;\n\n}\n\n";
+}
+
+/// EmitIncludes - Emit necessary #include directives and some
+/// additional declarations.
+void EmitIncludes(std::ostream& O) {
+ O << "#include \"llvm/CompilerDriver/CompilationGraph.h\"\n"
+ << "#include \"llvm/CompilerDriver/Plugin.h\"\n"
+ << "#include \"llvm/CompilerDriver/Tool.h\"\n\n"
+
+ << "#include \"llvm/ADT/StringExtras.h\"\n"
+ << "#include \"llvm/Support/CommandLine.h\"\n\n"
+
+ << "#include <cstdlib>\n"
+ << "#include <stdexcept>\n\n"
+
+ << "using namespace llvm;\n"
+ << "using namespace llvmc;\n\n"
+
+ << "extern cl::opt<std::string> OutputFilename;\n\n"
+
+ << "inline const char* checkCString(const char* s)\n"
+ << "{ return s == NULL ? \"\" : s; }\n\n";
+}
+
+/// NotInGraph - Helper function object for FilterNotInGraph.
+struct NotInGraph {
+private:
+ const llvm::StringSet<>& ToolsInGraph_;
+
+public:
+ NotInGraph(const llvm::StringSet<>& ToolsInGraph)
+ : ToolsInGraph_(ToolsInGraph)
+ {}
+
+ bool operator()(const IntrusiveRefCntPtr<ToolProperties>& x) {
+ return (ToolsInGraph_.count(x->Name) == 0);
+ }
+};
+
+/// FilterNotInGraph - Filter out from ToolProps all Tools not
+/// mentioned in the compilation graph definition.
+void FilterNotInGraph (const RecordVector& EdgeVector,
+ ToolPropertiesList& ToolProps) {
+
+ // List all tools mentioned in the graph.
+ llvm::StringSet<> ToolsInGraph;
+
+ for (RecordVector::const_iterator B = EdgeVector.begin(),
+ E = EdgeVector.end(); B != E; ++B) {
+
+ const Record* Edge = *B;
+ const std::string& A = Edge->getValueAsString("a");
+ const std::string& B = Edge->getValueAsString("b");
+
+ if (A != "root")
+ ToolsInGraph.insert(A);
+ ToolsInGraph.insert(B);
+ }
+
+ // Filter ToolPropertiesList.
+ ToolPropertiesList::iterator new_end =
+ std::remove_if(ToolProps.begin(), ToolProps.end(),
+ NotInGraph(ToolsInGraph));
+ ToolProps.erase(new_end, ToolProps.end());
+}
+
+/// CalculatePriority - Calculate the priority of this plugin.
+int CalculatePriority(RecordVector::const_iterator B,
+ RecordVector::const_iterator E) {
+ int total = 0;
+ for (; B!=E; ++B) {
+ total += static_cast<int>((*B)->getValueAsInt("priority"));
+ }
+ return total;
+}
+
+/// FillInEdgeVector - Merge all compilation graph definitions into
+/// one single edge list.
+void FillInEdgeVector(RecordVector::const_iterator B,
+ RecordVector::const_iterator E, RecordVector& Out) {
+ for (; B != E; ++B) {
+ const ListInit* edges = (*B)->getValueAsListInit("edges");
+
+ for (unsigned i = 0; i < edges->size(); ++i)
+ Out.push_back(edges->getElementAsRecord(i));
+ }
+}
+