Use edge weights to choose the right linker based on input language names.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@50759 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/tools/llvmc2/CompilationGraph.cpp b/tools/llvmc2/CompilationGraph.cpp
index 310413b..f5cefbf 100644
--- a/tools/llvmc2/CompilationGraph.cpp
+++ b/tools/llvmc2/CompilationGraph.cpp
@@ -20,6 +20,7 @@
 
 #include <algorithm>
 #include <iterator>
+#include <iostream>
 #include <limits>
 #include <queue>
 #include <stdexcept>
@@ -36,6 +37,7 @@
   // Return the edge with the maximum weight.
   template <class C>
   const Edge* ChooseEdge(const C& EdgesContainer,
+                         const InputLanguagesSet& InLangs,
                          const std::string& NodeName = "root") {
     const Edge* MaxEdge = 0;
     unsigned MaxWeight = 0;
@@ -44,7 +46,7 @@
     for (typename C::const_iterator B = EdgesContainer.begin(),
            E = EdgesContainer.end(); B != E; ++B) {
       const Edge* E = B->getPtr();
-      unsigned EW = E->Weight();
+      unsigned EW = E->Weight(InLangs);
       if (EW > MaxWeight) {
         MaxEdge = E;
         MaxWeight = EW;
@@ -142,6 +144,7 @@
 // a node that says that it is the last.
 void CompilationGraph::PassThroughGraph (const sys::Path& InFile,
                                          const Node* StartNode,
+                                         const InputLanguagesSet& InLangs,
                                          const sys::Path& TempDir) const {
   bool Last = false;
   sys::Path In = InFile;
@@ -180,6 +183,7 @@
       return;
 
     CurNode = &getNode(ChooseEdge(CurNode->OutEdges,
+                                  InLangs,
                                   CurNode->Name())->ToolName());
     In = Out; Out.clear();
   }
@@ -221,21 +225,32 @@
 }
 
 // Find head of the toolchain corresponding to the given file.
+// Also, insert an input language into InLangs.
 const Node* CompilationGraph::
-FindToolChain(const sys::Path& In, const std::string* forceLanguage) const {
+FindToolChain(const sys::Path& In, const std::string* forceLanguage,
+              InputLanguagesSet& InLangs) const {
+
+  // Determine the input language.
   const std::string& InLanguage =
     forceLanguage ? *forceLanguage : getLanguage(In);
+
+  // Add the current input language to the input language set.
+  InLangs.insert(InLanguage);
+
+  // Find the toolchain for the input language.
   const tools_vector_type& TV = getToolsVector(InLanguage);
   if (TV.empty())
     throw std::runtime_error("No toolchain corresponding to language"
                              + InLanguage + " found!");
-  return &getNode(ChooseEdge(TV)->ToolName());
+  return &getNode(ChooseEdge(TV, InLangs)->ToolName());
 }
 
 // Build the targets. Command-line options are passed through
 // temporary variables.
 int CompilationGraph::Build (const sys::Path& TempDir) {
 
+  InputLanguagesSet InLangs;
+
   // This is related to -x option handling.
   cl::list<std::string>::const_iterator xIter = Languages.begin(),
     xBegin = xIter, xEnd = Languages.end();
@@ -284,9 +299,9 @@
     }
 
     // Find the toolchain corresponding to this file.
-    const Node* N = FindToolChain(In, xLanguage);
+    const Node* N = FindToolChain(In, xLanguage, InLangs);
     // Pass file through the chain starting at head.
-    PassThroughGraph(In, N, TempDir);
+    PassThroughGraph(In, N, InLangs, TempDir);
   }
 
   std::vector<const Node*> JTV;
@@ -324,9 +339,10 @@
       throw std::runtime_error("Tool returned error code!");
 
     if (!IsLast) {
-      const Node* NextNode = &getNode(ChooseEdge(CurNode->OutEdges,
-                                                 CurNode->Name())->ToolName());
-      PassThroughGraph(Out, NextNode, TempDir);
+      const Node* NextNode =
+        &getNode(ChooseEdge(CurNode->OutEdges, InLangs,
+                            CurNode->Name())->ToolName());
+      PassThroughGraph(Out, NextNode, InLangs, TempDir);
     }
   }