blob: 3b129cfad18dcecb1f9477790340d1b2415ba1fd [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"
Daniel Dunbarec069ed2009-03-25 06:58:31 +000020#include "llvm/Support/raw_ostream.h"
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000021#include "llvm/System/Path.h"
22
Daniel Dunbar39176082009-03-20 00:20:03 +000023using namespace clang::driver;
24using namespace clang::driver::toolchains;
25
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +000026/// Darwin_X86 - Darwin tool chain for i386 and x86_64.
27
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000028Darwin_X86::Darwin_X86(const HostInfo &Host, const char *Arch,
29 const char *Platform, const char *OS,
30 const unsigned (&_DarwinVersion)[3],
31 const unsigned (&_GCCVersion)[3])
32 : ToolChain(Host, Arch, Platform, OS)
33{
34 DarwinVersion[0] = _DarwinVersion[0];
35 DarwinVersion[1] = _DarwinVersion[1];
36 DarwinVersion[2] = _DarwinVersion[2];
37 GCCVersion[0] = _GCCVersion[0];
38 GCCVersion[1] = _GCCVersion[1];
39 GCCVersion[2] = _GCCVersion[2];
40
Daniel Dunbar02633b52009-03-26 16:23:12 +000041 llvm::raw_string_ostream(MacosxVersionMin)
42 << "10." << DarwinVersion[0] - 4 << '.' << DarwinVersion[1];
43
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000044 ToolChainDir = "i686-apple-darwin";
45 ToolChainDir += llvm::utostr(DarwinVersion[0]);
46 ToolChainDir += "/";
47 ToolChainDir += llvm::utostr(GCCVersion[0]);
48 ToolChainDir += '.';
49 ToolChainDir += llvm::utostr(GCCVersion[1]);
50 ToolChainDir += '.';
51 ToolChainDir += llvm::utostr(GCCVersion[2]);
52
53 std::string Path;
54 if (getArchName() == "x86_64") {
55 Path = getHost().getDriver().Dir;
56 Path += "/../lib/gcc/";
57 Path += getToolChainDir();
58 Path += "/x86_64";
59 getFilePaths().push_back(Path);
60
61 Path = "/usr/lib/gcc/";
62 Path += getToolChainDir();
63 Path += "/x86_64";
64 getFilePaths().push_back(Path);
65 }
66
67 Path = getHost().getDriver().Dir;
68 Path += "/../lib/gcc/";
69 Path += getToolChainDir();
70 getFilePaths().push_back(Path);
71
72 Path = "/usr/lib/gcc/";
73 Path += getToolChainDir();
74 getFilePaths().push_back(Path);
75
76 Path = getHost().getDriver().Dir;
77 Path += "/../libexec/gcc/";
78 Path += getToolChainDir();
79 getProgramPaths().push_back(Path);
80
81 Path = "/usr/libexec/gcc/";
82 Path += getToolChainDir();
83 getProgramPaths().push_back(Path);
84
Daniel Dunbar82fa7c52009-03-24 04:07:10 +000085 Path = getHost().getDriver().Dir;
86 Path += "/../libexec";
87 getProgramPaths().push_back(Path);
88
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000089 getProgramPaths().push_back(getHost().getDriver().Dir);
90}
91
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +000092Darwin_X86::~Darwin_X86() {
93 // Free tool implementations.
94 for (llvm::DenseMap<unsigned, Tool*>::iterator
95 it = Tools.begin(), ie = Tools.end(); it != ie; ++it)
96 delete it->second;
97}
98
99Tool &Darwin_X86::SelectTool(const Compilation &C,
100 const JobAction &JA) const {
101 Action::ActionClass Key;
Daniel Dunbaraf80e1f2009-03-24 18:57:02 +0000102 if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getArchName()))
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000103 Key = Action::AnalyzeJobClass;
104 else
105 Key = JA.getKind();
106
107 Tool *&T = Tools[Key];
108 if (!T) {
109 switch (Key) {
110 case Action::InputClass:
111 case Action::BindArchClass:
112 assert(0 && "Invalid tool kind.");
113 case Action::PreprocessJobClass:
Daniel Dunbar9120f172009-03-29 22:27:40 +0000114 T = new tools::darwin::Preprocess(*this); break;
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000115 case Action::AnalyzeJobClass:
116 T = new tools::Clang(*this); break;
Daniel Dunbar9120f172009-03-29 22:27:40 +0000117 case Action::PrecompileJobClass:
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000118 case Action::CompileJobClass:
Daniel Dunbar9120f172009-03-29 22:27:40 +0000119 T = new tools::darwin::Compile(*this); break;
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000120 case Action::AssembleJobClass:
Daniel Dunbar8cac5f72009-03-20 16:06:39 +0000121 T = new tools::darwin::Assemble(*this); break;
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000122 case Action::LinkJobClass:
Daniel Dunbar02633b52009-03-26 16:23:12 +0000123 T = new tools::darwin::Link(*this, MacosxVersionMin.c_str()); break;
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000124 case Action::LipoJobClass:
125 T = new tools::darwin::Lipo(*this); break;
126 }
127 }
128
129 return *T;
130}
131
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000132DerivedArgList *Darwin_X86::TranslateArgs(InputArgList &Args) const {
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000133 DerivedArgList *DAL = new DerivedArgList(Args, false);
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000134 const OptTable &Opts = getHost().getDriver().getOpts();
135
136 // FIXME: We really want to get out of the tool chain level argument
137 // translation business, as it makes the driver functionality much
138 // more opaque. For now, we follow gcc closely solely for the
139 // purpose of easily achieving feature parity & testability. Once we
140 // have something that works, we should reevaluate each translation
141 // and try to push it down into tool specific logic.
142
143 if (!Args.hasArg(options::OPT_mmacosx_version_min_EQ, false)) {
144 const Option *O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
Daniel Dunbar478edc22009-03-29 22:29:05 +0000145 DAL->append(DAL->MakeJoinedArg(0, O, MacosxVersionMin.c_str()));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000146 }
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000147
148 for (ArgList::iterator it = Args.begin(), ie = Args.end(); it != ie; ++it) {
149 Arg *A = *it;
150
151 if (A->getOption().matches(options::OPT_Xarch__)) {
152 // FIXME: Canonicalize name.
153 if (getArchName() != A->getValue(Args, 0))
154 continue;
155
156 // FIXME: The arg is leaked here, and we should have a nicer
157 // interface for this.
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000158 unsigned Prev, Index = Prev = A->getIndex() + 1;
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000159 Arg *XarchArg = Opts.ParseOneArg(Args, Index);
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000160
161 // If the argument parsing failed or more than one argument was
162 // consumed, the -Xarch_ argument's parameter tried to consume
163 // extra arguments. Emit an error and ignore.
164 //
165 // We also want to disallow any options which would alter the
166 // driver behavior; that isn't going to work in our model. We
167 // use isDriverOption() as an approximation, although things
168 // like -O4 are going to slip through.
169 if (!XarchArg || Index > Prev + 1 ||
170 XarchArg->getOption().isDriverOption()) {
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000171 getHost().getDriver().Diag(clang::diag::err_drv_invalid_Xarch_argument)
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000172 << A->getAsString(Args);
173 continue;
174 }
175
Daniel Dunbar478edc22009-03-29 22:29:05 +0000176 XarchArg->setBaseArg(A);
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000177 A = XarchArg;
178 }
179
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000180 // Sob. These is strictly gcc compatible for the time being. Apple
181 // gcc translates options twice, which means that self-expanding
182 // options add duplicates.
183 options::ID id = A->getOption().getId();
184 switch (id) {
185 default:
186 DAL->append(A);
187 break;
188
189 case options::OPT_mkernel:
190 case options::OPT_fapple_kext:
191 DAL->append(A);
Daniel Dunbar478edc22009-03-29 22:29:05 +0000192 DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_static)));
193 DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_static)));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000194 break;
195
196 case options::OPT_dependency_file:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000197 DAL->append(DAL->MakeSeparateArg(A, Opts.getOption(options::OPT_MF),
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000198 A->getValue(Args)));
199 break;
200
201 case options::OPT_gfull:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000202 DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_g_Flag)));
203 DAL->append(DAL->MakeFlagArg(A,
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000204 Opts.getOption(options::OPT_fno_eliminate_unused_debug_symbols)));
205 break;
206
207 case options::OPT_gused:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000208 DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_g_Flag)));
209 DAL->append(DAL->MakeFlagArg(A,
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000210 Opts.getOption(options::OPT_feliminate_unused_debug_symbols)));
211 break;
212
213 case options::OPT_fterminated_vtables:
214 case options::OPT_findirect_virtual_calls:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000215 DAL->append(DAL->MakeFlagArg(A,
216 Opts.getOption(options::OPT_fapple_kext)));
217 DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_static)));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000218 break;
219
220 case options::OPT_shared:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000221 DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_dynamiclib)));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000222 break;
223
224 case options::OPT_fconstant_cfstrings:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000225 DAL->append(DAL->MakeFlagArg(A,
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000226 Opts.getOption(options::OPT_mconstant_cfstrings)));
227 break;
228
229 case options::OPT_fno_constant_cfstrings:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000230 DAL->append(DAL->MakeFlagArg(A,
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000231 Opts.getOption(options::OPT_mno_constant_cfstrings)));
232 break;
233
234 case options::OPT_Wnonportable_cfstrings:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000235 DAL->append(DAL->MakeFlagArg(A,
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000236 Opts.getOption(options::OPT_mwarn_nonportable_cfstrings)));
237 break;
238
239 case options::OPT_Wno_nonportable_cfstrings:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000240 DAL->append(DAL->MakeFlagArg(A,
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000241 Opts.getOption(options::OPT_mno_warn_nonportable_cfstrings)));
242 break;
243
244 case options::OPT_fpascal_strings:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000245 DAL->append(DAL->MakeFlagArg(A,
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000246 Opts.getOption(options::OPT_mpascal_strings)));
247 break;
248
249 case options::OPT_fno_pascal_strings:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000250 DAL->append(DAL->MakeFlagArg(A,
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000251 Opts.getOption(options::OPT_mno_pascal_strings)));
252 break;
253 }
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000254 }
255
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000256 // FIXME: Actually, gcc always adds this, but it is filtered for
257 // duplicates somewhere. This also changes the order of things, so
258 // look it up.
259 if (getArchName() == "x86_64")
260 if (!Args.hasArg(options::OPT_m64, false))
Daniel Dunbar478edc22009-03-29 22:29:05 +0000261 DAL->append(DAL->MakeFlagArg(0, Opts.getOption(options::OPT_m64)));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000262
263 if (!Args.hasArg(options::OPT_mtune_EQ, false))
Daniel Dunbar478edc22009-03-29 22:29:05 +0000264 DAL->append(DAL->MakeJoinedArg(0, Opts.getOption(options::OPT_mtune_EQ),
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000265 "core2"));
266
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000267 return DAL;
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000268}
269
270bool Darwin_X86::IsMathErrnoDefault() const {
271 return false;
272}
273
274bool Darwin_X86::IsUnwindTablesDefault() const {
275 // FIXME: Gross; we should probably have some separate target
276 // definition, possibly even reusing the one in clang.
277 return getArchName() == "x86_64";
278}
279
280const char *Darwin_X86::GetDefaultRelocationModel() const {
281 return "pic";
282}
283
284const char *Darwin_X86::GetForcedPicModel() const {
285 if (getArchName() == "x86_64")
286 return "pic";
287 return 0;
288}
289
Daniel Dunbar39176082009-03-20 00:20:03 +0000290/// Generic_GCC - A tool chain using the 'gcc' command to perform
291/// all subcommands; this relies on gcc translating the majority of
292/// command line options.
293
Daniel Dunbarc50b00d2009-03-23 16:15:50 +0000294Generic_GCC::Generic_GCC(const HostInfo &Host, const char *Arch,
295 const char *Platform, const char *OS)
296 : ToolChain(Host, Arch, Platform, OS)
297{
Daniel Dunbar82fa7c52009-03-24 04:07:10 +0000298 std::string Path(getHost().getDriver().Dir);
299 Path += "/../libexec";
300 getProgramPaths().push_back(Path);
301
Daniel Dunbarc50b00d2009-03-23 16:15:50 +0000302 getProgramPaths().push_back(getHost().getDriver().Dir);
303}
304
Daniel Dunbar39176082009-03-20 00:20:03 +0000305Generic_GCC::~Generic_GCC() {
306 // Free tool implementations.
307 for (llvm::DenseMap<unsigned, Tool*>::iterator
308 it = Tools.begin(), ie = Tools.end(); it != ie; ++it)
309 delete it->second;
310}
311
312Tool &Generic_GCC::SelectTool(const Compilation &C,
313 const JobAction &JA) const {
314 Action::ActionClass Key;
Daniel Dunbaraf80e1f2009-03-24 18:57:02 +0000315 if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getArchName()))
Daniel Dunbar39176082009-03-20 00:20:03 +0000316 Key = Action::AnalyzeJobClass;
317 else
318 Key = JA.getKind();
319
320 Tool *&T = Tools[Key];
321 if (!T) {
322 switch (Key) {
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000323 case Action::InputClass:
324 case Action::BindArchClass:
Daniel Dunbar39176082009-03-20 00:20:03 +0000325 assert(0 && "Invalid tool kind.");
326 case Action::PreprocessJobClass:
327 T = new tools::gcc::Preprocess(*this); break;
328 case Action::PrecompileJobClass:
329 T = new tools::gcc::Precompile(*this); break;
330 case Action::AnalyzeJobClass:
331 T = new tools::Clang(*this); break;
332 case Action::CompileJobClass:
333 T = new tools::gcc::Compile(*this); break;
334 case Action::AssembleJobClass:
335 T = new tools::gcc::Assemble(*this); break;
336 case Action::LinkJobClass:
337 T = new tools::gcc::Link(*this); break;
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000338
339 // This is a bit ungeneric, but the only platform using a driver
340 // driver is Darwin.
341 case Action::LipoJobClass:
342 T = new tools::darwin::Lipo(*this); break;
Daniel Dunbar39176082009-03-20 00:20:03 +0000343 }
344 }
345
346 return *T;
347}
348
349bool Generic_GCC::IsMathErrnoDefault() const {
350 return true;
351}
352
353bool Generic_GCC::IsUnwindTablesDefault() const {
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000354 // FIXME: Gross; we should probably have some separate target
355 // definition, possibly even reusing the one in clang.
Daniel Dunbar39176082009-03-20 00:20:03 +0000356 return getArchName() == "x86_64";
357}
358
359const char *Generic_GCC::GetDefaultRelocationModel() const {
360 return "static";
361}
362
363const char *Generic_GCC::GetForcedPicModel() const {
364 return 0;
365}
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000366
367DerivedArgList *Generic_GCC::TranslateArgs(InputArgList &Args) const {
368 return new DerivedArgList(Args, true);
369}
Daniel Dunbar75358d22009-03-30 21:06:03 +0000370
371/// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly.
372
373FreeBSD::FreeBSD(const HostInfo &Host, const char *Arch,
374 const char *Platform, const char *OS, bool Lib32)
375 : Generic_GCC(Host, Arch, Platform, OS) {
376 if (Lib32)
377 getFilePaths().push_back(getHost().getDriver().Dir + "/../lib32");
378 else
379 getFilePaths().push_back(getHost().getDriver().Dir + "/../lib");
380}
381
382Tool &FreeBSD::SelectTool(const Compilation &C, const JobAction &JA) const {
383 Action::ActionClass Key;
384 if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getArchName()))
385 Key = Action::AnalyzeJobClass;
386 else
387 Key = JA.getKind();
388
389 Tool *&T = Tools[Key];
390 if (!T) {
391 switch (Key) {
Daniel Dunbar68a31d42009-03-31 17:45:15 +0000392 case Action::AssembleJobClass:
393 T = new tools::freebsd::Assemble(*this); break;
Daniel Dunbar008f54a2009-04-01 19:36:32 +0000394 case Action::LinkJobClass:
395 T = new tools::freebsd::Link(*this); break;
Daniel Dunbar75358d22009-03-30 21:06:03 +0000396 default:
397 T = &Generic_GCC::SelectTool(C, JA);
398 }
399 }
400
401 return *T;
402}