blob: ce4fc1eea3d93597566910d3406319f8f349c95d [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 Dunbar84ec96c2009-09-09 22:33:15 +000020#include "llvm/Support/ErrorHandling.h"
Daniel Dunbarec069ed2009-03-25 06:58:31 +000021#include "llvm/Support/raw_ostream.h"
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000022#include "llvm/System/Path.h"
23
Daniel Dunbarf36a06a2009-04-10 21:00:07 +000024#include <cstdlib> // ::getenv
25
Daniel Dunbar39176082009-03-20 00:20:03 +000026using namespace clang::driver;
27using namespace clang::driver::toolchains;
28
Daniel Dunbarf3955282009-09-04 18:34:51 +000029/// Darwin - Darwin tool chain for i386 and x86_64.
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +000030
Daniel Dunbarf3955282009-09-04 18:34:51 +000031Darwin::Darwin(const HostInfo &Host, const llvm::Triple& Triple,
32 const unsigned (&_DarwinVersion)[3],
Daniel Dunbar30392de2009-09-04 18:35:21 +000033 const unsigned (&_GCCVersion)[3],
34 bool _IsIPhone)
Daniel Dunbarcb8ab232009-05-22 02:53:45 +000035 : ToolChain(Host, Triple) {
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000036 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];
Daniel Dunbar30392de2009-09-04 18:35:21 +000042 IsIPhone = _IsIPhone;
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000043
Daniel Dunbar02633b52009-03-26 16:23:12 +000044 llvm::raw_string_ostream(MacosxVersionMin)
45 << "10." << DarwinVersion[0] - 4 << '.' << DarwinVersion[1];
46
Daniel Dunbar30392de2009-09-04 18:35:21 +000047 // FIXME: Lift default up.
48 IPhoneOSVersionMin = "3.0";
49
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000050 ToolChainDir = "i686-apple-darwin";
51 ToolChainDir += llvm::utostr(DarwinVersion[0]);
52 ToolChainDir += "/";
53 ToolChainDir += llvm::utostr(GCCVersion[0]);
54 ToolChainDir += '.';
55 ToolChainDir += llvm::utostr(GCCVersion[1]);
56 ToolChainDir += '.';
57 ToolChainDir += llvm::utostr(GCCVersion[2]);
58
59 std::string Path;
60 if (getArchName() == "x86_64") {
61 Path = getHost().getDriver().Dir;
62 Path += "/../lib/gcc/";
Daniel Dunbar6b200b22009-09-18 08:14:36 +000063 Path += ToolChainDir;
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000064 Path += "/x86_64";
65 getFilePaths().push_back(Path);
66
67 Path = "/usr/lib/gcc/";
Daniel Dunbar6b200b22009-09-18 08:14:36 +000068 Path += ToolChainDir;
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000069 Path += "/x86_64";
70 getFilePaths().push_back(Path);
71 }
Mike Stump1eb44332009-09-09 15:08:12 +000072
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000073 Path = getHost().getDriver().Dir;
74 Path += "/../lib/gcc/";
Daniel Dunbar6b200b22009-09-18 08:14:36 +000075 Path += ToolChainDir;
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000076 getFilePaths().push_back(Path);
77
78 Path = "/usr/lib/gcc/";
Daniel Dunbar6b200b22009-09-18 08:14:36 +000079 Path += ToolChainDir;
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000080 getFilePaths().push_back(Path);
81
82 Path = getHost().getDriver().Dir;
83 Path += "/../libexec/gcc/";
Daniel Dunbar6b200b22009-09-18 08:14:36 +000084 Path += ToolChainDir;
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000085 getProgramPaths().push_back(Path);
86
87 Path = "/usr/libexec/gcc/";
Daniel Dunbar6b200b22009-09-18 08:14:36 +000088 Path += ToolChainDir;
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000089 getProgramPaths().push_back(Path);
90
Daniel Dunbar82fa7c52009-03-24 04:07:10 +000091 Path = getHost().getDriver().Dir;
92 Path += "/../libexec";
93 getProgramPaths().push_back(Path);
94
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000095 getProgramPaths().push_back(getHost().getDriver().Dir);
96}
97
Daniel Dunbarf3955282009-09-04 18:34:51 +000098Darwin::~Darwin() {
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +000099 // Free tool implementations.
100 for (llvm::DenseMap<unsigned, Tool*>::iterator
101 it = Tools.begin(), ie = Tools.end(); it != ie; ++it)
102 delete it->second;
103}
104
Daniel Dunbarf3955282009-09-04 18:34:51 +0000105Tool &Darwin::SelectTool(const Compilation &C, const JobAction &JA) const {
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000106 Action::ActionClass Key;
Daniel Dunbara6046be2009-09-08 23:36:55 +0000107 if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000108 Key = Action::AnalyzeJobClass;
109 else
110 Key = JA.getKind();
111
112 Tool *&T = Tools[Key];
113 if (!T) {
114 switch (Key) {
115 case Action::InputClass:
116 case Action::BindArchClass:
117 assert(0 && "Invalid tool kind.");
118 case Action::PreprocessJobClass:
Daniel Dunbar9120f172009-03-29 22:27:40 +0000119 T = new tools::darwin::Preprocess(*this); break;
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000120 case Action::AnalyzeJobClass:
121 T = new tools::Clang(*this); break;
Daniel Dunbar9120f172009-03-29 22:27:40 +0000122 case Action::PrecompileJobClass:
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000123 case Action::CompileJobClass:
Daniel Dunbar9120f172009-03-29 22:27:40 +0000124 T = new tools::darwin::Compile(*this); break;
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000125 case Action::AssembleJobClass:
Daniel Dunbar8cac5f72009-03-20 16:06:39 +0000126 T = new tools::darwin::Assemble(*this); break;
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000127 case Action::LinkJobClass:
Daniel Dunbar8f289622009-09-04 17:39:02 +0000128 T = new tools::darwin::Link(*this); break;
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000129 case Action::LipoJobClass:
130 T = new tools::darwin::Lipo(*this); break;
131 }
132 }
133
134 return *T;
135}
136
Daniel Dunbar6b200b22009-09-18 08:14:36 +0000137void Darwin::AddLinkSearchPathArgs(const ArgList &Args,
138 ArgStringList &CmdArgs) const {
139 // FIXME: Derive these correctly.
140 if (getArchName() == "x86_64") {
141 CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir +
142 "/x86_64"));
143 // Intentionally duplicated for (temporary) gcc bug compatibility.
144 CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir +
145 "/x86_64"));
146 }
147 CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/" + ToolChainDir));
148 CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir));
149 // Intentionally duplicated for (temporary) gcc bug compatibility.
150 CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir));
151 CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir +
152 "/../../../" + ToolChainDir));
153 CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir +
154 "/../../.."));
155}
156
Daniel Dunbar48d5aae2009-09-18 08:14:46 +0000157void Darwin::getMacosxVersionMin(const ArgList &Args,
158 unsigned (&Res)[3]) const {
159 if (Arg *A = Args.getLastArg(options::OPT_mmacosx_version_min_EQ)) {
160 bool HadExtra;
161 if (!Driver::GetReleaseVersion(A->getValue(Args), Res[0], Res[1], Res[2],
162 HadExtra) ||
163 HadExtra) {
164 const Driver &D = getHost().getDriver();
165 D.Diag(clang::diag::err_drv_invalid_version_number)
166 << A->getAsString(Args);
167 }
168 } else
169 return getMacosxVersion(Res);
170}
171
Daniel Dunbar0dcb9a32009-09-09 18:36:12 +0000172DerivedArgList *Darwin::TranslateArgs(InputArgList &Args,
173 const char *BoundArch) const {
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000174 DerivedArgList *DAL = new DerivedArgList(Args, false);
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000175 const OptTable &Opts = getHost().getDriver().getOpts();
176
177 // FIXME: We really want to get out of the tool chain level argument
178 // translation business, as it makes the driver functionality much
179 // more opaque. For now, we follow gcc closely solely for the
180 // purpose of easily achieving feature parity & testability. Once we
181 // have something that works, we should reevaluate each translation
Mike Stump1eb44332009-09-09 15:08:12 +0000182 // and try to push it down into tool specific logic.
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000183
Mike Stump1eb44332009-09-09 15:08:12 +0000184 Arg *OSXVersion =
Daniel Dunbarff8857a2009-04-10 20:11:50 +0000185 Args.getLastArg(options::OPT_mmacosx_version_min_EQ, false);
186 Arg *iPhoneVersion =
Mike Stump1eb44332009-09-09 15:08:12 +0000187 Args.getLastArg(options::OPT_miphoneos_version_min_EQ, false);
Daniel Dunbarff8857a2009-04-10 20:11:50 +0000188 if (OSXVersion && iPhoneVersion) {
189 getHost().getDriver().Diag(clang::diag::err_drv_argument_not_allowed_with)
190 << OSXVersion->getAsString(Args)
Mike Stump1eb44332009-09-09 15:08:12 +0000191 << iPhoneVersion->getAsString(Args);
Daniel Dunbarff8857a2009-04-10 20:11:50 +0000192 } else if (!OSXVersion && !iPhoneVersion) {
193 // Chose the default version based on the arch.
194 //
Daniel Dunbar30392de2009-09-04 18:35:21 +0000195 // FIXME: Are there iPhone overrides for this?
Daniel Dunbarf36a06a2009-04-10 21:00:07 +0000196
Daniel Dunbar30392de2009-09-04 18:35:21 +0000197 if (!isIPhone()) {
198 // Look for MACOSX_DEPLOYMENT_TARGET, otherwise use the version
199 // from the host.
200 const char *Version = ::getenv("MACOSX_DEPLOYMENT_TARGET");
201 if (!Version)
202 Version = MacosxVersionMin.c_str();
203 const Option *O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
204 DAL->append(DAL->MakeJoinedArg(0, O, Version));
205 } else {
206 const char *Version = IPhoneOSVersionMin.c_str();
207 const Option *O = Opts.getOption(options::OPT_miphoneos_version_min_EQ);
208 DAL->append(DAL->MakeJoinedArg(0, O, Version));
209 }
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000210 }
Mike Stump1eb44332009-09-09 15:08:12 +0000211
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000212 for (ArgList::iterator it = Args.begin(), ie = Args.end(); it != ie; ++it) {
213 Arg *A = *it;
214
215 if (A->getOption().matches(options::OPT_Xarch__)) {
216 // FIXME: Canonicalize name.
217 if (getArchName() != A->getValue(Args, 0))
218 continue;
219
220 // FIXME: The arg is leaked here, and we should have a nicer
221 // interface for this.
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000222 unsigned Prev, Index = Prev = A->getIndex() + 1;
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000223 Arg *XarchArg = Opts.ParseOneArg(Args, Index);
Mike Stump1eb44332009-09-09 15:08:12 +0000224
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000225 // If the argument parsing failed or more than one argument was
226 // consumed, the -Xarch_ argument's parameter tried to consume
227 // extra arguments. Emit an error and ignore.
228 //
229 // We also want to disallow any options which would alter the
230 // driver behavior; that isn't going to work in our model. We
231 // use isDriverOption() as an approximation, although things
232 // like -O4 are going to slip through.
Mike Stump1eb44332009-09-09 15:08:12 +0000233 if (!XarchArg || Index > Prev + 1 ||
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000234 XarchArg->getOption().isDriverOption()) {
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000235 getHost().getDriver().Diag(clang::diag::err_drv_invalid_Xarch_argument)
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000236 << A->getAsString(Args);
237 continue;
238 }
239
Daniel Dunbar478edc22009-03-29 22:29:05 +0000240 XarchArg->setBaseArg(A);
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000241 A = XarchArg;
Mike Stump1eb44332009-09-09 15:08:12 +0000242 }
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000243
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000244 // Sob. These is strictly gcc compatible for the time being. Apple
245 // gcc translates options twice, which means that self-expanding
246 // options add duplicates.
247 options::ID id = A->getOption().getId();
248 switch (id) {
249 default:
250 DAL->append(A);
251 break;
252
253 case options::OPT_mkernel:
254 case options::OPT_fapple_kext:
255 DAL->append(A);
Daniel Dunbar478edc22009-03-29 22:29:05 +0000256 DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_static)));
257 DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_static)));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000258 break;
Mike Stump1eb44332009-09-09 15:08:12 +0000259
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000260 case options::OPT_dependency_file:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000261 DAL->append(DAL->MakeSeparateArg(A, Opts.getOption(options::OPT_MF),
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000262 A->getValue(Args)));
263 break;
264
265 case options::OPT_gfull:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000266 DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_g_Flag)));
267 DAL->append(DAL->MakeFlagArg(A,
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000268 Opts.getOption(options::OPT_fno_eliminate_unused_debug_symbols)));
269 break;
270
271 case options::OPT_gused:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000272 DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_g_Flag)));
273 DAL->append(DAL->MakeFlagArg(A,
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000274 Opts.getOption(options::OPT_feliminate_unused_debug_symbols)));
275 break;
276
277 case options::OPT_fterminated_vtables:
278 case options::OPT_findirect_virtual_calls:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000279 DAL->append(DAL->MakeFlagArg(A,
280 Opts.getOption(options::OPT_fapple_kext)));
281 DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_static)));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000282 break;
283
284 case options::OPT_shared:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000285 DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_dynamiclib)));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000286 break;
287
288 case options::OPT_fconstant_cfstrings:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000289 DAL->append(DAL->MakeFlagArg(A,
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000290 Opts.getOption(options::OPT_mconstant_cfstrings)));
291 break;
292
293 case options::OPT_fno_constant_cfstrings:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000294 DAL->append(DAL->MakeFlagArg(A,
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000295 Opts.getOption(options::OPT_mno_constant_cfstrings)));
296 break;
297
298 case options::OPT_Wnonportable_cfstrings:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000299 DAL->append(DAL->MakeFlagArg(A,
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000300 Opts.getOption(options::OPT_mwarn_nonportable_cfstrings)));
301 break;
302
303 case options::OPT_Wno_nonportable_cfstrings:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000304 DAL->append(DAL->MakeFlagArg(A,
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000305 Opts.getOption(options::OPT_mno_warn_nonportable_cfstrings)));
306 break;
307
308 case options::OPT_fpascal_strings:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000309 DAL->append(DAL->MakeFlagArg(A,
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000310 Opts.getOption(options::OPT_mpascal_strings)));
311 break;
312
313 case options::OPT_fno_pascal_strings:
Daniel Dunbar478edc22009-03-29 22:29:05 +0000314 DAL->append(DAL->MakeFlagArg(A,
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000315 Opts.getOption(options::OPT_mno_pascal_strings)));
316 break;
317 }
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000318 }
319
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000320 if (getTriple().getArch() == llvm::Triple::x86 ||
321 getTriple().getArch() == llvm::Triple::x86_64)
322 if (!Args.hasArg(options::OPT_mtune_EQ, false))
323 DAL->append(DAL->MakeJoinedArg(0, Opts.getOption(options::OPT_mtune_EQ),
324 "core2"));
325
326 // Add the arch options based on the particular spelling of -arch, to match
327 // how the driver driver works.
328 if (BoundArch) {
329 llvm::StringRef Name = BoundArch;
330 const Option *MCpu = Opts.getOption(options::OPT_mcpu_EQ);
331 const Option *MArch = Opts.getOption(options::OPT_march_EQ);
332
333 // This code must be kept in sync with LLVM's getArchTypeForDarwinArch,
334 // which defines the list of which architectures we accept.
335 if (Name == "ppc")
336 ;
337 else if (Name == "ppc601")
338 DAL->append(DAL->MakeJoinedArg(0, MCpu, "601"));
339 else if (Name == "ppc603")
340 DAL->append(DAL->MakeJoinedArg(0, MCpu, "603"));
341 else if (Name == "ppc604")
342 DAL->append(DAL->MakeJoinedArg(0, MCpu, "604"));
343 else if (Name == "ppc604e")
344 DAL->append(DAL->MakeJoinedArg(0, MCpu, "604e"));
345 else if (Name == "ppc750")
346 DAL->append(DAL->MakeJoinedArg(0, MCpu, "750"));
347 else if (Name == "ppc7400")
348 DAL->append(DAL->MakeJoinedArg(0, MCpu, "7400"));
349 else if (Name == "ppc7450")
350 DAL->append(DAL->MakeJoinedArg(0, MCpu, "7450"));
351 else if (Name == "ppc970")
352 DAL->append(DAL->MakeJoinedArg(0, MCpu, "970"));
353
354 else if (Name == "ppc64")
Daniel Dunbar478edc22009-03-29 22:29:05 +0000355 DAL->append(DAL->MakeFlagArg(0, Opts.getOption(options::OPT_m64)));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000356
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000357 else if (Name == "i386")
358 ;
359 else if (Name == "i486")
360 DAL->append(DAL->MakeJoinedArg(0, MArch, "i486"));
361 else if (Name == "i586")
362 DAL->append(DAL->MakeJoinedArg(0, MArch, "i586"));
363 else if (Name == "i686")
364 DAL->append(DAL->MakeJoinedArg(0, MArch, "i686"));
365 else if (Name == "pentium")
366 DAL->append(DAL->MakeJoinedArg(0, MArch, "pentium"));
367 else if (Name == "pentium2")
368 DAL->append(DAL->MakeJoinedArg(0, MArch, "pentium2"));
369 else if (Name == "pentpro")
370 DAL->append(DAL->MakeJoinedArg(0, MArch, "pentiumpro"));
371 else if (Name == "pentIIm3")
372 DAL->append(DAL->MakeJoinedArg(0, MArch, "pentium2"));
373
374 else if (Name == "x86_64")
375 DAL->append(DAL->MakeFlagArg(0, Opts.getOption(options::OPT_m64)));
376
377 else if (Name == "arm")
378 DAL->append(DAL->MakeJoinedArg(0, MArch, "armv4t"));
379 else if (Name == "armv4t")
380 DAL->append(DAL->MakeJoinedArg(0, MArch, "armv4t"));
381 else if (Name == "armv5")
382 DAL->append(DAL->MakeJoinedArg(0, MArch, "armv5tej"));
383 else if (Name == "xscale")
384 DAL->append(DAL->MakeJoinedArg(0, MArch, "xscale"));
385 else if (Name == "armv6")
386 DAL->append(DAL->MakeJoinedArg(0, MArch, "armv6k"));
387 else if (Name == "armv7")
388 DAL->append(DAL->MakeJoinedArg(0, MArch, "armv7a"));
389
390 else
391 llvm::llvm_unreachable("invalid Darwin arch");
392 }
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000393
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000394 return DAL;
Mike Stump1eb44332009-09-09 15:08:12 +0000395}
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000396
Daniel Dunbarf3955282009-09-04 18:34:51 +0000397bool Darwin::IsMathErrnoDefault() const {
Mike Stump1eb44332009-09-09 15:08:12 +0000398 return false;
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000399}
400
Daniel Dunbarf3955282009-09-04 18:34:51 +0000401bool Darwin::IsUnwindTablesDefault() const {
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000402 // FIXME: Gross; we should probably have some separate target
403 // definition, possibly even reusing the one in clang.
404 return getArchName() == "x86_64";
405}
406
Daniel Dunbarf3955282009-09-04 18:34:51 +0000407const char *Darwin::GetDefaultRelocationModel() const {
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000408 return "pic";
409}
410
Daniel Dunbarf3955282009-09-04 18:34:51 +0000411const char *Darwin::GetForcedPicModel() const {
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000412 if (getArchName() == "x86_64")
413 return "pic";
414 return 0;
415}
416
Daniel Dunbar39176082009-03-20 00:20:03 +0000417/// Generic_GCC - A tool chain using the 'gcc' command to perform
418/// all subcommands; this relies on gcc translating the majority of
419/// command line options.
420
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000421Generic_GCC::Generic_GCC(const HostInfo &Host, const llvm::Triple& Triple)
Mike Stump1eb44332009-09-09 15:08:12 +0000422 : ToolChain(Host, Triple) {
Daniel Dunbar82fa7c52009-03-24 04:07:10 +0000423 std::string Path(getHost().getDriver().Dir);
424 Path += "/../libexec";
425 getProgramPaths().push_back(Path);
426
Mike Stump1eb44332009-09-09 15:08:12 +0000427 getProgramPaths().push_back(getHost().getDriver().Dir);
Daniel Dunbarc50b00d2009-03-23 16:15:50 +0000428}
429
Daniel Dunbar39176082009-03-20 00:20:03 +0000430Generic_GCC::~Generic_GCC() {
431 // Free tool implementations.
432 for (llvm::DenseMap<unsigned, Tool*>::iterator
433 it = Tools.begin(), ie = Tools.end(); it != ie; ++it)
434 delete it->second;
435}
436
Mike Stump1eb44332009-09-09 15:08:12 +0000437Tool &Generic_GCC::SelectTool(const Compilation &C,
Daniel Dunbar39176082009-03-20 00:20:03 +0000438 const JobAction &JA) const {
439 Action::ActionClass Key;
Daniel Dunbara6046be2009-09-08 23:36:55 +0000440 if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
Daniel Dunbar39176082009-03-20 00:20:03 +0000441 Key = Action::AnalyzeJobClass;
442 else
443 Key = JA.getKind();
444
445 Tool *&T = Tools[Key];
446 if (!T) {
447 switch (Key) {
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000448 case Action::InputClass:
449 case Action::BindArchClass:
Daniel Dunbar39176082009-03-20 00:20:03 +0000450 assert(0 && "Invalid tool kind.");
451 case Action::PreprocessJobClass:
452 T = new tools::gcc::Preprocess(*this); break;
453 case Action::PrecompileJobClass:
454 T = new tools::gcc::Precompile(*this); break;
455 case Action::AnalyzeJobClass:
456 T = new tools::Clang(*this); break;
457 case Action::CompileJobClass:
458 T = new tools::gcc::Compile(*this); break;
459 case Action::AssembleJobClass:
460 T = new tools::gcc::Assemble(*this); break;
461 case Action::LinkJobClass:
462 T = new tools::gcc::Link(*this); break;
Mike Stump1eb44332009-09-09 15:08:12 +0000463
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000464 // This is a bit ungeneric, but the only platform using a driver
465 // driver is Darwin.
466 case Action::LipoJobClass:
467 T = new tools::darwin::Lipo(*this); break;
Daniel Dunbar39176082009-03-20 00:20:03 +0000468 }
469 }
470
471 return *T;
472}
473
Daniel Dunbarf3955282009-09-04 18:34:51 +0000474bool Generic_GCC::IsMathErrnoDefault() const {
Mike Stump1eb44332009-09-09 15:08:12 +0000475 return true;
Daniel Dunbar39176082009-03-20 00:20:03 +0000476}
477
478bool Generic_GCC::IsUnwindTablesDefault() const {
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000479 // FIXME: Gross; we should probably have some separate target
480 // definition, possibly even reusing the one in clang.
Daniel Dunbar39176082009-03-20 00:20:03 +0000481 return getArchName() == "x86_64";
482}
483
484const char *Generic_GCC::GetDefaultRelocationModel() const {
485 return "static";
486}
487
488const char *Generic_GCC::GetForcedPicModel() const {
489 return 0;
490}
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000491
Daniel Dunbar0dcb9a32009-09-09 18:36:12 +0000492DerivedArgList *Generic_GCC::TranslateArgs(InputArgList &Args,
493 const char *BoundArch) const {
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000494 return new DerivedArgList(Args, true);
495}
Daniel Dunbar75358d22009-03-30 21:06:03 +0000496
Daniel Dunbarf7b8eec2009-06-29 20:52:51 +0000497/// OpenBSD - OpenBSD tool chain which can call as(1) and ld(1) directly.
498
499OpenBSD::OpenBSD(const HostInfo &Host, const llvm::Triple& Triple)
500 : Generic_GCC(Host, Triple) {
501 getFilePaths().push_back(getHost().getDriver().Dir + "/../lib");
502 getFilePaths().push_back("/usr/lib");
503}
504
505Tool &OpenBSD::SelectTool(const Compilation &C, const JobAction &JA) const {
506 Action::ActionClass Key;
Daniel Dunbara6046be2009-09-08 23:36:55 +0000507 if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
Daniel Dunbarf7b8eec2009-06-29 20:52:51 +0000508 Key = Action::AnalyzeJobClass;
509 else
510 Key = JA.getKind();
511
512 Tool *&T = Tools[Key];
513 if (!T) {
514 switch (Key) {
515 case Action::AssembleJobClass:
516 T = new tools::openbsd::Assemble(*this); break;
517 case Action::LinkJobClass:
518 T = new tools::openbsd::Link(*this); break;
519 default:
520 T = &Generic_GCC::SelectTool(C, JA);
521 }
522 }
523
524 return *T;
525}
526
Daniel Dunbar75358d22009-03-30 21:06:03 +0000527/// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly.
528
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000529FreeBSD::FreeBSD(const HostInfo &Host, const llvm::Triple& Triple, bool Lib32)
530 : Generic_GCC(Host, Triple) {
Daniel Dunbarbc534662009-04-02 18:30:04 +0000531 if (Lib32) {
Daniel Dunbar75358d22009-03-30 21:06:03 +0000532 getFilePaths().push_back(getHost().getDriver().Dir + "/../lib32");
Daniel Dunbarbc534662009-04-02 18:30:04 +0000533 getFilePaths().push_back("/usr/lib32");
534 } else {
Daniel Dunbar75358d22009-03-30 21:06:03 +0000535 getFilePaths().push_back(getHost().getDriver().Dir + "/../lib");
Daniel Dunbarbc534662009-04-02 18:30:04 +0000536 getFilePaths().push_back("/usr/lib");
537 }
Daniel Dunbar75358d22009-03-30 21:06:03 +0000538}
539
540Tool &FreeBSD::SelectTool(const Compilation &C, const JobAction &JA) const {
541 Action::ActionClass Key;
Daniel Dunbara6046be2009-09-08 23:36:55 +0000542 if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
Daniel Dunbar75358d22009-03-30 21:06:03 +0000543 Key = Action::AnalyzeJobClass;
544 else
545 Key = JA.getKind();
546
547 Tool *&T = Tools[Key];
548 if (!T) {
549 switch (Key) {
Daniel Dunbar68a31d42009-03-31 17:45:15 +0000550 case Action::AssembleJobClass:
551 T = new tools::freebsd::Assemble(*this); break;
Daniel Dunbar008f54a2009-04-01 19:36:32 +0000552 case Action::LinkJobClass:
553 T = new tools::freebsd::Link(*this); break;
Daniel Dunbar75358d22009-03-30 21:06:03 +0000554 default:
555 T = &Generic_GCC::SelectTool(C, JA);
556 }
557 }
558
559 return *T;
560}
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000561
Edward O'Callaghane7925a02009-08-22 01:06:46 +0000562/// AuroraUX - AuroraUX tool chain which can call as(1) and ld(1) directly.
563
564AuroraUX::AuroraUX(const HostInfo &Host, const llvm::Triple& Triple)
565 : Generic_GCC(Host, Triple) {
566
567 // Path mangling to find libexec
568 std::string Path(getHost().getDriver().Dir);
569
570 Path += "/../libexec";
571 getProgramPaths().push_back(Path);
Mike Stump1eb44332009-09-09 15:08:12 +0000572 getProgramPaths().push_back(getHost().getDriver().Dir);
Edward O'Callaghane7925a02009-08-22 01:06:46 +0000573
574 getFilePaths().push_back(getHost().getDriver().Dir + "/../lib");
575 getFilePaths().push_back("/usr/lib");
576 getFilePaths().push_back("/usr/sfw/lib");
577 getFilePaths().push_back("/opt/gcc4/lib");
578
579}
580
581Tool &AuroraUX::SelectTool(const Compilation &C, const JobAction &JA) const {
582 Action::ActionClass Key;
Daniel Dunbara6046be2009-09-08 23:36:55 +0000583 if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
Edward O'Callaghane7925a02009-08-22 01:06:46 +0000584 Key = Action::AnalyzeJobClass;
585 else
586 Key = JA.getKind();
587
588 Tool *&T = Tools[Key];
589 if (!T) {
590 switch (Key) {
591 case Action::AssembleJobClass:
592 T = new tools::auroraux::Assemble(*this); break;
593 case Action::LinkJobClass:
594 T = new tools::auroraux::Link(*this); break;
595 default:
596 T = &Generic_GCC::SelectTool(C, JA);
597 }
598 }
599
600 return *T;
601}
602
603
Eli Friedman6b3454a2009-05-26 07:52:18 +0000604/// Linux toolchain (very bare-bones at the moment).
605
606Linux::Linux(const HostInfo &Host, const llvm::Triple& Triple)
607 : Generic_GCC(Host, Triple) {
608 getFilePaths().push_back(getHost().getDriver().Dir + "/../lib/clang/1.0/");
609 getFilePaths().push_back("/lib/");
610 getFilePaths().push_back("/usr/lib/");
Daniel Dunbara9822de2009-08-06 01:47:11 +0000611
612 // Depending on the Linux distribution, any combination of lib{,32,64} is
613 // possible. E.g. Debian uses lib and lib32 for mixed i386/x86-64 systems,
614 // openSUSE uses lib and lib64 for the same purpose.
615 getFilePaths().push_back("/lib32/");
616 getFilePaths().push_back("/usr/lib32/");
617 getFilePaths().push_back("/lib64/");
618 getFilePaths().push_back("/usr/lib64/");
619
Eli Friedman6b3454a2009-05-26 07:52:18 +0000620 // FIXME: Figure out some way to get gcc's libdir
621 // (e.g. /usr/lib/gcc/i486-linux-gnu/4.3/ for Ubuntu 32-bit); we need
622 // crtbegin.o/crtend.o/etc., and want static versions of various
623 // libraries. If we had our own crtbegin.o/crtend.o/etc, we could probably
624 // get away with using shared versions in /usr/lib, though.
625 // We could fall back to the approach we used for includes (a massive
626 // list), but that's messy at best.
627}
628
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000629/// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly.
630
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000631DragonFly::DragonFly(const HostInfo &Host, const llvm::Triple& Triple)
632 : Generic_GCC(Host, Triple) {
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000633
634 // Path mangling to find libexec
635 std::string Path(getHost().getDriver().Dir);
636
637 Path += "/../libexec";
638 getProgramPaths().push_back(Path);
Mike Stump1eb44332009-09-09 15:08:12 +0000639 getProgramPaths().push_back(getHost().getDriver().Dir);
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000640
641 getFilePaths().push_back(getHost().getDriver().Dir + "/../lib");
642 getFilePaths().push_back("/usr/lib");
643 getFilePaths().push_back("/usr/lib/gcc41");
644}
645
646Tool &DragonFly::SelectTool(const Compilation &C, const JobAction &JA) const {
647 Action::ActionClass Key;
Daniel Dunbara6046be2009-09-08 23:36:55 +0000648 if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000649 Key = Action::AnalyzeJobClass;
650 else
651 Key = JA.getKind();
652
653 Tool *&T = Tools[Key];
654 if (!T) {
655 switch (Key) {
656 case Action::AssembleJobClass:
657 T = new tools::dragonfly::Assemble(*this); break;
658 case Action::LinkJobClass:
659 T = new tools::dragonfly::Link(*this); break;
660 default:
661 T = &Generic_GCC::SelectTool(C, JA);
662 }
663 }
664
665 return *T;
666}