blob: 866cfa15dce8811567ae1df8c0903f5c51c8300f [file] [log] [blame]
Daniel Dunbar39176082009-03-20 00:20:03 +00001//===--- ToolChains.cpp - ToolChain Implementations ---------------------*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "ToolChains.h"
11
Daniel Dunbarf3cad362009-03-25 04:13:45 +000012#include "clang/Driver/Arg.h"
13#include "clang/Driver/ArgList.h"
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000014#include "clang/Driver/Driver.h"
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +000015#include "clang/Driver/DriverDiagnostic.h"
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000016#include "clang/Driver/HostInfo.h"
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +000017#include "clang/Driver/Option.h"
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000018
19#include "llvm/ADT/StringExtras.h"
20#include "llvm/System/Path.h"
21
Daniel Dunbar39176082009-03-20 00:20:03 +000022using namespace clang::driver;
23using namespace clang::driver::toolchains;
24
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +000025/// Darwin_X86 - Darwin tool chain for i386 and x86_64.
26
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000027Darwin_X86::Darwin_X86(const HostInfo &Host, const char *Arch,
28 const char *Platform, const char *OS,
29 const unsigned (&_DarwinVersion)[3],
30 const unsigned (&_GCCVersion)[3])
31 : ToolChain(Host, Arch, Platform, OS)
32{
33 DarwinVersion[0] = _DarwinVersion[0];
34 DarwinVersion[1] = _DarwinVersion[1];
35 DarwinVersion[2] = _DarwinVersion[2];
36 GCCVersion[0] = _GCCVersion[0];
37 GCCVersion[1] = _GCCVersion[1];
38 GCCVersion[2] = _GCCVersion[2];
39
40 ToolChainDir = "i686-apple-darwin";
41 ToolChainDir += llvm::utostr(DarwinVersion[0]);
42 ToolChainDir += "/";
43 ToolChainDir += llvm::utostr(GCCVersion[0]);
44 ToolChainDir += '.';
45 ToolChainDir += llvm::utostr(GCCVersion[1]);
46 ToolChainDir += '.';
47 ToolChainDir += llvm::utostr(GCCVersion[2]);
48
49 std::string Path;
50 if (getArchName() == "x86_64") {
51 Path = getHost().getDriver().Dir;
52 Path += "/../lib/gcc/";
53 Path += getToolChainDir();
54 Path += "/x86_64";
55 getFilePaths().push_back(Path);
56
57 Path = "/usr/lib/gcc/";
58 Path += getToolChainDir();
59 Path += "/x86_64";
60 getFilePaths().push_back(Path);
61 }
62
63 Path = getHost().getDriver().Dir;
64 Path += "/../lib/gcc/";
65 Path += getToolChainDir();
66 getFilePaths().push_back(Path);
67
68 Path = "/usr/lib/gcc/";
69 Path += getToolChainDir();
70 getFilePaths().push_back(Path);
71
72 Path = getHost().getDriver().Dir;
73 Path += "/../libexec/gcc/";
74 Path += getToolChainDir();
75 getProgramPaths().push_back(Path);
76
77 Path = "/usr/libexec/gcc/";
78 Path += getToolChainDir();
79 getProgramPaths().push_back(Path);
80
Daniel Dunbar82fa7c52009-03-24 04:07:10 +000081 Path = getHost().getDriver().Dir;
82 Path += "/../libexec";
83 getProgramPaths().push_back(Path);
84
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000085 getProgramPaths().push_back(getHost().getDriver().Dir);
86}
87
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +000088Darwin_X86::~Darwin_X86() {
89 // Free tool implementations.
90 for (llvm::DenseMap<unsigned, Tool*>::iterator
91 it = Tools.begin(), ie = Tools.end(); it != ie; ++it)
92 delete it->second;
93}
94
95Tool &Darwin_X86::SelectTool(const Compilation &C,
96 const JobAction &JA) const {
97 Action::ActionClass Key;
Daniel Dunbaraf80e1f2009-03-24 18:57:02 +000098 if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getArchName()))
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +000099 Key = Action::AnalyzeJobClass;
100 else
101 Key = JA.getKind();
102
103 Tool *&T = Tools[Key];
104 if (!T) {
105 switch (Key) {
106 case Action::InputClass:
107 case Action::BindArchClass:
108 assert(0 && "Invalid tool kind.");
109 case Action::PreprocessJobClass:
110 T = new tools::gcc::Preprocess(*this); break;
111 case Action::PrecompileJobClass:
112 T = new tools::gcc::Precompile(*this); break;
113 case Action::AnalyzeJobClass:
114 T = new tools::Clang(*this); break;
115 case Action::CompileJobClass:
116 T = new tools::gcc::Compile(*this); break;
117 case Action::AssembleJobClass:
Daniel Dunbar8cac5f72009-03-20 16:06:39 +0000118 T = new tools::darwin::Assemble(*this); break;
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000119 case Action::LinkJobClass:
120 T = new tools::gcc::Link(*this); break;
121 case Action::LipoJobClass:
122 T = new tools::darwin::Lipo(*this); break;
123 }
124 }
125
126 return *T;
127}
128
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000129DerivedArgList *Darwin_X86::TranslateArgs(InputArgList &Args) const {
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000130 DerivedArgList *DAL = new DerivedArgList(Args, false);
131
132 for (ArgList::iterator it = Args.begin(), ie = Args.end(); it != ie; ++it) {
133 Arg *A = *it;
134
135 if (A->getOption().matches(options::OPT_Xarch__)) {
136 // FIXME: Canonicalize name.
137 if (getArchName() != A->getValue(Args, 0))
138 continue;
139
140 // FIXME: The arg is leaked here, and we should have a nicer
141 // interface for this.
142 const Driver &D = getHost().getDriver();
143 unsigned Prev, Index = Prev = A->getIndex() + 1;
144 Arg *XarchArg = D.getOpts().ParseOneArg(Args, Index);
145
146 // If the argument parsing failed or more than one argument was
147 // consumed, the -Xarch_ argument's parameter tried to consume
148 // extra arguments. Emit an error and ignore.
149 //
150 // We also want to disallow any options which would alter the
151 // driver behavior; that isn't going to work in our model. We
152 // use isDriverOption() as an approximation, although things
153 // like -O4 are going to slip through.
154 if (!XarchArg || Index > Prev + 1 ||
155 XarchArg->getOption().isDriverOption()) {
156 D.Diag(clang::diag::err_drv_invalid_Xarch_argument)
157 << A->getAsString(Args);
158 continue;
159 }
160
161 A = XarchArg;
162 }
163
164 // FIXME: Translate.
165 DAL->append(A);
166 }
167
168 return DAL;
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000169}
170
171bool Darwin_X86::IsMathErrnoDefault() const {
172 return false;
173}
174
175bool Darwin_X86::IsUnwindTablesDefault() const {
176 // FIXME: Gross; we should probably have some separate target
177 // definition, possibly even reusing the one in clang.
178 return getArchName() == "x86_64";
179}
180
181const char *Darwin_X86::GetDefaultRelocationModel() const {
182 return "pic";
183}
184
185const char *Darwin_X86::GetForcedPicModel() const {
186 if (getArchName() == "x86_64")
187 return "pic";
188 return 0;
189}
190
Daniel Dunbar39176082009-03-20 00:20:03 +0000191/// Generic_GCC - A tool chain using the 'gcc' command to perform
192/// all subcommands; this relies on gcc translating the majority of
193/// command line options.
194
Daniel Dunbarc50b00d2009-03-23 16:15:50 +0000195Generic_GCC::Generic_GCC(const HostInfo &Host, const char *Arch,
196 const char *Platform, const char *OS)
197 : ToolChain(Host, Arch, Platform, OS)
198{
Daniel Dunbar82fa7c52009-03-24 04:07:10 +0000199 std::string Path(getHost().getDriver().Dir);
200 Path += "/../libexec";
201 getProgramPaths().push_back(Path);
202
Daniel Dunbarc50b00d2009-03-23 16:15:50 +0000203 getProgramPaths().push_back(getHost().getDriver().Dir);
204}
205
Daniel Dunbar39176082009-03-20 00:20:03 +0000206Generic_GCC::~Generic_GCC() {
207 // Free tool implementations.
208 for (llvm::DenseMap<unsigned, Tool*>::iterator
209 it = Tools.begin(), ie = Tools.end(); it != ie; ++it)
210 delete it->second;
211}
212
213Tool &Generic_GCC::SelectTool(const Compilation &C,
214 const JobAction &JA) const {
215 Action::ActionClass Key;
Daniel Dunbaraf80e1f2009-03-24 18:57:02 +0000216 if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getArchName()))
Daniel Dunbar39176082009-03-20 00:20:03 +0000217 Key = Action::AnalyzeJobClass;
218 else
219 Key = JA.getKind();
220
221 Tool *&T = Tools[Key];
222 if (!T) {
223 switch (Key) {
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000224 case Action::InputClass:
225 case Action::BindArchClass:
Daniel Dunbar39176082009-03-20 00:20:03 +0000226 assert(0 && "Invalid tool kind.");
227 case Action::PreprocessJobClass:
228 T = new tools::gcc::Preprocess(*this); break;
229 case Action::PrecompileJobClass:
230 T = new tools::gcc::Precompile(*this); break;
231 case Action::AnalyzeJobClass:
232 T = new tools::Clang(*this); break;
233 case Action::CompileJobClass:
234 T = new tools::gcc::Compile(*this); break;
235 case Action::AssembleJobClass:
236 T = new tools::gcc::Assemble(*this); break;
237 case Action::LinkJobClass:
238 T = new tools::gcc::Link(*this); break;
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000239
240 // This is a bit ungeneric, but the only platform using a driver
241 // driver is Darwin.
242 case Action::LipoJobClass:
243 T = new tools::darwin::Lipo(*this); break;
Daniel Dunbar39176082009-03-20 00:20:03 +0000244 }
245 }
246
247 return *T;
248}
249
250bool Generic_GCC::IsMathErrnoDefault() const {
251 return true;
252}
253
254bool Generic_GCC::IsUnwindTablesDefault() const {
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000255 // FIXME: Gross; we should probably have some separate target
256 // definition, possibly even reusing the one in clang.
Daniel Dunbar39176082009-03-20 00:20:03 +0000257 return getArchName() == "x86_64";
258}
259
260const char *Generic_GCC::GetDefaultRelocationModel() const {
261 return "static";
262}
263
264const char *Generic_GCC::GetForcedPicModel() const {
265 return 0;
266}
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000267
268DerivedArgList *Generic_GCC::TranslateArgs(InputArgList &Args) const {
269 return new DerivedArgList(Args, true);
270}