36e5fc7c0ab985b1cf0fa6f8a6d351a79a49aee9
[oota-llvm.git] / tools / llvmc2 / CompilationGraph.cpp
1 //===--- CompilationGraph.cpp - The LLVM Compiler Driver --------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open
6 // Source License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 //  Compilation graph - implementation.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "CompilationGraph.h"
15
16 #include "llvm/Support/CommandLine.h"
17 #include "llvm/ADT/STLExtras.h"
18
19 #include <stdexcept>
20
21 using namespace llvm;
22
23 extern cl::list<std::string> InputFilenames;
24 extern cl::opt<std::string> OutputFilename;
25
26 int llvmcc::CompilationGraph::Build (const sys::Path& tempDir) const {
27   sys::Path In(InputFilenames.at(0)), Out;
28
29   // Find out which language corresponds to the suffix of the first input file
30   LanguageMap::const_iterator Lang = ExtsToLangs.find(In.getSuffix());
31   if (Lang == ExtsToLangs.end())
32     throw std::runtime_error("Unknown suffix!");
33
34   // Find the toolchain corresponding to this language
35   ToolChainMap::const_iterator ToolsIt = ToolChains.find(Lang->second);
36   if (ToolsIt == ToolChains.end())
37     throw std::runtime_error("Unknown language!");
38   ToolChain Tools = ToolsIt->second;
39
40   PathVector JoinList;
41
42   for (cl::list<std::string>::const_iterator B = InputFilenames.begin(),
43         E = InputFilenames.end(); B != E; ++B) {
44     In = sys::Path(*B);
45
46     // Pass input file through the toolchain
47     for (ToolChain::const_iterator B = Tools.begin(), E = Tools.end();
48          B != E; ++B) {
49
50       const Tool* CurTool = B->getPtr();
51
52       // Is this the last step in the chain?
53       if (llvm::next(B) == E || CurTool->IsLast()) {
54         JoinList.push_back(In);
55         break;
56       }
57       else {
58         Out = tempDir;
59         Out.appendComponent(In.getBasename());
60         Out.appendSuffix(CurTool->OutputSuffix());
61         Out.makeUnique(true, NULL);
62         Out.eraseFromDisk();
63       }
64
65       if (CurTool->GenerateAction(In, Out).Execute() != 0)
66         throw std::runtime_error("Tool returned error code!");
67
68       In = Out; Out.clear();
69     }
70   }
71
72   // Pass .o files to linker
73   const Tool* JoinNode = (--Tools.end())->getPtr();
74
75   // If the final output name is empty, set it to "a.out"
76   if (!OutputFilename.empty()) {
77     Out = sys::Path(OutputFilename);
78   }
79   else {
80     Out = sys::Path("a");
81     Out.appendSuffix(JoinNode->OutputSuffix());
82   }
83
84   if (JoinNode->GenerateAction(JoinList, Out).Execute() != 0)
85     throw std::runtime_error("Tool returned error code!");
86
87   return 0;
88 }