blob: 87927f8fb65add5bf0fc15083fc2213c3f3476e2 [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 Dunbarf36a06a2009-04-10 21:00:07 +000023#include <cstdlib> // ::getenv
24
Daniel Dunbar39176082009-03-20 00:20:03 +000025using namespace clang::driver;
26using namespace clang::driver::toolchains;
27
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +000028/// Darwin_X86 - Darwin tool chain for i386 and x86_64.
29
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000030Darwin_X86::Darwin_X86(const HostInfo &Host, const char *Arch,
31 const char *Platform, const char *OS,
32 const unsigned (&_DarwinVersion)[3],
33 const unsigned (&_GCCVersion)[3])
34 : ToolChain(Host, Arch, Platform, OS)
35{
36 DarwinVersion[0] = _DarwinVersion[0];
37 DarwinVersion[1] = _DarwinVersion[1];
38 DarwinVersion[2] = _DarwinVersion[2];
39 GCCVersion[0] = _GCCVersion[0];
40 GCCVersion[1] = _GCCVersion[1];
41 GCCVersion[2] = _GCCVersion[2];
42
Daniel Dunbar02633b52009-03-26 16:23:12 +000043 llvm::raw_string_ostream(MacosxVersionMin)
44 << "10." << DarwinVersion[0] - 4 << '.' << DarwinVersion[1];
45
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000046 ToolChainDir = "i686-apple-darwin";
47 ToolChainDir += llvm::utostr(DarwinVersion[0]);
48 ToolChainDir += "/";
49 ToolChainDir += llvm::utostr(GCCVersion[0]);
50 ToolChainDir += '.';
51 ToolChainDir += llvm::utostr(GCCVersion[1]);
52 ToolChainDir += '.';
53 ToolChainDir += llvm::utostr(GCCVersion[2]);
54
55 std::string Path;
56 if (getArchName() == "x86_64") {
57 Path = getHost().getDriver().Dir;
58 Path += "/../lib/gcc/";
59 Path += getToolChainDir();
60 Path += "/x86_64";
61 getFilePaths().push_back(Path);
62
63 Path = "/usr/lib/gcc/";
64 Path += getToolChainDir();
65 Path += "/x86_64";
66 getFilePaths().push_back(Path);
67 }
68
69 Path = getHost().getDriver().Dir;
70 Path += "/../lib/gcc/";
71 Path += getToolChainDir();
72 getFilePaths().push_back(Path);
73
74 Path = "/usr/lib/gcc/";
75 Path += getToolChainDir();
76 getFilePaths().push_back(Path);
77
78 Path = getHost().getDriver().Dir;
79 Path += "/../libexec/gcc/";
80 Path += getToolChainDir();
81 getProgramPaths().push_back(Path);
82
83 Path = "/usr/libexec/gcc/";
84 Path += getToolChainDir();
85 getProgramPaths().push_back(Path);
86
Daniel Dunbar82fa7c52009-03-24 04:07:10 +000087 Path = getHost().getDriver().Dir;
88 Path += "/../libexec";
89 getProgramPaths().push_back(Path);
90
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000091 getProgramPaths().push_back(getHost().getDriver().Dir);
92}
93
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +000094Darwin_X86::~Darwin_X86() {
95 // Free tool implementations.
96 for (llvm::DenseMap<unsigned, Tool*>::iterator
97 it = Tools.begin(), ie = Tools.end(); it != ie; ++it)
98 delete it->second;
99}
100
101Tool &Darwin_X86::SelectTool(const Compilation &C,
102 const JobAction &JA) const {
103 Action::ActionClass Key;
Daniel Dunbaraf80e1f2009-03-24 18:57:02 +0000104 if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getArchName()))
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000105 Key = Action::AnalyzeJobClass;
106 else
107 Key = JA.getKind();
108
109 Tool *&T = Tools[Key];
110 if (!T) {
111 switch (Key) {
112 case Action::InputClass:
113 case Action::BindArchClass:
114 assert(0 && "Invalid tool kind.");
115 case Action::PreprocessJobClass:
Daniel Dunbar9120f172009-03-29 22:27:40 +0000116 T = new tools::darwin::Preprocess(*this); break;
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000117 case Action::AnalyzeJobClass:
118 T = new tools::Clang(*this); break;
Daniel Dunbar9120f172009-03-29 22:27:40 +0000119 case Action::PrecompileJobClass:
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000120 case Action::CompileJobClass:
Daniel Dunbar9120f172009-03-29 22:27:40 +0000121 T = new tools::darwin::Compile(*this); break;
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000122 case Action::AssembleJobClass:
Daniel Dunbar8cac5f72009-03-20 16:06:39 +0000123 T = new tools::darwin::Assemble(*this); break;
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000124 case Action::LinkJobClass:
Daniel Dunbar02633b52009-03-26 16:23:12 +0000125 T = new tools::darwin::Link(*this, MacosxVersionMin.c_str()); break;
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000126 case Action::LipoJobClass:
127 T = new tools::darwin::Lipo(*this); break;
128 }
129 }
130
131 return *T;
132}
133
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000134DerivedArgList *Darwin_X86::TranslateArgs(InputArgList &Args) const {
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000135 DerivedArgList *DAL = new DerivedArgList(Args, false);
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000136 const OptTable &Opts = getHost().getDriver().getOpts();
137
138 // FIXME: We really want to get out of the tool chain level argument
139 // translation business, as it makes the driver functionality much
140 // more opaque. For now, we follow gcc closely solely for the
141 // purpose of easily achieving feature parity & testability. Once we
142 // have something that works, we should reevaluate each translation
143 // and try to push it down into tool specific logic.
144
Daniel Dunbarff8857a2009-04-10 20:11:50 +0000145 Arg *OSXVersion =
146 Args.getLastArg(options::OPT_mmacosx_version_min_EQ, false);
147 Arg *iPhoneVersion =
148 Args.getLastArg(options::OPT_miphoneos_version_min_EQ, false);
149 if (OSXVersion && iPhoneVersion) {
150 getHost().getDriver().Diag(clang::diag::err_drv_argument_not_allowed_with)
151 << OSXVersion->getAsString(Args)
152 << iPhoneVersion->getAsString(Args);
153 } else if (!OSXVersion && !iPhoneVersion) {
154 // Chose the default version based on the arch.
155 //
156 // FIXME: This will need to be fixed when we merge in arm support.
Daniel Dunbarf36a06a2009-04-10 21:00:07 +0000157
158 // Look for MACOSX_DEPLOYMENT_TARGET, otherwise use the version
159 // from the host.
160 const char *Version = ::getenv("MACOSX_DEPLOYMENT_TARGET");
161 if (!Version)
162 Version = MacosxVersionMin.c_str();
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000163 const Option *O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
Daniel Dunbarf36a06a2009-04-10 21:00:07 +0000164 DAL->append(DAL->MakeJoinedArg(0, O, Version));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000165 }
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000166
167 for (ArgList::iterator it = Args.begin(), ie = Args.end(); it != ie; ++it) {
168 Arg *A = *it;
169
170 if (A->getOption().matches(options::OPT_Xarch__)) {
171 // FIXME: Canonicalize name.
172 if (getArchName() != A->getValue(Args, 0))
173 continue;
174
175 // FIXME: The arg is leaked here, and we should have a nicer
176 // interface for this.
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000177 unsigned Prev, Index = Prev = A->getIndex() + 1;
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000178 Arg *XarchArg = Opts.ParseOneArg(Args, Index);
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000179
180 // If the argument parsing failed or more than one argument was
181 // consumed, the -Xarch_ argument's parameter tried to consume
182 // extra arguments. Emit an error and ignore.
183 //
184 // We also want to disallow any options which would alter the
185 // driver behavior; that isn't going to work in our model. We
186 // use isDriverOption() as an approximation, although things
187 // like -O4 are going to slip through.
188 if (!XarchArg || Index > Prev + 1 ||
189 XarchArg->getOption().isDriverOption()) {
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000190 getHost().getDriver().Diag(clang::diag::err_drv_invalid_Xarch_argument)
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000191 << A->getAsString(Args);
192 continue;
193 }
194
Daniel Dunbar478edc22009-03-29 22:29:05 +0000195 XarchArg->setBaseArg(A);
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000196 A = XarchArg;
197 }
198
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000199 // Sob. These is strictly gcc compatible for the time being. Apple
200 // gcc translates options twice, which means that self-expanding
201 // options add duplicates.
202 options::ID id = A->getOption().getId();
203 switch (id) {
204 default:
205 DAL->append(A);
206 break;
207
208 case options::OPT_mkernel:
209 case options::OPT_fapple_kext:
210 DAL->append(A);
Daniel Dunbar478edc22009-03-29 22:29:05 +0000211 DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_static)));
212 DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_static)));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000213 break;
214
215 case options::OPT_dependency_file:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000216 DAL->append(DAL->MakeSeparateArg(A, Opts.getOption(options::OPT_MF),
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000217 A->getValue(Args)));
218 break;
219
220 case options::OPT_gfull:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000221 DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_g_Flag)));
222 DAL->append(DAL->MakeFlagArg(A,
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000223 Opts.getOption(options::OPT_fno_eliminate_unused_debug_symbols)));
224 break;
225
226 case options::OPT_gused:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000227 DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_g_Flag)));
228 DAL->append(DAL->MakeFlagArg(A,
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000229 Opts.getOption(options::OPT_feliminate_unused_debug_symbols)));
230 break;
231
232 case options::OPT_fterminated_vtables:
233 case options::OPT_findirect_virtual_calls:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000234 DAL->append(DAL->MakeFlagArg(A,
235 Opts.getOption(options::OPT_fapple_kext)));
236 DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_static)));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000237 break;
238
239 case options::OPT_shared:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000240 DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_dynamiclib)));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000241 break;
242
243 case options::OPT_fconstant_cfstrings:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000244 DAL->append(DAL->MakeFlagArg(A,
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000245 Opts.getOption(options::OPT_mconstant_cfstrings)));
246 break;
247
248 case options::OPT_fno_constant_cfstrings:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000249 DAL->append(DAL->MakeFlagArg(A,
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000250 Opts.getOption(options::OPT_mno_constant_cfstrings)));
251 break;
252
253 case options::OPT_Wnonportable_cfstrings:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000254 DAL->append(DAL->MakeFlagArg(A,
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000255 Opts.getOption(options::OPT_mwarn_nonportable_cfstrings)));
256 break;
257
258 case options::OPT_Wno_nonportable_cfstrings:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000259 DAL->append(DAL->MakeFlagArg(A,
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000260 Opts.getOption(options::OPT_mno_warn_nonportable_cfstrings)));
261 break;
262
263 case options::OPT_fpascal_strings:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000264 DAL->append(DAL->MakeFlagArg(A,
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000265 Opts.getOption(options::OPT_mpascal_strings)));
266 break;
267
268 case options::OPT_fno_pascal_strings:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000269 DAL->append(DAL->MakeFlagArg(A,
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000270 Opts.getOption(options::OPT_mno_pascal_strings)));
271 break;
272 }
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000273 }
274
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000275 // FIXME: Actually, gcc always adds this, but it is filtered for
276 // duplicates somewhere. This also changes the order of things, so
277 // look it up.
278 if (getArchName() == "x86_64")
279 if (!Args.hasArg(options::OPT_m64, false))
Daniel Dunbar478edc22009-03-29 22:29:05 +0000280 DAL->append(DAL->MakeFlagArg(0, Opts.getOption(options::OPT_m64)));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000281
282 if (!Args.hasArg(options::OPT_mtune_EQ, false))
Daniel Dunbar478edc22009-03-29 22:29:05 +0000283 DAL->append(DAL->MakeJoinedArg(0, Opts.getOption(options::OPT_mtune_EQ),
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000284 "core2"));
285
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000286 return DAL;
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000287}
288
289bool Darwin_X86::IsMathErrnoDefault() const {
290 return false;
291}
292
293bool Darwin_X86::IsUnwindTablesDefault() const {
294 // FIXME: Gross; we should probably have some separate target
295 // definition, possibly even reusing the one in clang.
296 return getArchName() == "x86_64";
297}
298
299const char *Darwin_X86::GetDefaultRelocationModel() const {
300 return "pic";
301}
302
303const char *Darwin_X86::GetForcedPicModel() const {
304 if (getArchName() == "x86_64")
305 return "pic";
306 return 0;
307}
308
Daniel Dunbar39176082009-03-20 00:20:03 +0000309/// Generic_GCC - A tool chain using the 'gcc' command to perform
310/// all subcommands; this relies on gcc translating the majority of
311/// command line options.
312
Daniel Dunbarc50b00d2009-03-23 16:15:50 +0000313Generic_GCC::Generic_GCC(const HostInfo &Host, const char *Arch,
314 const char *Platform, const char *OS)
315 : ToolChain(Host, Arch, Platform, OS)
316{
Daniel Dunbar82fa7c52009-03-24 04:07:10 +0000317 std::string Path(getHost().getDriver().Dir);
318 Path += "/../libexec";
319 getProgramPaths().push_back(Path);
320
Daniel Dunbarc50b00d2009-03-23 16:15:50 +0000321 getProgramPaths().push_back(getHost().getDriver().Dir);
322}
323
Daniel Dunbar39176082009-03-20 00:20:03 +0000324Generic_GCC::~Generic_GCC() {
325 // Free tool implementations.
326 for (llvm::DenseMap<unsigned, Tool*>::iterator
327 it = Tools.begin(), ie = Tools.end(); it != ie; ++it)
328 delete it->second;
329}
330
331Tool &Generic_GCC::SelectTool(const Compilation &C,
332 const JobAction &JA) const {
333 Action::ActionClass Key;
Daniel Dunbaraf80e1f2009-03-24 18:57:02 +0000334 if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getArchName()))
Daniel Dunbar39176082009-03-20 00:20:03 +0000335 Key = Action::AnalyzeJobClass;
336 else
337 Key = JA.getKind();
338
339 Tool *&T = Tools[Key];
340 if (!T) {
341 switch (Key) {
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000342 case Action::InputClass:
343 case Action::BindArchClass:
Daniel Dunbar39176082009-03-20 00:20:03 +0000344 assert(0 && "Invalid tool kind.");
345 case Action::PreprocessJobClass:
346 T = new tools::gcc::Preprocess(*this); break;
347 case Action::PrecompileJobClass:
348 T = new tools::gcc::Precompile(*this); break;
349 case Action::AnalyzeJobClass:
350 T = new tools::Clang(*this); break;
351 case Action::CompileJobClass:
352 T = new tools::gcc::Compile(*this); break;
353 case Action::AssembleJobClass:
354 T = new tools::gcc::Assemble(*this); break;
355 case Action::LinkJobClass:
356 T = new tools::gcc::Link(*this); break;
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000357
358 // This is a bit ungeneric, but the only platform using a driver
359 // driver is Darwin.
360 case Action::LipoJobClass:
361 T = new tools::darwin::Lipo(*this); break;
Daniel Dunbar39176082009-03-20 00:20:03 +0000362 }
363 }
364
365 return *T;
366}
367
368bool Generic_GCC::IsMathErrnoDefault() const {
369 return true;
370}
371
372bool Generic_GCC::IsUnwindTablesDefault() const {
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000373 // FIXME: Gross; we should probably have some separate target
374 // definition, possibly even reusing the one in clang.
Daniel Dunbar39176082009-03-20 00:20:03 +0000375 return getArchName() == "x86_64";
376}
377
378const char *Generic_GCC::GetDefaultRelocationModel() const {
379 return "static";
380}
381
382const char *Generic_GCC::GetForcedPicModel() const {
383 return 0;
384}
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000385
386DerivedArgList *Generic_GCC::TranslateArgs(InputArgList &Args) const {
387 return new DerivedArgList(Args, true);
388}
Daniel Dunbar75358d22009-03-30 21:06:03 +0000389
390/// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly.
391
392FreeBSD::FreeBSD(const HostInfo &Host, const char *Arch,
393 const char *Platform, const char *OS, bool Lib32)
394 : Generic_GCC(Host, Arch, Platform, OS) {
Daniel Dunbarbc534662009-04-02 18:30:04 +0000395 if (Lib32) {
Daniel Dunbar75358d22009-03-30 21:06:03 +0000396 getFilePaths().push_back(getHost().getDriver().Dir + "/../lib32");
Daniel Dunbarbc534662009-04-02 18:30:04 +0000397 getFilePaths().push_back("/usr/lib32");
398 } else {
Daniel Dunbar75358d22009-03-30 21:06:03 +0000399 getFilePaths().push_back(getHost().getDriver().Dir + "/../lib");
Daniel Dunbarbc534662009-04-02 18:30:04 +0000400 getFilePaths().push_back("/usr/lib");
401 }
Daniel Dunbar75358d22009-03-30 21:06:03 +0000402}
403
404Tool &FreeBSD::SelectTool(const Compilation &C, const JobAction &JA) const {
405 Action::ActionClass Key;
406 if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getArchName()))
407 Key = Action::AnalyzeJobClass;
408 else
409 Key = JA.getKind();
410
411 Tool *&T = Tools[Key];
412 if (!T) {
413 switch (Key) {
Daniel Dunbar68a31d42009-03-31 17:45:15 +0000414 case Action::AssembleJobClass:
415 T = new tools::freebsd::Assemble(*this); break;
Daniel Dunbar008f54a2009-04-01 19:36:32 +0000416 case Action::LinkJobClass:
417 T = new tools::freebsd::Link(*this); break;
Daniel Dunbar75358d22009-03-30 21:06:03 +0000418 default:
419 T = &Generic_GCC::SelectTool(C, JA);
420 }
421 }
422
423 return *T;
424}