blob: dc35a33598bf4489305069faaa667fd8b79a29da [file] [log] [blame]
Nick Lewycky3fdcc6f2010-12-31 17:31:54 +00001//===--- ToolChains.cpp - ToolChain Implementations -----------------------===//
Daniel Dunbar39176082009-03-20 00:20:03 +00002//
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 Dunbar0f602de2010-05-20 21:48:38 +000014#include "clang/Driver/Compilation.h"
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000015#include "clang/Driver/Driver.h"
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +000016#include "clang/Driver/DriverDiagnostic.h"
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000017#include "clang/Driver/HostInfo.h"
Daniel Dunbar27e738d2009-11-19 00:15:11 +000018#include "clang/Driver/OptTable.h"
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +000019#include "clang/Driver/Option.h"
Daniel Dunbar265e9ef2009-11-19 04:25:22 +000020#include "clang/Driver/Options.h"
Douglas Gregor34916db2010-09-03 17:16:03 +000021#include "clang/Basic/Version.h"
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000022
Daniel Dunbar00577ad2010-08-23 22:35:37 +000023#include "llvm/ADT/SmallString.h"
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000024#include "llvm/ADT/StringExtras.h"
Daniel Dunbar84ec96c2009-09-09 22:33:15 +000025#include "llvm/Support/ErrorHandling.h"
Michael J. Spencer32bef4e2011-01-10 02:34:13 +000026#include "llvm/Support/FileSystem.h"
Rafael Espindolac1da9812010-11-07 20:14:31 +000027#include "llvm/Support/MemoryBuffer.h"
Daniel Dunbarec069ed2009-03-25 06:58:31 +000028#include "llvm/Support/raw_ostream.h"
Michael J. Spencer03013fa2010-11-29 18:12:39 +000029#include "llvm/Support/Path.h"
Michael J. Spencer3a321e22010-12-09 17:36:38 +000030#include "llvm/Support/system_error.h"
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000031
Daniel Dunbarf36a06a2009-04-10 21:00:07 +000032#include <cstdlib> // ::getenv
33
Daniel Dunbar39176082009-03-20 00:20:03 +000034using namespace clang::driver;
35using namespace clang::driver::toolchains;
36
Daniel Dunbarf3955282009-09-04 18:34:51 +000037/// Darwin - Darwin tool chain for i386 and x86_64.
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +000038
Daniel Dunbar25b58eb2010-08-02 05:44:07 +000039Darwin::Darwin(const HostInfo &Host, const llvm::Triple& Triple)
Daniel Dunbarcc8e1892010-01-27 00:56:44 +000040 : ToolChain(Host, Triple), TargetInitialized(false)
Daniel Dunbar1d4612b2009-09-18 08:15:13 +000041{
Daniel Dunbar25b58eb2010-08-02 05:44:07 +000042 // Compute the initial Darwin version based on the host.
43 bool HadExtra;
44 std::string OSName = Triple.getOSName();
Daniel Dunbar34f9e292011-02-25 21:20:15 +000045 if (!Driver::GetReleaseVersion(&OSName.c_str()[6],
Daniel Dunbar25b58eb2010-08-02 05:44:07 +000046 DarwinVersion[0], DarwinVersion[1],
47 DarwinVersion[2], HadExtra))
48 getDriver().Diag(clang::diag::err_drv_invalid_darwin_version) << OSName;
49
Daniel Dunbar02633b52009-03-26 16:23:12 +000050 llvm::raw_string_ostream(MacosxVersionMin)
Daniel Dunbar25b58eb2010-08-02 05:44:07 +000051 << "10." << std::max(0, (int)DarwinVersion[0] - 4) << '.'
52 << DarwinVersion[1];
Daniel Dunbar1d4612b2009-09-18 08:15:13 +000053}
54
Daniel Dunbar41800112010-08-02 05:43:56 +000055types::ID Darwin::LookupTypeForExtension(const char *Ext) const {
56 types::ID Ty = types::lookupTypeForExtension(Ext);
57
58 // Darwin always preprocesses assembly files (unless -x is used explicitly).
59 if (Ty == types::TY_PP_Asm)
60 return types::TY_Asm;
61
62 return Ty;
63}
64
Daniel Dunbarb993f5d2010-09-17 00:24:52 +000065bool Darwin::HasNativeLLVMSupport() const {
66 return true;
67}
68
Daniel Dunbareeff4062010-01-22 02:04:58 +000069// FIXME: Can we tablegen this?
70static const char *GetArmArchForMArch(llvm::StringRef Value) {
71 if (Value == "armv6k")
72 return "armv6";
73
74 if (Value == "armv5tej")
75 return "armv5";
76
77 if (Value == "xscale")
78 return "xscale";
79
80 if (Value == "armv4t")
81 return "armv4t";
82
83 if (Value == "armv7" || Value == "armv7-a" || Value == "armv7-r" ||
84 Value == "armv7-m" || Value == "armv7a" || Value == "armv7r" ||
85 Value == "armv7m")
86 return "armv7";
87
88 return 0;
89}
90
91// FIXME: Can we tablegen this?
92static const char *GetArmArchForMCpu(llvm::StringRef Value) {
93 if (Value == "arm10tdmi" || Value == "arm1020t" || Value == "arm9e" ||
94 Value == "arm946e-s" || Value == "arm966e-s" ||
95 Value == "arm968e-s" || Value == "arm10e" ||
96 Value == "arm1020e" || Value == "arm1022e" || Value == "arm926ej-s" ||
97 Value == "arm1026ej-s")
98 return "armv5";
99
100 if (Value == "xscale")
101 return "xscale";
102
103 if (Value == "arm1136j-s" || Value == "arm1136jf-s" ||
104 Value == "arm1176jz-s" || Value == "arm1176jzf-s")
105 return "armv6";
106
107 if (Value == "cortex-a8" || Value == "cortex-r4" || Value == "cortex-m3")
108 return "armv7";
109
110 return 0;
111}
112
113llvm::StringRef Darwin::getDarwinArchName(const ArgList &Args) const {
114 switch (getTriple().getArch()) {
115 default:
116 return getArchName();
Douglas Gregorf0594d82011-03-06 19:11:49 +0000117
118 case llvm::Triple::thumb:
Daniel Dunbareeff4062010-01-22 02:04:58 +0000119 case llvm::Triple::arm: {
120 if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
121 if (const char *Arch = GetArmArchForMArch(A->getValue(Args)))
122 return Arch;
123
124 if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
125 if (const char *Arch = GetArmArchForMCpu(A->getValue(Args)))
126 return Arch;
127
128 return "arm";
129 }
130 }
131}
132
Daniel Dunbar25b58eb2010-08-02 05:44:07 +0000133DarwinGCC::DarwinGCC(const HostInfo &Host, const llvm::Triple& Triple)
134 : Darwin(Host, Triple)
Daniel Dunbar1d4612b2009-09-18 08:15:13 +0000135{
Daniel Dunbarc2bda622010-08-02 05:44:01 +0000136 // We can only work with 4.2.1 currently.
137 GCCVersion[0] = 4;
138 GCCVersion[1] = 2;
139 GCCVersion[2] = 1;
Daniel Dunbar1d4612b2009-09-18 08:15:13 +0000140
141 // Set up the tool chain paths to match gcc.
Daniel Dunbarc50b00d2009-03-23 16:15:50 +0000142 ToolChainDir = "i686-apple-darwin";
Ted Kremenek55bac532009-10-07 03:21:11 +0000143 ToolChainDir += llvm::utostr(DarwinVersion[0]);
Daniel Dunbarc50b00d2009-03-23 16:15:50 +0000144 ToolChainDir += "/";
145 ToolChainDir += llvm::utostr(GCCVersion[0]);
146 ToolChainDir += '.';
147 ToolChainDir += llvm::utostr(GCCVersion[1]);
148 ToolChainDir += '.';
149 ToolChainDir += llvm::utostr(GCCVersion[2]);
150
Daniel Dunbar74782b02009-10-20 19:25:43 +0000151 // Try the next major version if that tool chain dir is invalid.
Daniel Dunbar080fb192009-10-22 00:12:00 +0000152 std::string Tmp = "/usr/lib/gcc/" + ToolChainDir;
Michael J. Spencer32bef4e2011-01-10 02:34:13 +0000153 bool Exists;
154 if (llvm::sys::fs::exists(Tmp, Exists) || Exists) {
Daniel Dunbar74782b02009-10-20 19:25:43 +0000155 std::string Next = "i686-apple-darwin";
156 Next += llvm::utostr(DarwinVersion[0] + 1);
157 Next += "/";
158 Next += llvm::utostr(GCCVersion[0]);
159 Next += '.';
160 Next += llvm::utostr(GCCVersion[1]);
161 Next += '.';
162 Next += llvm::utostr(GCCVersion[2]);
163
164 // Use that if it exists, otherwise hope the user isn't linking.
165 //
166 // FIXME: Drop dependency on gcc's tool chain.
Daniel Dunbar080fb192009-10-22 00:12:00 +0000167 Tmp = "/usr/lib/gcc/" + Next;
Michael J. Spencer32bef4e2011-01-10 02:34:13 +0000168 if (!llvm::sys::fs::exists(Tmp, Exists) && Exists)
Daniel Dunbar74782b02009-10-20 19:25:43 +0000169 ToolChainDir = Next;
170 }
171
Daniel Dunbarc50b00d2009-03-23 16:15:50 +0000172 std::string Path;
173 if (getArchName() == "x86_64") {
Daniel Dunbaree788e72009-12-21 18:54:17 +0000174 Path = getDriver().Dir;
Daniel Dunbarc50b00d2009-03-23 16:15:50 +0000175 Path += "/../lib/gcc/";
Daniel Dunbar6b200b22009-09-18 08:14:36 +0000176 Path += ToolChainDir;
Daniel Dunbarc50b00d2009-03-23 16:15:50 +0000177 Path += "/x86_64";
178 getFilePaths().push_back(Path);
179
180 Path = "/usr/lib/gcc/";
Daniel Dunbar6b200b22009-09-18 08:14:36 +0000181 Path += ToolChainDir;
Daniel Dunbarc50b00d2009-03-23 16:15:50 +0000182 Path += "/x86_64";
183 getFilePaths().push_back(Path);
184 }
Mike Stump1eb44332009-09-09 15:08:12 +0000185
Daniel Dunbaree788e72009-12-21 18:54:17 +0000186 Path = getDriver().Dir;
Daniel Dunbarc50b00d2009-03-23 16:15:50 +0000187 Path += "/../lib/gcc/";
Daniel Dunbar6b200b22009-09-18 08:14:36 +0000188 Path += ToolChainDir;
Daniel Dunbarc50b00d2009-03-23 16:15:50 +0000189 getFilePaths().push_back(Path);
190
191 Path = "/usr/lib/gcc/";
Daniel Dunbar6b200b22009-09-18 08:14:36 +0000192 Path += ToolChainDir;
Daniel Dunbarc50b00d2009-03-23 16:15:50 +0000193 getFilePaths().push_back(Path);
194
Daniel Dunbaree788e72009-12-21 18:54:17 +0000195 Path = getDriver().Dir;
Daniel Dunbarc50b00d2009-03-23 16:15:50 +0000196 Path += "/../libexec/gcc/";
Daniel Dunbar6b200b22009-09-18 08:14:36 +0000197 Path += ToolChainDir;
Daniel Dunbarc50b00d2009-03-23 16:15:50 +0000198 getProgramPaths().push_back(Path);
199
200 Path = "/usr/libexec/gcc/";
Daniel Dunbar6b200b22009-09-18 08:14:36 +0000201 Path += ToolChainDir;
Daniel Dunbarc50b00d2009-03-23 16:15:50 +0000202 getProgramPaths().push_back(Path);
203
Daniel Dunbaredf29b02010-08-01 22:29:51 +0000204 getProgramPaths().push_back(getDriver().getInstalledDir());
205 if (getDriver().getInstalledDir() != getDriver().Dir)
206 getProgramPaths().push_back(getDriver().Dir);
Daniel Dunbarc50b00d2009-03-23 16:15:50 +0000207}
208
Daniel Dunbarf3955282009-09-04 18:34:51 +0000209Darwin::~Darwin() {
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000210 // Free tool implementations.
211 for (llvm::DenseMap<unsigned, Tool*>::iterator
212 it = Tools.begin(), ie = Tools.end(); it != ie; ++it)
213 delete it->second;
214}
215
Daniel Dunbar00577ad2010-08-23 22:35:37 +0000216std::string Darwin::ComputeEffectiveClangTriple(const ArgList &Args) const {
217 llvm::Triple Triple(ComputeLLVMTriple(Args));
218
219 // If the target isn't initialized (e.g., an unknown Darwin platform, return
220 // the default triple).
221 if (!isTargetInitialized())
222 return Triple.getTriple();
223
224 unsigned Version[3];
225 getTargetVersion(Version);
226
227 // Mangle the target version into the OS triple component. For historical
228 // reasons that make little sense, the version passed here is the "darwin"
229 // version, which drops the 10 and offsets by 4. See inverse code when
230 // setting the OS version preprocessor define.
231 if (!isTargetIPhoneOS()) {
232 Version[0] = Version[1] + 4;
233 Version[1] = Version[2];
234 Version[2] = 0;
235 } else {
236 // Use the environment to communicate that we are targetting iPhoneOS.
237 Triple.setEnvironmentName("iphoneos");
238 }
239
240 llvm::SmallString<16> Str;
241 llvm::raw_svector_ostream(Str) << "darwin" << Version[0]
242 << "." << Version[1] << "." << Version[2];
243 Triple.setOSName(Str.str());
244
245 return Triple.getTriple();
246}
247
Daniel Dunbarf3955282009-09-04 18:34:51 +0000248Tool &Darwin::SelectTool(const Compilation &C, const JobAction &JA) const {
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000249 Action::ActionClass Key;
Daniel Dunbaree788e72009-12-21 18:54:17 +0000250 if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000251 Key = Action::AnalyzeJobClass;
252 else
253 Key = JA.getKind();
254
Daniel Dunbar0f602de2010-05-20 21:48:38 +0000255 // FIXME: This doesn't belong here, but ideally we will support static soon
256 // anyway.
257 bool HasStatic = (C.getArgs().hasArg(options::OPT_mkernel) ||
258 C.getArgs().hasArg(options::OPT_static) ||
259 C.getArgs().hasArg(options::OPT_fapple_kext));
260 bool IsIADefault = IsIntegratedAssemblerDefault() && !HasStatic;
261 bool UseIntegratedAs = C.getArgs().hasFlag(options::OPT_integrated_as,
262 options::OPT_no_integrated_as,
263 IsIADefault);
264
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000265 Tool *&T = Tools[Key];
266 if (!T) {
267 switch (Key) {
268 case Action::InputClass:
269 case Action::BindArchClass:
270 assert(0 && "Invalid tool kind.");
271 case Action::PreprocessJobClass:
Daniel Dunbar9120f172009-03-29 22:27:40 +0000272 T = new tools::darwin::Preprocess(*this); break;
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000273 case Action::AnalyzeJobClass:
274 T = new tools::Clang(*this); break;
Daniel Dunbar9120f172009-03-29 22:27:40 +0000275 case Action::PrecompileJobClass:
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000276 case Action::CompileJobClass:
Daniel Dunbar9120f172009-03-29 22:27:40 +0000277 T = new tools::darwin::Compile(*this); break;
Daniel Dunbar0f602de2010-05-20 21:48:38 +0000278 case Action::AssembleJobClass: {
279 if (UseIntegratedAs)
280 T = new tools::ClangAs(*this);
281 else
282 T = new tools::darwin::Assemble(*this);
283 break;
284 }
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000285 case Action::LinkJobClass:
Daniel Dunbar8f289622009-09-04 17:39:02 +0000286 T = new tools::darwin::Link(*this); break;
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000287 case Action::LipoJobClass:
288 T = new tools::darwin::Lipo(*this); break;
Daniel Dunbar6e0f2542010-06-04 18:28:36 +0000289 case Action::DsymutilJobClass:
290 T = new tools::darwin::Dsymutil(*this); break;
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000291 }
292 }
293
294 return *T;
295}
296
Daniel Dunbar1d4612b2009-09-18 08:15:13 +0000297void DarwinGCC::AddLinkSearchPathArgs(const ArgList &Args,
298 ArgStringList &CmdArgs) const {
Daniel Dunbare3c153a2010-04-10 18:18:57 +0000299 std::string Tmp;
300
Daniel Dunbar6b200b22009-09-18 08:14:36 +0000301 // FIXME: Derive these correctly.
302 if (getArchName() == "x86_64") {
303 CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir +
304 "/x86_64"));
305 // Intentionally duplicated for (temporary) gcc bug compatibility.
306 CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir +
307 "/x86_64"));
308 }
Daniel Dunbareab3bc42010-08-23 20:58:52 +0000309
Daniel Dunbar6b200b22009-09-18 08:14:36 +0000310 CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/" + ToolChainDir));
Daniel Dunbare3c153a2010-04-10 18:18:57 +0000311
312 Tmp = getDriver().Dir + "/../lib/gcc/" + ToolChainDir;
Michael J. Spencer32bef4e2011-01-10 02:34:13 +0000313 bool Exists;
314 if (!llvm::sys::fs::exists(Tmp, Exists) && Exists)
Daniel Dunbare3c153a2010-04-10 18:18:57 +0000315 CmdArgs.push_back(Args.MakeArgString("-L" + Tmp));
316 Tmp = getDriver().Dir + "/../lib/gcc";
Michael J. Spencer32bef4e2011-01-10 02:34:13 +0000317 if (!llvm::sys::fs::exists(Tmp, Exists) && Exists)
Daniel Dunbare3c153a2010-04-10 18:18:57 +0000318 CmdArgs.push_back(Args.MakeArgString("-L" + Tmp));
Daniel Dunbar6b200b22009-09-18 08:14:36 +0000319 CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir));
320 // Intentionally duplicated for (temporary) gcc bug compatibility.
321 CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir));
Daniel Dunbare3c153a2010-04-10 18:18:57 +0000322 Tmp = getDriver().Dir + "/../lib/" + ToolChainDir;
Michael J. Spencer32bef4e2011-01-10 02:34:13 +0000323 if (!llvm::sys::fs::exists(Tmp, Exists) && Exists)
Daniel Dunbare3c153a2010-04-10 18:18:57 +0000324 CmdArgs.push_back(Args.MakeArgString("-L" + Tmp));
325 Tmp = getDriver().Dir + "/../lib";
Michael J. Spencer32bef4e2011-01-10 02:34:13 +0000326 if (!llvm::sys::fs::exists(Tmp, Exists) && Exists)
Daniel Dunbare3c153a2010-04-10 18:18:57 +0000327 CmdArgs.push_back(Args.MakeArgString("-L" + Tmp));
Daniel Dunbar6b200b22009-09-18 08:14:36 +0000328 CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir +
329 "/../../../" + ToolChainDir));
330 CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir +
331 "/../../.."));
332}
333
Daniel Dunbar1d4612b2009-09-18 08:15:13 +0000334void DarwinGCC::AddLinkRuntimeLibArgs(const ArgList &Args,
335 ArgStringList &CmdArgs) const {
Daniel Dunbarce3fdf22010-01-27 00:57:03 +0000336 // Note that this routine is only used for targetting OS X.
Daniel Dunbar6cd41542009-09-18 08:15:03 +0000337
338 // Derived from libgcc and lib specs but refactored.
339 if (Args.hasArg(options::OPT_static)) {
340 CmdArgs.push_back("-lgcc_static");
341 } else {
342 if (Args.hasArg(options::OPT_static_libgcc)) {
343 CmdArgs.push_back("-lgcc_eh");
344 } else if (Args.hasArg(options::OPT_miphoneos_version_min_EQ)) {
345 // Derived from darwin_iphoneos_libgcc spec.
Daniel Dunbar251ca6c2010-01-27 00:56:37 +0000346 if (isTargetIPhoneOS()) {
Daniel Dunbar6cd41542009-09-18 08:15:03 +0000347 CmdArgs.push_back("-lgcc_s.1");
348 } else {
349 CmdArgs.push_back("-lgcc_s.10.5");
350 }
351 } else if (Args.hasArg(options::OPT_shared_libgcc) ||
Daniel Dunbar8a0d94d2010-01-10 00:46:10 +0000352 Args.hasFlag(options::OPT_fexceptions,
353 options::OPT_fno_exceptions) ||
Daniel Dunbar6cd41542009-09-18 08:15:03 +0000354 Args.hasArg(options::OPT_fgnu_runtime)) {
355 // FIXME: This is probably broken on 10.3?
Daniel Dunbarce3fdf22010-01-27 00:57:03 +0000356 if (isMacosxVersionLT(10, 5))
Daniel Dunbar6cd41542009-09-18 08:15:03 +0000357 CmdArgs.push_back("-lgcc_s.10.4");
Daniel Dunbarce3fdf22010-01-27 00:57:03 +0000358 else if (isMacosxVersionLT(10, 6))
Daniel Dunbar6cd41542009-09-18 08:15:03 +0000359 CmdArgs.push_back("-lgcc_s.10.5");
360 } else {
Daniel Dunbarce3fdf22010-01-27 00:57:03 +0000361 if (isMacosxVersionLT(10, 3, 9))
Daniel Dunbar6cd41542009-09-18 08:15:03 +0000362 ; // Do nothing.
Daniel Dunbarce3fdf22010-01-27 00:57:03 +0000363 else if (isMacosxVersionLT(10, 5))
Daniel Dunbar6cd41542009-09-18 08:15:03 +0000364 CmdArgs.push_back("-lgcc_s.10.4");
Daniel Dunbarce3fdf22010-01-27 00:57:03 +0000365 else if (isMacosxVersionLT(10, 6))
Daniel Dunbar6cd41542009-09-18 08:15:03 +0000366 CmdArgs.push_back("-lgcc_s.10.5");
367 }
368
Daniel Dunbarce3fdf22010-01-27 00:57:03 +0000369 if (isTargetIPhoneOS() || isMacosxVersionLT(10, 6)) {
Daniel Dunbar6cd41542009-09-18 08:15:03 +0000370 CmdArgs.push_back("-lgcc");
371 CmdArgs.push_back("-lSystem");
372 } else {
373 CmdArgs.push_back("-lSystem");
374 CmdArgs.push_back("-lgcc");
375 }
376 }
377}
378
Daniel Dunbar25b58eb2010-08-02 05:44:07 +0000379DarwinClang::DarwinClang(const HostInfo &Host, const llvm::Triple& Triple)
380 : Darwin(Host, Triple)
Daniel Dunbar1d4612b2009-09-18 08:15:13 +0000381{
Daniel Dunbar0e50ee42010-09-17 08:22:12 +0000382 getProgramPaths().push_back(getDriver().getInstalledDir());
383 if (getDriver().getInstalledDir() != getDriver().Dir)
384 getProgramPaths().push_back(getDriver().Dir);
385
Daniel Dunbar1d4612b2009-09-18 08:15:13 +0000386 // We expect 'as', 'ld', etc. to be adjacent to our install dir.
Daniel Dunbaredf29b02010-08-01 22:29:51 +0000387 getProgramPaths().push_back(getDriver().getInstalledDir());
388 if (getDriver().getInstalledDir() != getDriver().Dir)
389 getProgramPaths().push_back(getDriver().Dir);
Daniel Dunbar0e50ee42010-09-17 08:22:12 +0000390
391 // For fallback, we need to know how to find the GCC cc1 executables, so we
392 // also add the GCC libexec paths. This is legiy code that can be removed once
393 // fallback is no longer useful.
394 std::string ToolChainDir = "i686-apple-darwin";
395 ToolChainDir += llvm::utostr(DarwinVersion[0]);
396 ToolChainDir += "/4.2.1";
397
398 std::string Path = getDriver().Dir;
399 Path += "/../libexec/gcc/";
400 Path += ToolChainDir;
401 getProgramPaths().push_back(Path);
402
403 Path = "/usr/libexec/gcc/";
404 Path += ToolChainDir;
405 getProgramPaths().push_back(Path);
Daniel Dunbar1d4612b2009-09-18 08:15:13 +0000406}
407
408void DarwinClang::AddLinkSearchPathArgs(const ArgList &Args,
409 ArgStringList &CmdArgs) const {
410 // The Clang toolchain uses explicit paths for internal libraries.
Daniel Dunbar424b6612010-06-30 23:56:13 +0000411
412 // Unfortunately, we still might depend on a few of the libraries that are
413 // only available in the gcc library directory (in particular
414 // libstdc++.dylib). For now, hardcode the path to the known install location.
415 llvm::sys::Path P(getDriver().Dir);
416 P.eraseComponent(); // .../usr/bin -> ../usr
417 P.appendComponent("lib");
418 P.appendComponent("gcc");
419 switch (getTriple().getArch()) {
420 default:
421 assert(0 && "Invalid Darwin arch!");
422 case llvm::Triple::x86:
423 case llvm::Triple::x86_64:
424 P.appendComponent("i686-apple-darwin10");
425 break;
426 case llvm::Triple::arm:
427 case llvm::Triple::thumb:
428 P.appendComponent("arm-apple-darwin10");
429 break;
430 case llvm::Triple::ppc:
431 case llvm::Triple::ppc64:
432 P.appendComponent("powerpc-apple-darwin10");
433 break;
434 }
435 P.appendComponent("4.2.1");
Daniel Dunbareab3bc42010-08-23 20:58:52 +0000436
437 // Determine the arch specific GCC subdirectory.
438 const char *ArchSpecificDir = 0;
439 switch (getTriple().getArch()) {
440 default:
441 break;
442 case llvm::Triple::arm:
Daniel Dunbar3a0e3922010-08-26 00:55:52 +0000443 case llvm::Triple::thumb: {
444 std::string Triple = ComputeLLVMTriple(Args);
445 llvm::StringRef TripleStr = Triple;
446 if (TripleStr.startswith("armv5") || TripleStr.startswith("thumbv5"))
447 ArchSpecificDir = "v5";
448 else if (TripleStr.startswith("armv6") || TripleStr.startswith("thumbv6"))
449 ArchSpecificDir = "v6";
450 else if (TripleStr.startswith("armv7") || TripleStr.startswith("thumbv7"))
451 ArchSpecificDir = "v7";
Daniel Dunbareab3bc42010-08-23 20:58:52 +0000452 break;
Daniel Dunbar3a0e3922010-08-26 00:55:52 +0000453 }
Daniel Dunbareab3bc42010-08-23 20:58:52 +0000454 case llvm::Triple::ppc64:
455 ArchSpecificDir = "ppc64";
456 break;
457 case llvm::Triple::x86_64:
458 ArchSpecificDir = "x86_64";
459 break;
460 }
461
462 if (ArchSpecificDir) {
463 P.appendComponent(ArchSpecificDir);
Michael J. Spencer32bef4e2011-01-10 02:34:13 +0000464 bool Exists;
465 if (!llvm::sys::fs::exists(P.str(), Exists) && Exists)
Daniel Dunbareab3bc42010-08-23 20:58:52 +0000466 CmdArgs.push_back(Args.MakeArgString("-L" + P.str()));
467 P.eraseComponent();
468 }
469
Michael J. Spencer32bef4e2011-01-10 02:34:13 +0000470 bool Exists;
471 if (!llvm::sys::fs::exists(P.str(), Exists) && Exists)
Daniel Dunbar424b6612010-06-30 23:56:13 +0000472 CmdArgs.push_back(Args.MakeArgString("-L" + P.str()));
Daniel Dunbar1d4612b2009-09-18 08:15:13 +0000473}
474
475void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args,
476 ArgStringList &CmdArgs) const {
Daniel Dunbareec99102010-01-22 03:38:14 +0000477 // Darwin doesn't support real static executables, don't link any runtime
478 // libraries with -static.
479 if (Args.hasArg(options::OPT_static))
Daniel Dunbar1d4612b2009-09-18 08:15:13 +0000480 return;
Daniel Dunbar1d4612b2009-09-18 08:15:13 +0000481
482 // Reject -static-libgcc for now, we can deal with this when and if someone
483 // cares. This is useful in situations where someone wants to statically link
484 // something like libstdc++, and needs its runtime support routines.
485 if (const Arg *A = Args.getLastArg(options::OPT_static_libgcc)) {
Daniel Dunbaree788e72009-12-21 18:54:17 +0000486 getDriver().Diag(clang::diag::err_drv_unsupported_opt)
Daniel Dunbar1d4612b2009-09-18 08:15:13 +0000487 << A->getAsString(Args);
488 return;
489 }
490
Daniel Dunbareec99102010-01-22 03:38:14 +0000491 // Otherwise link libSystem, then the dynamic runtime library, and finally any
492 // target specific static runtime library.
Daniel Dunbar1d4612b2009-09-18 08:15:13 +0000493 CmdArgs.push_back("-lSystem");
Daniel Dunbareec99102010-01-22 03:38:14 +0000494
495 // Select the dynamic runtime library and the target specific static library.
496 const char *DarwinStaticLib = 0;
Daniel Dunbar251ca6c2010-01-27 00:56:37 +0000497 if (isTargetIPhoneOS()) {
Daniel Dunbareec99102010-01-22 03:38:14 +0000498 CmdArgs.push_back("-lgcc_s.1");
499
500 // We may need some static functions for armv6/thumb which are required to
501 // be in the same linkage unit as their caller.
502 if (getDarwinArchName(Args) == "armv6")
503 DarwinStaticLib = "libclang_rt.armv6.a";
504 } else {
Daniel Dunbareec99102010-01-22 03:38:14 +0000505 // The dynamic runtime library was merged with libSystem for 10.6 and
506 // beyond; only 10.4 and 10.5 need an additional runtime library.
Daniel Dunbarce3fdf22010-01-27 00:57:03 +0000507 if (isMacosxVersionLT(10, 5))
Daniel Dunbareec99102010-01-22 03:38:14 +0000508 CmdArgs.push_back("-lgcc_s.10.4");
Daniel Dunbarce3fdf22010-01-27 00:57:03 +0000509 else if (isMacosxVersionLT(10, 6))
Daniel Dunbareec99102010-01-22 03:38:14 +0000510 CmdArgs.push_back("-lgcc_s.10.5");
511
Daniel Dunbar885b1db2010-09-22 00:03:52 +0000512 // For OS X, we thought we would only need a static runtime library when
513 // targetting 10.4, to provide versions of the static functions which were
514 // omitted from 10.4.dylib.
515 //
516 // Unfortunately, that turned out to not be true, because Darwin system
517 // headers can still use eprintf on i386, and it is not exported from
518 // libSystem. Therefore, we still must provide a runtime library just for
519 // the tiny tiny handful of projects that *might* use that symbol.
520 if (isMacosxVersionLT(10, 5)) {
Daniel Dunbareec99102010-01-22 03:38:14 +0000521 DarwinStaticLib = "libclang_rt.10.4.a";
Daniel Dunbar885b1db2010-09-22 00:03:52 +0000522 } else {
523 if (getTriple().getArch() == llvm::Triple::x86)
524 DarwinStaticLib = "libclang_rt.eprintf.a";
525 }
Daniel Dunbareec99102010-01-22 03:38:14 +0000526 }
527
528 /// Add the target specific static library, if needed.
529 if (DarwinStaticLib) {
530 llvm::sys::Path P(getDriver().ResourceDir);
531 P.appendComponent("lib");
532 P.appendComponent("darwin");
533 P.appendComponent(DarwinStaticLib);
534
535 // For now, allow missing resource libraries to support developers who may
536 // not have compiler-rt checked out or integrated into their build.
Michael J. Spencer32bef4e2011-01-10 02:34:13 +0000537 bool Exists;
538 if (!llvm::sys::fs::exists(P.str(), Exists) && Exists)
Daniel Dunbareec99102010-01-22 03:38:14 +0000539 CmdArgs.push_back(Args.MakeArgString(P.str()));
540 }
Daniel Dunbar1d4612b2009-09-18 08:15:13 +0000541}
542
Daniel Dunbar60baf0f2010-07-19 17:11:36 +0000543void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
Daniel Dunbaree788e72009-12-21 18:54:17 +0000544 const OptTable &Opts = getDriver().getOpts();
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000545
Daniel Dunbar26031372010-01-27 00:56:25 +0000546 Arg *OSXVersion = Args.getLastArg(options::OPT_mmacosx_version_min_EQ);
547 Arg *iPhoneVersion = Args.getLastArg(options::OPT_miphoneos_version_min_EQ);
Daniel Dunbarff8857a2009-04-10 20:11:50 +0000548 if (OSXVersion && iPhoneVersion) {
Daniel Dunbaree788e72009-12-21 18:54:17 +0000549 getDriver().Diag(clang::diag::err_drv_argument_not_allowed_with)
Daniel Dunbarff8857a2009-04-10 20:11:50 +0000550 << OSXVersion->getAsString(Args)
Mike Stump1eb44332009-09-09 15:08:12 +0000551 << iPhoneVersion->getAsString(Args);
Daniel Dunbar26031372010-01-27 00:56:25 +0000552 iPhoneVersion = 0;
Daniel Dunbarff8857a2009-04-10 20:11:50 +0000553 } else if (!OSXVersion && !iPhoneVersion) {
Daniel Dunbar816bc312010-01-26 01:45:19 +0000554 // If neither OS X nor iPhoneOS targets were specified, check for
555 // environment defines.
556 const char *OSXTarget = ::getenv("MACOSX_DEPLOYMENT_TARGET");
557 const char *iPhoneOSTarget = ::getenv("IPHONEOS_DEPLOYMENT_TARGET");
Daniel Dunbarf36a06a2009-04-10 21:00:07 +0000558
Daniel Dunbar816bc312010-01-26 01:45:19 +0000559 // Ignore empty strings.
560 if (OSXTarget && OSXTarget[0] == '\0')
561 OSXTarget = 0;
562 if (iPhoneOSTarget && iPhoneOSTarget[0] == '\0')
563 iPhoneOSTarget = 0;
564
Daniel Dunbar39053672010-02-02 17:31:12 +0000565 // Diagnose conflicting deployment targets, and choose default platform
566 // based on the tool chain.
567 //
568 // FIXME: Don't hardcode default here.
569 if (OSXTarget && iPhoneOSTarget) {
570 // FIXME: We should see if we can get away with warning or erroring on
571 // this. Perhaps put under -pedantic?
572 if (getTriple().getArch() == llvm::Triple::arm ||
573 getTriple().getArch() == llvm::Triple::thumb)
Daniel Dunbar84d1e6e2010-03-20 08:47:42 +0000574 OSXTarget = 0;
Daniel Dunbar39053672010-02-02 17:31:12 +0000575 else
Daniel Dunbar84d1e6e2010-03-20 08:47:42 +0000576 iPhoneOSTarget = 0;
Daniel Dunbar39053672010-02-02 17:31:12 +0000577 }
Daniel Dunbar1a3c1d92010-01-29 17:02:25 +0000578
Daniel Dunbar39053672010-02-02 17:31:12 +0000579 if (OSXTarget) {
Daniel Dunbar30392de2009-09-04 18:35:21 +0000580 const Option *O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
Daniel Dunbar60baf0f2010-07-19 17:11:36 +0000581 OSXVersion = Args.MakeJoinedArg(0, O, OSXTarget);
582 Args.append(OSXVersion);
Daniel Dunbar816bc312010-01-26 01:45:19 +0000583 } else if (iPhoneOSTarget) {
Daniel Dunbar30392de2009-09-04 18:35:21 +0000584 const Option *O = Opts.getOption(options::OPT_miphoneos_version_min_EQ);
Daniel Dunbar60baf0f2010-07-19 17:11:36 +0000585 iPhoneVersion = Args.MakeJoinedArg(0, O, iPhoneOSTarget);
586 Args.append(iPhoneVersion);
Daniel Dunbar816bc312010-01-26 01:45:19 +0000587 } else {
Daniel Dunbar2bb38d02010-07-15 16:18:06 +0000588 // Otherwise, assume we are targeting OS X.
589 const Option *O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
Daniel Dunbar60baf0f2010-07-19 17:11:36 +0000590 OSXVersion = Args.MakeJoinedArg(0, O, MacosxVersionMin);
591 Args.append(OSXVersion);
Daniel Dunbar30392de2009-09-04 18:35:21 +0000592 }
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000593 }
Mike Stump1eb44332009-09-09 15:08:12 +0000594
Daniel Dunbar26031372010-01-27 00:56:25 +0000595 // Set the tool chain target information.
596 unsigned Major, Minor, Micro;
597 bool HadExtra;
598 if (OSXVersion) {
599 assert(!iPhoneVersion && "Unknown target platform!");
600 if (!Driver::GetReleaseVersion(OSXVersion->getValue(Args), Major, Minor,
601 Micro, HadExtra) || HadExtra ||
602 Major != 10 || Minor >= 10 || Micro >= 10)
603 getDriver().Diag(clang::diag::err_drv_invalid_version_number)
604 << OSXVersion->getAsString(Args);
605 } else {
606 assert(iPhoneVersion && "Unknown target platform!");
607 if (!Driver::GetReleaseVersion(iPhoneVersion->getValue(Args), Major, Minor,
608 Micro, HadExtra) || HadExtra ||
609 Major >= 10 || Minor >= 100 || Micro >= 100)
610 getDriver().Diag(clang::diag::err_drv_invalid_version_number)
611 << iPhoneVersion->getAsString(Args);
612 }
613 setTarget(iPhoneVersion, Major, Minor, Micro);
Daniel Dunbarc0e665e2010-07-19 17:11:33 +0000614}
615
Daniel Dunbar132e35d2010-09-17 01:20:05 +0000616void DarwinClang::AddCXXStdlibLibArgs(const ArgList &Args,
Daniel Dunbarefe91ea2010-09-17 01:16:06 +0000617 ArgStringList &CmdArgs) const {
618 CXXStdlibType Type = GetCXXStdlibType(Args);
619
620 switch (Type) {
621 case ToolChain::CST_Libcxx:
622 CmdArgs.push_back("-lc++");
623 break;
624
625 case ToolChain::CST_Libstdcxx: {
626 // Unfortunately, -lstdc++ doesn't always exist in the standard search path;
627 // it was previously found in the gcc lib dir. However, for all the Darwin
628 // platforms we care about it was -lstdc++.6, so we search for that
629 // explicitly if we can't see an obvious -lstdc++ candidate.
630
631 // Check in the sysroot first.
Michael J. Spencer32bef4e2011-01-10 02:34:13 +0000632 bool Exists;
Daniel Dunbarefe91ea2010-09-17 01:16:06 +0000633 if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
634 llvm::sys::Path P(A->getValue(Args));
635 P.appendComponent("usr");
636 P.appendComponent("lib");
637 P.appendComponent("libstdc++.dylib");
638
Michael J. Spencer32bef4e2011-01-10 02:34:13 +0000639 if (llvm::sys::fs::exists(P.str(), Exists) || !Exists) {
Daniel Dunbarefe91ea2010-09-17 01:16:06 +0000640 P.eraseComponent();
641 P.appendComponent("libstdc++.6.dylib");
Michael J. Spencer32bef4e2011-01-10 02:34:13 +0000642 if (!llvm::sys::fs::exists(P.str(), Exists) && Exists) {
Daniel Dunbarefe91ea2010-09-17 01:16:06 +0000643 CmdArgs.push_back(Args.MakeArgString(P.str()));
644 return;
645 }
646 }
647 }
648
649 // Otherwise, look in the root.
Michael J. Spencer32bef4e2011-01-10 02:34:13 +0000650 if ((llvm::sys::fs::exists("/usr/lib/libstdc++.dylib", Exists) || !Exists)&&
651 (!llvm::sys::fs::exists("/usr/lib/libstdc++.6.dylib", Exists) && Exists)){
Daniel Dunbarefe91ea2010-09-17 01:16:06 +0000652 CmdArgs.push_back("/usr/lib/libstdc++.6.dylib");
653 return;
654 }
655
656 // Otherwise, let the linker search.
657 CmdArgs.push_back("-lstdc++");
658 break;
659 }
660 }
661}
662
Shantonu Sen7433fed2010-09-17 18:39:08 +0000663void DarwinClang::AddCCKextLibArgs(const ArgList &Args,
664 ArgStringList &CmdArgs) const {
665
666 // For Darwin platforms, use the compiler-rt-based support library
667 // instead of the gcc-provided one (which is also incidentally
668 // only present in the gcc lib dir, which makes it hard to find).
669
670 llvm::sys::Path P(getDriver().ResourceDir);
671 P.appendComponent("lib");
672 P.appendComponent("darwin");
673 P.appendComponent("libclang_rt.cc_kext.a");
674
675 // For now, allow missing resource libraries to support developers who may
676 // not have compiler-rt checked out or integrated into their build.
Michael J. Spencer32bef4e2011-01-10 02:34:13 +0000677 bool Exists;
678 if (!llvm::sys::fs::exists(P.str(), Exists) && Exists)
Shantonu Sen7433fed2010-09-17 18:39:08 +0000679 CmdArgs.push_back(Args.MakeArgString(P.str()));
680}
681
Daniel Dunbarc0e665e2010-07-19 17:11:33 +0000682DerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args,
683 const char *BoundArch) const {
684 DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
685 const OptTable &Opts = getDriver().getOpts();
686
687 // FIXME: We really want to get out of the tool chain level argument
688 // translation business, as it makes the driver functionality much
689 // more opaque. For now, we follow gcc closely solely for the
690 // purpose of easily achieving feature parity & testability. Once we
691 // have something that works, we should reevaluate each translation
692 // and try to push it down into tool specific logic.
Daniel Dunbar26031372010-01-27 00:56:25 +0000693
Daniel Dunbar279c1db2010-06-11 22:00:26 +0000694 for (ArgList::const_iterator it = Args.begin(),
695 ie = Args.end(); it != ie; ++it) {
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000696 Arg *A = *it;
697
698 if (A->getOption().matches(options::OPT_Xarch__)) {
699 // FIXME: Canonicalize name.
700 if (getArchName() != A->getValue(Args, 0))
701 continue;
702
Daniel Dunbar8ac38d72011-02-19 05:33:51 +0000703 Arg *OriginalArg = A;
Daniel Dunbar0e100312010-06-14 21:23:08 +0000704 unsigned Index = Args.getBaseArgs().MakeIndex(A->getValue(Args, 1));
705 unsigned Prev = Index;
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000706 Arg *XarchArg = Opts.ParseOneArg(Args, Index);
Mike Stump1eb44332009-09-09 15:08:12 +0000707
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000708 // If the argument parsing failed or more than one argument was
709 // consumed, the -Xarch_ argument's parameter tried to consume
710 // extra arguments. Emit an error and ignore.
711 //
712 // We also want to disallow any options which would alter the
713 // driver behavior; that isn't going to work in our model. We
714 // use isDriverOption() as an approximation, although things
715 // like -O4 are going to slip through.
Mike Stump1eb44332009-09-09 15:08:12 +0000716 if (!XarchArg || Index > Prev + 1 ||
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000717 XarchArg->getOption().isDriverOption()) {
Daniel Dunbaree788e72009-12-21 18:54:17 +0000718 getDriver().Diag(clang::diag::err_drv_invalid_Xarch_argument)
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000719 << A->getAsString(Args);
720 continue;
721 }
722
Daniel Dunbar478edc22009-03-29 22:29:05 +0000723 XarchArg->setBaseArg(A);
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000724 A = XarchArg;
Daniel Dunbar0e100312010-06-14 21:23:08 +0000725
726 DAL->AddSynthesizedArg(A);
Daniel Dunbar8ac38d72011-02-19 05:33:51 +0000727
728 // Linker input arguments require custom handling. The problem is that we
729 // have already constructed the phase actions, so we can not treat them as
730 // "input arguments".
731 if (A->getOption().isLinkerInput()) {
732 // Convert the argument into individual Zlinker_input_args.
733 for (unsigned i = 0, e = A->getNumValues(); i != e; ++i) {
734 DAL->AddSeparateArg(OriginalArg,
735 Opts.getOption(options::OPT_Zlinker_input),
736 A->getValue(Args, i));
737
738 }
739 continue;
740 }
Mike Stump1eb44332009-09-09 15:08:12 +0000741 }
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000742
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000743 // Sob. These is strictly gcc compatible for the time being. Apple
744 // gcc translates options twice, which means that self-expanding
745 // options add duplicates.
Daniel Dunbar9e1f9822009-11-19 04:14:53 +0000746 switch ((options::ID) A->getOption().getID()) {
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000747 default:
748 DAL->append(A);
749 break;
750
751 case options::OPT_mkernel:
752 case options::OPT_fapple_kext:
753 DAL->append(A);
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000754 DAL->AddFlagArg(A, Opts.getOption(options::OPT_static));
755 DAL->AddFlagArg(A, Opts.getOption(options::OPT_static));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000756 break;
Mike Stump1eb44332009-09-09 15:08:12 +0000757
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000758 case options::OPT_dependency_file:
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000759 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF),
760 A->getValue(Args));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000761 break;
762
763 case options::OPT_gfull:
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000764 DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag));
765 DAL->AddFlagArg(A,
766 Opts.getOption(options::OPT_fno_eliminate_unused_debug_symbols));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000767 break;
768
769 case options::OPT_gused:
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000770 DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag));
771 DAL->AddFlagArg(A,
772 Opts.getOption(options::OPT_feliminate_unused_debug_symbols));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000773 break;
774
775 case options::OPT_fterminated_vtables:
776 case options::OPT_findirect_virtual_calls:
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000777 DAL->AddFlagArg(A, Opts.getOption(options::OPT_fapple_kext));
778 DAL->AddFlagArg(A, Opts.getOption(options::OPT_static));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000779 break;
780
781 case options::OPT_shared:
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000782 DAL->AddFlagArg(A, Opts.getOption(options::OPT_dynamiclib));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000783 break;
784
785 case options::OPT_fconstant_cfstrings:
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000786 DAL->AddFlagArg(A, Opts.getOption(options::OPT_mconstant_cfstrings));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000787 break;
788
789 case options::OPT_fno_constant_cfstrings:
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000790 DAL->AddFlagArg(A, Opts.getOption(options::OPT_mno_constant_cfstrings));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000791 break;
792
793 case options::OPT_Wnonportable_cfstrings:
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000794 DAL->AddFlagArg(A,
795 Opts.getOption(options::OPT_mwarn_nonportable_cfstrings));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000796 break;
797
798 case options::OPT_Wno_nonportable_cfstrings:
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000799 DAL->AddFlagArg(A,
800 Opts.getOption(options::OPT_mno_warn_nonportable_cfstrings));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000801 break;
802
803 case options::OPT_fpascal_strings:
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000804 DAL->AddFlagArg(A, Opts.getOption(options::OPT_mpascal_strings));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000805 break;
806
807 case options::OPT_fno_pascal_strings:
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000808 DAL->AddFlagArg(A, Opts.getOption(options::OPT_mno_pascal_strings));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000809 break;
810 }
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000811 }
812
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000813 if (getTriple().getArch() == llvm::Triple::x86 ||
814 getTriple().getArch() == llvm::Triple::x86_64)
Daniel Dunbare4bdae72009-11-19 04:00:53 +0000815 if (!Args.hasArgNoClaim(options::OPT_mtune_EQ))
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000816 DAL->AddJoinedArg(0, Opts.getOption(options::OPT_mtune_EQ), "core2");
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000817
818 // Add the arch options based on the particular spelling of -arch, to match
819 // how the driver driver works.
820 if (BoundArch) {
821 llvm::StringRef Name = BoundArch;
822 const Option *MCpu = Opts.getOption(options::OPT_mcpu_EQ);
823 const Option *MArch = Opts.getOption(options::OPT_march_EQ);
824
825 // This code must be kept in sync with LLVM's getArchTypeForDarwinArch,
826 // which defines the list of which architectures we accept.
827 if (Name == "ppc")
828 ;
829 else if (Name == "ppc601")
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000830 DAL->AddJoinedArg(0, MCpu, "601");
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000831 else if (Name == "ppc603")
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000832 DAL->AddJoinedArg(0, MCpu, "603");
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000833 else if (Name == "ppc604")
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000834 DAL->AddJoinedArg(0, MCpu, "604");
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000835 else if (Name == "ppc604e")
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000836 DAL->AddJoinedArg(0, MCpu, "604e");
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000837 else if (Name == "ppc750")
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000838 DAL->AddJoinedArg(0, MCpu, "750");
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000839 else if (Name == "ppc7400")
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000840 DAL->AddJoinedArg(0, MCpu, "7400");
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000841 else if (Name == "ppc7450")
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000842 DAL->AddJoinedArg(0, MCpu, "7450");
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000843 else if (Name == "ppc970")
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000844 DAL->AddJoinedArg(0, MCpu, "970");
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000845
846 else if (Name == "ppc64")
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000847 DAL->AddFlagArg(0, Opts.getOption(options::OPT_m64));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000848
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000849 else if (Name == "i386")
850 ;
851 else if (Name == "i486")
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000852 DAL->AddJoinedArg(0, MArch, "i486");
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000853 else if (Name == "i586")
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000854 DAL->AddJoinedArg(0, MArch, "i586");
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000855 else if (Name == "i686")
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000856 DAL->AddJoinedArg(0, MArch, "i686");
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000857 else if (Name == "pentium")
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000858 DAL->AddJoinedArg(0, MArch, "pentium");
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000859 else if (Name == "pentium2")
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000860 DAL->AddJoinedArg(0, MArch, "pentium2");
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000861 else if (Name == "pentpro")
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000862 DAL->AddJoinedArg(0, MArch, "pentiumpro");
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000863 else if (Name == "pentIIm3")
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000864 DAL->AddJoinedArg(0, MArch, "pentium2");
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000865
866 else if (Name == "x86_64")
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000867 DAL->AddFlagArg(0, Opts.getOption(options::OPT_m64));
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000868
869 else if (Name == "arm")
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000870 DAL->AddJoinedArg(0, MArch, "armv4t");
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000871 else if (Name == "armv4t")
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000872 DAL->AddJoinedArg(0, MArch, "armv4t");
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000873 else if (Name == "armv5")
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000874 DAL->AddJoinedArg(0, MArch, "armv5tej");
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000875 else if (Name == "xscale")
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000876 DAL->AddJoinedArg(0, MArch, "xscale");
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000877 else if (Name == "armv6")
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000878 DAL->AddJoinedArg(0, MArch, "armv6k");
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000879 else if (Name == "armv7")
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000880 DAL->AddJoinedArg(0, MArch, "armv7a");
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000881
882 else
Jeffrey Yasskin9f61aa92009-12-12 05:05:38 +0000883 llvm_unreachable("invalid Darwin arch");
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000884 }
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000885
Daniel Dunbar60baf0f2010-07-19 17:11:36 +0000886 // Add an explicit version min argument for the deployment target. We do this
887 // after argument translation because -Xarch_ arguments may add a version min
888 // argument.
889 AddDeploymentTarget(*DAL);
890
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000891 return DAL;
Mike Stump1eb44332009-09-09 15:08:12 +0000892}
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000893
Daniel Dunbarf3955282009-09-04 18:34:51 +0000894bool Darwin::IsUnwindTablesDefault() const {
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000895 // FIXME: Gross; we should probably have some separate target
896 // definition, possibly even reusing the one in clang.
897 return getArchName() == "x86_64";
898}
899
Daniel Dunbarf2d8b9f2009-12-18 02:43:17 +0000900bool Darwin::UseDwarfDebugFlags() const {
901 if (const char *S = ::getenv("RC_DEBUG_OPTIONS"))
902 return S[0] != '\0';
903 return false;
904}
905
Daniel Dunbarb2987d12010-02-10 18:49:11 +0000906bool Darwin::UseSjLjExceptions() const {
907 // Darwin uses SjLj exceptions on ARM.
908 return (getTriple().getArch() == llvm::Triple::arm ||
909 getTriple().getArch() == llvm::Triple::thumb);
910}
911
Daniel Dunbarf3955282009-09-04 18:34:51 +0000912const char *Darwin::GetDefaultRelocationModel() const {
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000913 return "pic";
914}
915
Daniel Dunbarf3955282009-09-04 18:34:51 +0000916const char *Darwin::GetForcedPicModel() const {
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000917 if (getArchName() == "x86_64")
918 return "pic";
919 return 0;
920}
921
Daniel Dunbarbbe8e3e2011-03-01 18:49:30 +0000922bool Darwin::SupportsProfiling() const {
923 // Profiling instrumentation is only supported on x86.
924 return getArchName() == "i386" || getArchName() == "x86_64";
925}
926
Daniel Dunbar43a9b322010-04-10 16:20:23 +0000927bool Darwin::SupportsObjCGC() const {
928 // Garbage collection is supported everywhere except on iPhone OS.
929 return !isTargetIPhoneOS();
930}
931
Daniel Dunbar00577ad2010-08-23 22:35:37 +0000932std::string
933Darwin_Generic_GCC::ComputeEffectiveClangTriple(const ArgList &Args) const {
934 return ComputeLLVMTriple(Args);
935}
936
Daniel Dunbar39176082009-03-20 00:20:03 +0000937/// Generic_GCC - A tool chain using the 'gcc' command to perform
938/// all subcommands; this relies on gcc translating the majority of
939/// command line options.
940
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000941Generic_GCC::Generic_GCC(const HostInfo &Host, const llvm::Triple& Triple)
Mike Stump1eb44332009-09-09 15:08:12 +0000942 : ToolChain(Host, Triple) {
Daniel Dunbaredf29b02010-08-01 22:29:51 +0000943 getProgramPaths().push_back(getDriver().getInstalledDir());
Benjamin Kramer86643b82011-03-01 22:50:47 +0000944 if (getDriver().getInstalledDir() != getDriver().Dir)
Daniel Dunbaredf29b02010-08-01 22:29:51 +0000945 getProgramPaths().push_back(getDriver().Dir);
Daniel Dunbarc50b00d2009-03-23 16:15:50 +0000946}
947
Daniel Dunbar39176082009-03-20 00:20:03 +0000948Generic_GCC::~Generic_GCC() {
949 // Free tool implementations.
950 for (llvm::DenseMap<unsigned, Tool*>::iterator
951 it = Tools.begin(), ie = Tools.end(); it != ie; ++it)
952 delete it->second;
953}
954
Mike Stump1eb44332009-09-09 15:08:12 +0000955Tool &Generic_GCC::SelectTool(const Compilation &C,
Daniel Dunbar39176082009-03-20 00:20:03 +0000956 const JobAction &JA) const {
957 Action::ActionClass Key;
Daniel Dunbaree788e72009-12-21 18:54:17 +0000958 if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
Daniel Dunbar39176082009-03-20 00:20:03 +0000959 Key = Action::AnalyzeJobClass;
960 else
961 Key = JA.getKind();
962
963 Tool *&T = Tools[Key];
964 if (!T) {
965 switch (Key) {
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000966 case Action::InputClass:
967 case Action::BindArchClass:
Daniel Dunbar39176082009-03-20 00:20:03 +0000968 assert(0 && "Invalid tool kind.");
969 case Action::PreprocessJobClass:
970 T = new tools::gcc::Preprocess(*this); break;
971 case Action::PrecompileJobClass:
972 T = new tools::gcc::Precompile(*this); break;
973 case Action::AnalyzeJobClass:
974 T = new tools::Clang(*this); break;
975 case Action::CompileJobClass:
976 T = new tools::gcc::Compile(*this); break;
977 case Action::AssembleJobClass:
978 T = new tools::gcc::Assemble(*this); break;
979 case Action::LinkJobClass:
980 T = new tools::gcc::Link(*this); break;
Mike Stump1eb44332009-09-09 15:08:12 +0000981
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000982 // This is a bit ungeneric, but the only platform using a driver
983 // driver is Darwin.
984 case Action::LipoJobClass:
985 T = new tools::darwin::Lipo(*this); break;
Daniel Dunbar6e0f2542010-06-04 18:28:36 +0000986 case Action::DsymutilJobClass:
987 T = new tools::darwin::Dsymutil(*this); break;
Daniel Dunbar39176082009-03-20 00:20:03 +0000988 }
989 }
990
991 return *T;
992}
993
Daniel Dunbar39176082009-03-20 00:20:03 +0000994bool Generic_GCC::IsUnwindTablesDefault() const {
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000995 // FIXME: Gross; we should probably have some separate target
996 // definition, possibly even reusing the one in clang.
Daniel Dunbar39176082009-03-20 00:20:03 +0000997 return getArchName() == "x86_64";
998}
999
1000const char *Generic_GCC::GetDefaultRelocationModel() const {
1001 return "static";
1002}
1003
1004const char *Generic_GCC::GetForcedPicModel() const {
1005 return 0;
1006}
Daniel Dunbarf3cad362009-03-25 04:13:45 +00001007
Chris Lattner3a47c4e2010-03-04 21:07:38 +00001008/// TCEToolChain - A tool chain using the llvm bitcode tools to perform
1009/// all subcommands. See http://tce.cs.tut.fi for our peculiar target.
1010/// Currently does not support anything else but compilation.
1011
1012TCEToolChain::TCEToolChain(const HostInfo &Host, const llvm::Triple& Triple)
1013 : ToolChain(Host, Triple) {
1014 // Path mangling to find libexec
1015 std::string Path(getDriver().Dir);
1016
1017 Path += "/../libexec";
1018 getProgramPaths().push_back(Path);
1019}
1020
1021TCEToolChain::~TCEToolChain() {
1022 for (llvm::DenseMap<unsigned, Tool*>::iterator
1023 it = Tools.begin(), ie = Tools.end(); it != ie; ++it)
1024 delete it->second;
1025}
1026
1027bool TCEToolChain::IsMathErrnoDefault() const {
1028 return true;
1029}
1030
1031bool TCEToolChain::IsUnwindTablesDefault() const {
1032 return false;
1033}
1034
1035const char *TCEToolChain::GetDefaultRelocationModel() const {
1036 return "static";
1037}
1038
1039const char *TCEToolChain::GetForcedPicModel() const {
1040 return 0;
1041}
1042
1043Tool &TCEToolChain::SelectTool(const Compilation &C,
1044 const JobAction &JA) const {
1045 Action::ActionClass Key;
1046 Key = Action::AnalyzeJobClass;
1047
1048 Tool *&T = Tools[Key];
1049 if (!T) {
1050 switch (Key) {
1051 case Action::PreprocessJobClass:
1052 T = new tools::gcc::Preprocess(*this); break;
1053 case Action::AnalyzeJobClass:
1054 T = new tools::Clang(*this); break;
1055 default:
1056 assert(false && "Unsupported action for TCE target.");
1057 }
1058 }
1059 return *T;
1060}
1061
Daniel Dunbarf7b8eec2009-06-29 20:52:51 +00001062/// OpenBSD - OpenBSD tool chain which can call as(1) and ld(1) directly.
1063
1064OpenBSD::OpenBSD(const HostInfo &Host, const llvm::Triple& Triple)
Rafael Espindolae43cfa12010-10-29 20:14:02 +00001065 : Generic_ELF(Host, Triple) {
Daniel Dunbaree788e72009-12-21 18:54:17 +00001066 getFilePaths().push_back(getDriver().Dir + "/../lib");
Daniel Dunbarf7b8eec2009-06-29 20:52:51 +00001067 getFilePaths().push_back("/usr/lib");
1068}
1069
1070Tool &OpenBSD::SelectTool(const Compilation &C, const JobAction &JA) const {
1071 Action::ActionClass Key;
Daniel Dunbaree788e72009-12-21 18:54:17 +00001072 if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
Daniel Dunbarf7b8eec2009-06-29 20:52:51 +00001073 Key = Action::AnalyzeJobClass;
1074 else
1075 Key = JA.getKind();
1076
Rafael Espindoladda5b922010-11-07 23:13:01 +00001077 bool UseIntegratedAs = C.getArgs().hasFlag(options::OPT_integrated_as,
1078 options::OPT_no_integrated_as,
1079 IsIntegratedAssemblerDefault());
1080
Daniel Dunbarf7b8eec2009-06-29 20:52:51 +00001081 Tool *&T = Tools[Key];
1082 if (!T) {
1083 switch (Key) {
Rafael Espindoladda5b922010-11-07 23:13:01 +00001084 case Action::AssembleJobClass: {
1085 if (UseIntegratedAs)
1086 T = new tools::ClangAs(*this);
1087 else
1088 T = new tools::openbsd::Assemble(*this);
1089 break;
1090 }
Daniel Dunbarf7b8eec2009-06-29 20:52:51 +00001091 case Action::LinkJobClass:
1092 T = new tools::openbsd::Link(*this); break;
1093 default:
1094 T = &Generic_GCC::SelectTool(C, JA);
1095 }
1096 }
1097
1098 return *T;
1099}
1100
Daniel Dunbar75358d22009-03-30 21:06:03 +00001101/// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly.
1102
Daniel Dunbar214afe92010-08-02 05:43:59 +00001103FreeBSD::FreeBSD(const HostInfo &Host, const llvm::Triple& Triple)
Rafael Espindolae43cfa12010-10-29 20:14:02 +00001104 : Generic_ELF(Host, Triple) {
Daniel Dunbar214afe92010-08-02 05:43:59 +00001105
1106 // Determine if we are compiling 32-bit code on an x86_64 platform.
1107 bool Lib32 = false;
1108 if (Triple.getArch() == llvm::Triple::x86 &&
1109 llvm::Triple(getDriver().DefaultHostTriple).getArch() ==
1110 llvm::Triple::x86_64)
1111 Lib32 = true;
1112
Daniel Dunbarbc534662009-04-02 18:30:04 +00001113 if (Lib32) {
Daniel Dunbarbc534662009-04-02 18:30:04 +00001114 getFilePaths().push_back("/usr/lib32");
1115 } else {
Daniel Dunbarbc534662009-04-02 18:30:04 +00001116 getFilePaths().push_back("/usr/lib");
1117 }
Daniel Dunbar75358d22009-03-30 21:06:03 +00001118}
1119
1120Tool &FreeBSD::SelectTool(const Compilation &C, const JobAction &JA) const {
1121 Action::ActionClass Key;
Daniel Dunbaree788e72009-12-21 18:54:17 +00001122 if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
Daniel Dunbar75358d22009-03-30 21:06:03 +00001123 Key = Action::AnalyzeJobClass;
1124 else
1125 Key = JA.getKind();
1126
Roman Divacky67dece72010-11-08 17:46:39 +00001127 bool UseIntegratedAs = C.getArgs().hasFlag(options::OPT_integrated_as,
1128 options::OPT_no_integrated_as,
1129 IsIntegratedAssemblerDefault());
1130
Daniel Dunbar75358d22009-03-30 21:06:03 +00001131 Tool *&T = Tools[Key];
1132 if (!T) {
1133 switch (Key) {
Daniel Dunbar68a31d42009-03-31 17:45:15 +00001134 case Action::AssembleJobClass:
Roman Divacky67dece72010-11-08 17:46:39 +00001135 if (UseIntegratedAs)
1136 T = new tools::ClangAs(*this);
1137 else
1138 T = new tools::freebsd::Assemble(*this);
Roman Divackyfe3a7ea2010-11-08 19:39:10 +00001139 break;
Daniel Dunbar008f54a2009-04-01 19:36:32 +00001140 case Action::LinkJobClass:
1141 T = new tools::freebsd::Link(*this); break;
Daniel Dunbar75358d22009-03-30 21:06:03 +00001142 default:
1143 T = &Generic_GCC::SelectTool(C, JA);
1144 }
1145 }
1146
1147 return *T;
1148}
Daniel Dunbar11e1b402009-05-02 18:28:39 +00001149
Benjamin Kramer8e50a962011-02-02 18:59:27 +00001150/// NetBSD - NetBSD tool chain which can call as(1) and ld(1) directly.
1151
1152NetBSD::NetBSD(const HostInfo &Host, const llvm::Triple& Triple)
1153 : Generic_ELF(Host, Triple) {
1154
1155 // Determine if we are compiling 32-bit code on an x86_64 platform.
1156 bool Lib32 = false;
1157 if (Triple.getArch() == llvm::Triple::x86 &&
1158 llvm::Triple(getDriver().DefaultHostTriple).getArch() ==
1159 llvm::Triple::x86_64)
1160 Lib32 = true;
1161
1162 getProgramPaths().push_back(getDriver().Dir + "/../libexec");
1163 getProgramPaths().push_back("/usr/libexec");
1164 if (Lib32) {
1165 getFilePaths().push_back("/usr/lib/i386");
1166 } else {
1167 getFilePaths().push_back("/usr/lib");
1168 }
1169}
1170
1171Tool &NetBSD::SelectTool(const Compilation &C, const JobAction &JA) const {
1172 Action::ActionClass Key;
1173 if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
1174 Key = Action::AnalyzeJobClass;
1175 else
1176 Key = JA.getKind();
1177
1178 bool UseIntegratedAs = C.getArgs().hasFlag(options::OPT_integrated_as,
1179 options::OPT_no_integrated_as,
1180 IsIntegratedAssemblerDefault());
1181
1182 Tool *&T = Tools[Key];
1183 if (!T) {
1184 switch (Key) {
1185 case Action::AssembleJobClass:
1186 if (UseIntegratedAs)
1187 T = new tools::ClangAs(*this);
1188 else
1189 T = new tools::netbsd::Assemble(*this);
1190 break;
1191 case Action::LinkJobClass:
1192 T = new tools::netbsd::Link(*this); break;
1193 default:
1194 T = &Generic_GCC::SelectTool(C, JA);
1195 }
1196 }
1197
1198 return *T;
1199}
1200
Chris Lattner38e317d2010-07-07 16:01:42 +00001201/// Minix - Minix tool chain which can call as(1) and ld(1) directly.
1202
1203Minix::Minix(const HostInfo &Host, const llvm::Triple& Triple)
1204 : Generic_GCC(Host, Triple) {
1205 getFilePaths().push_back(getDriver().Dir + "/../lib");
1206 getFilePaths().push_back("/usr/lib");
1207 getFilePaths().push_back("/usr/gnu/lib");
1208 getFilePaths().push_back("/usr/gnu/lib/gcc/i686-pc-minix/4.4.3");
1209}
1210
1211Tool &Minix::SelectTool(const Compilation &C, const JobAction &JA) const {
1212 Action::ActionClass Key;
1213 if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
1214 Key = Action::AnalyzeJobClass;
1215 else
1216 Key = JA.getKind();
1217
1218 Tool *&T = Tools[Key];
1219 if (!T) {
1220 switch (Key) {
1221 case Action::AssembleJobClass:
1222 T = new tools::minix::Assemble(*this); break;
1223 case Action::LinkJobClass:
1224 T = new tools::minix::Link(*this); break;
1225 default:
1226 T = &Generic_GCC::SelectTool(C, JA);
1227 }
1228 }
1229
1230 return *T;
1231}
1232
Edward O'Callaghane7925a02009-08-22 01:06:46 +00001233/// AuroraUX - AuroraUX tool chain which can call as(1) and ld(1) directly.
1234
1235AuroraUX::AuroraUX(const HostInfo &Host, const llvm::Triple& Triple)
1236 : Generic_GCC(Host, Triple) {
1237
Daniel Dunbaredf29b02010-08-01 22:29:51 +00001238 getProgramPaths().push_back(getDriver().getInstalledDir());
Benjamin Kramer86643b82011-03-01 22:50:47 +00001239 if (getDriver().getInstalledDir() != getDriver().Dir)
Daniel Dunbaredf29b02010-08-01 22:29:51 +00001240 getProgramPaths().push_back(getDriver().Dir);
Edward O'Callaghane7925a02009-08-22 01:06:46 +00001241
Daniel Dunbaree788e72009-12-21 18:54:17 +00001242 getFilePaths().push_back(getDriver().Dir + "/../lib");
Edward O'Callaghane7925a02009-08-22 01:06:46 +00001243 getFilePaths().push_back("/usr/lib");
1244 getFilePaths().push_back("/usr/sfw/lib");
1245 getFilePaths().push_back("/opt/gcc4/lib");
Edward O'Callaghan7adf9492009-10-15 07:44:07 +00001246 getFilePaths().push_back("/opt/gcc4/lib/gcc/i386-pc-solaris2.11/4.2.4");
Edward O'Callaghane7925a02009-08-22 01:06:46 +00001247
1248}
1249
1250Tool &AuroraUX::SelectTool(const Compilation &C, const JobAction &JA) const {
1251 Action::ActionClass Key;
Daniel Dunbaree788e72009-12-21 18:54:17 +00001252 if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
Edward O'Callaghane7925a02009-08-22 01:06:46 +00001253 Key = Action::AnalyzeJobClass;
1254 else
1255 Key = JA.getKind();
1256
1257 Tool *&T = Tools[Key];
1258 if (!T) {
1259 switch (Key) {
1260 case Action::AssembleJobClass:
1261 T = new tools::auroraux::Assemble(*this); break;
1262 case Action::LinkJobClass:
1263 T = new tools::auroraux::Link(*this); break;
1264 default:
1265 T = &Generic_GCC::SelectTool(C, JA);
1266 }
1267 }
1268
1269 return *T;
1270}
1271
1272
Eli Friedman6b3454a2009-05-26 07:52:18 +00001273/// Linux toolchain (very bare-bones at the moment).
1274
Rafael Espindolac1da9812010-11-07 20:14:31 +00001275enum LinuxDistro {
Chandler Carruth3fd345a2011-02-25 06:39:53 +00001276 ArchLinux,
Rafael Espindolac1da9812010-11-07 20:14:31 +00001277 DebianLenny,
1278 DebianSqueeze,
Rafael Espindola0a84aee2010-11-11 02:07:13 +00001279 Exherbo,
Rafael Espindolac1da9812010-11-07 20:14:31 +00001280 Fedora13,
1281 Fedora14,
1282 OpenSuse11_3,
Douglas Gregor814638e2011-03-14 15:39:50 +00001283 UbuntuHardy,
1284 UbuntuIntrepid,
Rafael Espindola021aaa42010-11-10 05:00:22 +00001285 UbuntuJaunty,
Zhongxing Xu5ede8072010-11-15 09:01:52 +00001286 UbuntuKarmic,
Rafael Espindolac1da9812010-11-07 20:14:31 +00001287 UbuntuLucid,
1288 UbuntuMaverick,
1289 UnknownDistro
1290};
1291
1292static bool IsFedora(enum LinuxDistro Distro) {
1293 return Distro == Fedora13 || Distro == Fedora14;
1294}
1295
1296static bool IsOpenSuse(enum LinuxDistro Distro) {
1297 return Distro == OpenSuse11_3;
1298}
1299
1300static bool IsDebian(enum LinuxDistro Distro) {
1301 return Distro == DebianLenny || Distro == DebianSqueeze;
1302}
1303
1304static bool IsUbuntu(enum LinuxDistro Distro) {
Douglas Gregor814638e2011-03-14 15:39:50 +00001305 return Distro == UbuntuHardy || Distro == UbuntuIntrepid ||
1306 Distro == UbuntuLucid || Distro == UbuntuMaverick ||
Zhongxing Xu5ede8072010-11-15 09:01:52 +00001307 Distro == UbuntuJaunty || Distro == UbuntuKarmic;
Rafael Espindolac1da9812010-11-07 20:14:31 +00001308}
1309
1310static bool IsDebianBased(enum LinuxDistro Distro) {
1311 return IsDebian(Distro) || IsUbuntu(Distro);
1312}
1313
1314static bool HasMultilib(llvm::Triple::ArchType Arch, enum LinuxDistro Distro) {
Rafael Espindola0a84aee2010-11-11 02:07:13 +00001315 if (Arch == llvm::Triple::x86_64) {
Michael J. Spencer32bef4e2011-01-10 02:34:13 +00001316 bool Exists;
1317 if (Distro == Exherbo &&
1318 (llvm::sys::fs::exists("/usr/lib32/libc.so", Exists) || !Exists))
Rafael Espindola0a84aee2010-11-11 02:07:13 +00001319 return false;
1320
Rafael Espindolac1da9812010-11-07 20:14:31 +00001321 return true;
Rafael Espindola0a84aee2010-11-11 02:07:13 +00001322 }
Rafael Espindolac1da9812010-11-07 20:14:31 +00001323 if (Arch == llvm::Triple::x86 && IsDebianBased(Distro))
1324 return true;
1325 return false;
1326}
1327
1328static LinuxDistro DetectLinuxDistro(llvm::Triple::ArchType Arch) {
Michael J. Spencer4eeebc42010-12-16 03:28:14 +00001329 llvm::OwningPtr<llvm::MemoryBuffer> File;
1330 if (!llvm::MemoryBuffer::getFile("/etc/lsb-release", File)) {
1331 llvm::StringRef Data = File.get()->getBuffer();
Rafael Espindolac1da9812010-11-07 20:14:31 +00001332 llvm::SmallVector<llvm::StringRef, 8> Lines;
1333 Data.split(Lines, "\n");
1334 for (unsigned int i = 0, s = Lines.size(); i < s; ++ i) {
Douglas Gregor814638e2011-03-14 15:39:50 +00001335 if (Lines[i] == "DISTRIB_CODENAME=hardy")
1336 return UbuntuHardy;
1337 if (Lines[i] == "DISTRIB_CODENAME=intrepid")
1338 return UbuntuIntrepid;
Rafael Espindolac1da9812010-11-07 20:14:31 +00001339 if (Lines[i] == "DISTRIB_CODENAME=maverick")
1340 return UbuntuMaverick;
1341 else if (Lines[i] == "DISTRIB_CODENAME=lucid")
1342 return UbuntuLucid;
Rafael Espindola021aaa42010-11-10 05:00:22 +00001343 else if (Lines[i] == "DISTRIB_CODENAME=jaunty")
Michael J. Spencer4eeebc42010-12-16 03:28:14 +00001344 return UbuntuJaunty;
Zhongxing Xu5ede8072010-11-15 09:01:52 +00001345 else if (Lines[i] == "DISTRIB_CODENAME=karmic")
1346 return UbuntuKarmic;
Rafael Espindolac1da9812010-11-07 20:14:31 +00001347 }
1348 return UnknownDistro;
1349 }
1350
Michael J. Spencer4eeebc42010-12-16 03:28:14 +00001351 if (!llvm::MemoryBuffer::getFile("/etc/redhat-release", File)) {
1352 llvm::StringRef Data = File.get()->getBuffer();
Rafael Espindolac1da9812010-11-07 20:14:31 +00001353 if (Data.startswith("Fedora release 14 (Laughlin)"))
1354 return Fedora14;
1355 else if (Data.startswith("Fedora release 13 (Goddard)"))
1356 return Fedora13;
1357 return UnknownDistro;
1358 }
1359
Michael J. Spencer4eeebc42010-12-16 03:28:14 +00001360 if (!llvm::MemoryBuffer::getFile("/etc/debian_version", File)) {
1361 llvm::StringRef Data = File.get()->getBuffer();
Rafael Espindolac1da9812010-11-07 20:14:31 +00001362 if (Data[0] == '5')
1363 return DebianLenny;
1364 else if (Data.startswith("squeeze/sid"))
1365 return DebianSqueeze;
1366 return UnknownDistro;
1367 }
1368
Michael J. Spencer4eeebc42010-12-16 03:28:14 +00001369 if (!llvm::MemoryBuffer::getFile("/etc/SuSE-release", File)) {
1370 llvm::StringRef Data = File.get()->getBuffer();
Rafael Espindolac1da9812010-11-07 20:14:31 +00001371 if (Data.startswith("openSUSE 11.3"))
1372 return OpenSuse11_3;
1373 return UnknownDistro;
1374 }
1375
Michael J. Spencer32bef4e2011-01-10 02:34:13 +00001376 bool Exists;
1377 if (!llvm::sys::fs::exists("/etc/exherbo-release", Exists) && Exists)
Rafael Espindola0a84aee2010-11-11 02:07:13 +00001378 return Exherbo;
1379
Chandler Carruth3fd345a2011-02-25 06:39:53 +00001380 if (!llvm::sys::fs::exists("/etc/arch-release", Exists) && Exists)
1381 return ArchLinux;
1382
Rafael Espindolac1da9812010-11-07 20:14:31 +00001383 return UnknownDistro;
1384}
1385
Nick Lewycky3fdcc6f2010-12-31 17:31:54 +00001386Linux::Linux(const HostInfo &Host, const llvm::Triple &Triple)
Rafael Espindolae43cfa12010-10-29 20:14:02 +00001387 : Generic_ELF(Host, Triple) {
Rafael Espindolac1da9812010-11-07 20:14:31 +00001388 llvm::Triple::ArchType Arch =
1389 llvm::Triple(getDriver().DefaultHostTriple).getArch();
Daniel Dunbara9822de2009-08-06 01:47:11 +00001390
Rafael Espindolac1da9812010-11-07 20:14:31 +00001391 std::string Suffix32 = "";
1392 if (Arch == llvm::Triple::x86_64)
1393 Suffix32 = "/32";
Daniel Dunbara9822de2009-08-06 01:47:11 +00001394
Rafael Espindolac1da9812010-11-07 20:14:31 +00001395 std::string Suffix64 = "";
1396 if (Arch == llvm::Triple::x86)
1397 Suffix64 = "/64";
1398
1399 std::string Lib32 = "lib";
1400
Michael J. Spencer32bef4e2011-01-10 02:34:13 +00001401 bool Exists;
1402 if (!llvm::sys::fs::exists("/lib32", Exists) && Exists)
Rafael Espindolac1da9812010-11-07 20:14:31 +00001403 Lib32 = "lib32";
1404
1405 std::string Lib64 = "lib";
Michael J. Spencer2dea7c72011-01-12 23:54:48 +00001406 bool Symlink;
Chris Lattner48aef362011-01-13 01:35:58 +00001407 if (!llvm::sys::fs::exists("/lib64", Exists) && Exists &&
1408 (llvm::sys::fs::is_symlink("/lib64", Symlink) || !Symlink))
Rafael Espindolac1da9812010-11-07 20:14:31 +00001409 Lib64 = "lib64";
1410
1411 std::string GccTriple = "";
Douglas Gregorf0594d82011-03-06 19:11:49 +00001412 if (Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb) {
Michael J. Spencer32bef4e2011-01-10 02:34:13 +00001413 if (!llvm::sys::fs::exists("/usr/lib/gcc/arm-linux-gnueabi", Exists) &&
1414 Exists)
Rafael Espindolac1da9812010-11-07 20:14:31 +00001415 GccTriple = "arm-linux-gnueabi";
1416 } else if (Arch == llvm::Triple::x86_64) {
Michael J. Spencer32bef4e2011-01-10 02:34:13 +00001417 if (!llvm::sys::fs::exists("/usr/lib/gcc/x86_64-linux-gnu", Exists) &&
1418 Exists)
Rafael Espindolac1da9812010-11-07 20:14:31 +00001419 GccTriple = "x86_64-linux-gnu";
Michael J. Spencer32bef4e2011-01-10 02:34:13 +00001420 else if (!llvm::sys::fs::exists("/usr/lib/gcc/x86_64-unknown-linux-gnu",
1421 Exists) && Exists)
Rafael Espindola53dd00b2010-11-17 00:25:26 +00001422 GccTriple = "x86_64-unknown-linux-gnu";
Michael J. Spencer32bef4e2011-01-10 02:34:13 +00001423 else if (!llvm::sys::fs::exists("/usr/lib/gcc/x86_64-pc-linux-gnu",
1424 Exists) && Exists)
Rafael Espindola0a84aee2010-11-11 02:07:13 +00001425 GccTriple = "x86_64-pc-linux-gnu";
Michael J. Spencer32bef4e2011-01-10 02:34:13 +00001426 else if (!llvm::sys::fs::exists("/usr/lib/gcc/x86_64-redhat-linux",
1427 Exists) && Exists)
Rafael Espindolac1da9812010-11-07 20:14:31 +00001428 GccTriple = "x86_64-redhat-linux";
Michael J. Spencer32bef4e2011-01-10 02:34:13 +00001429 else if (!llvm::sys::fs::exists("/usr/lib64/gcc/x86_64-suse-linux",
1430 Exists) && Exists)
Rafael Espindolac1da9812010-11-07 20:14:31 +00001431 GccTriple = "x86_64-suse-linux";
Nick Lewyckye10f9002011-02-01 23:03:29 +00001432 else if (!llvm::sys::fs::exists("/usr/lib/gcc/x86_64-manbo-linux-gnu",
1433 Exists) && Exists)
1434 GccTriple = "x86_64-manbo-linux-gnu";
Rafael Espindolac1da9812010-11-07 20:14:31 +00001435 } else if (Arch == llvm::Triple::x86) {
Michael J. Spencer32bef4e2011-01-10 02:34:13 +00001436 if (!llvm::sys::fs::exists("/usr/lib/gcc/i686-linux-gnu", Exists) && Exists)
Rafael Espindolac1da9812010-11-07 20:14:31 +00001437 GccTriple = "i686-linux-gnu";
Michael J. Spencer32bef4e2011-01-10 02:34:13 +00001438 else if (!llvm::sys::fs::exists("/usr/lib/gcc/i686-pc-linux-gnu", Exists) &&
1439 Exists)
Nuno Lopes2a69ddd2010-11-19 17:26:57 +00001440 GccTriple = "i686-pc-linux-gnu";
Michael J. Spencer32bef4e2011-01-10 02:34:13 +00001441 else if (!llvm::sys::fs::exists("/usr/lib/gcc/i486-linux-gnu", Exists) &&
1442 Exists)
Rafael Espindolac1da9812010-11-07 20:14:31 +00001443 GccTriple = "i486-linux-gnu";
Michael J. Spencer32bef4e2011-01-10 02:34:13 +00001444 else if (!llvm::sys::fs::exists("/usr/lib/gcc/i686-redhat-linux", Exists) &&
1445 Exists)
Rafael Espindolac1da9812010-11-07 20:14:31 +00001446 GccTriple = "i686-redhat-linux";
Michael J. Spencer32bef4e2011-01-10 02:34:13 +00001447 else if (!llvm::sys::fs::exists("/usr/lib/gcc/i586-suse-linux", Exists) &&
1448 Exists)
Rafael Espindolac1da9812010-11-07 20:14:31 +00001449 GccTriple = "i586-suse-linux";
1450 }
1451
Chandler Carruth3fd345a2011-02-25 06:39:53 +00001452 const char* GccVersions[] = {"4.5.2", "4.5.1", "4.5", "4.4.5", "4.4.4",
1453 "4.4.3", "4.4", "4.3.4", "4.3.3", "4.3.2",
Douglas Gregor814638e2011-03-14 15:39:50 +00001454 "4.3", "4.2.4", "4.2.3", "4.2.2", "4.2.1",
1455 "4.2"};
Rafael Espindolac1da9812010-11-07 20:14:31 +00001456 std::string Base = "";
1457 for (unsigned i = 0; i < sizeof(GccVersions)/sizeof(char*); ++i) {
1458 std::string Suffix = GccTriple + "/" + GccVersions[i];
1459 std::string t1 = "/usr/lib/gcc/" + Suffix;
Michael J. Spencer32bef4e2011-01-10 02:34:13 +00001460 if (!llvm::sys::fs::exists(t1 + "/crtbegin.o", Exists) && Exists) {
Rafael Espindolac1da9812010-11-07 20:14:31 +00001461 Base = t1;
1462 break;
1463 }
1464 std::string t2 = "/usr/lib64/gcc/" + Suffix;
Michael J. Spencer32bef4e2011-01-10 02:34:13 +00001465 if (!llvm::sys::fs::exists(t2 + "/crtbegin.o", Exists) && Exists) {
Rafael Espindolac1da9812010-11-07 20:14:31 +00001466 Base = t2;
1467 break;
1468 }
1469 }
1470
1471 path_list &Paths = getFilePaths();
1472 bool Is32Bits = getArch() == llvm::Triple::x86;
1473
1474 std::string Suffix;
1475 std::string Lib;
1476
1477 if (Is32Bits) {
1478 Suffix = Suffix32;
1479 Lib = Lib32;
1480 } else {
1481 Suffix = Suffix64;
1482 Lib = Lib64;
1483 }
1484
1485 llvm::sys::Path LinkerPath(Base + "/../../../../" + GccTriple + "/bin/ld");
Michael J. Spencer32bef4e2011-01-10 02:34:13 +00001486 if (!llvm::sys::fs::exists(LinkerPath.str(), Exists) && Exists)
Rafael Espindolac1da9812010-11-07 20:14:31 +00001487 Linker = LinkerPath.str();
1488 else
1489 Linker = GetProgramPath("ld");
1490
1491 LinuxDistro Distro = DetectLinuxDistro(Arch);
1492
Rafael Espindola94c80222010-11-08 14:48:47 +00001493 if (IsUbuntu(Distro)) {
1494 ExtraOpts.push_back("-z");
1495 ExtraOpts.push_back("relro");
1496 }
Rafael Espindolac1da9812010-11-07 20:14:31 +00001497
Douglas Gregorf0594d82011-03-06 19:11:49 +00001498 if (Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb)
Rafael Espindolac1da9812010-11-07 20:14:31 +00001499 ExtraOpts.push_back("-X");
1500
1501 if (IsFedora(Distro) || Distro == UbuntuMaverick)
1502 ExtraOpts.push_back("--hash-style=gnu");
1503
Zhongxing Xu5ede8072010-11-15 09:01:52 +00001504 if (IsDebian(Distro) || Distro == UbuntuLucid || Distro == UbuntuJaunty ||
1505 Distro == UbuntuKarmic)
Rafael Espindolac1da9812010-11-07 20:14:31 +00001506 ExtraOpts.push_back("--hash-style=both");
1507
1508 if (IsFedora(Distro))
1509 ExtraOpts.push_back("--no-add-needed");
1510
Rafael Espindola021aaa42010-11-10 05:00:22 +00001511 if (Distro == DebianSqueeze || IsOpenSuse(Distro) ||
Zhongxing Xu5ede8072010-11-15 09:01:52 +00001512 IsFedora(Distro) || Distro == UbuntuLucid || Distro == UbuntuMaverick ||
1513 Distro == UbuntuKarmic)
Rafael Espindolac1da9812010-11-07 20:14:31 +00001514 ExtraOpts.push_back("--build-id");
1515
Chandler Carruth3fd345a2011-02-25 06:39:53 +00001516 if (Distro == ArchLinux)
1517 Lib = "lib";
1518
Rafael Espindolac1da9812010-11-07 20:14:31 +00001519 Paths.push_back(Base + Suffix);
1520 if (HasMultilib(Arch, Distro)) {
1521 if (IsOpenSuse(Distro) && Is32Bits)
1522 Paths.push_back(Base + "/../../../../" + GccTriple + "/lib/../lib");
1523 Paths.push_back(Base + "/../../../../" + Lib);
1524 Paths.push_back("/lib/../" + Lib);
1525 Paths.push_back("/usr/lib/../" + Lib);
1526 }
1527 if (!Suffix.empty())
1528 Paths.push_back(Base);
1529 if (IsOpenSuse(Distro))
1530 Paths.push_back(Base + "/../../../../" + GccTriple + "/lib");
1531 Paths.push_back(Base + "/../../..");
1532 if (Arch == getArch() && IsUbuntu(Distro))
1533 Paths.push_back("/usr/lib/" + GccTriple);
1534}
1535
1536bool Linux::HasNativeLLVMSupport() const {
1537 return true;
Eli Friedman6b3454a2009-05-26 07:52:18 +00001538}
1539
Rafael Espindolaba30bbe2010-08-10 00:25:48 +00001540Tool &Linux::SelectTool(const Compilation &C, const JobAction &JA) const {
1541 Action::ActionClass Key;
1542 if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
1543 Key = Action::AnalyzeJobClass;
1544 else
1545 Key = JA.getKind();
1546
Rafael Espindoladda5b922010-11-07 23:13:01 +00001547 bool UseIntegratedAs = C.getArgs().hasFlag(options::OPT_integrated_as,
1548 options::OPT_no_integrated_as,
1549 IsIntegratedAssemblerDefault());
1550
Rafael Espindolaba30bbe2010-08-10 00:25:48 +00001551 Tool *&T = Tools[Key];
1552 if (!T) {
1553 switch (Key) {
1554 case Action::AssembleJobClass:
Rafael Espindoladda5b922010-11-07 23:13:01 +00001555 if (UseIntegratedAs)
1556 T = new tools::ClangAs(*this);
1557 else
1558 T = new tools::linuxtools::Assemble(*this);
1559 break;
Rafael Espindolac1da9812010-11-07 20:14:31 +00001560 case Action::LinkJobClass:
1561 T = new tools::linuxtools::Link(*this); break;
Rafael Espindolaba30bbe2010-08-10 00:25:48 +00001562 default:
1563 T = &Generic_GCC::SelectTool(C, JA);
1564 }
1565 }
1566
1567 return *T;
1568}
1569
Daniel Dunbar11e1b402009-05-02 18:28:39 +00001570/// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly.
1571
Daniel Dunbarcb8ab232009-05-22 02:53:45 +00001572DragonFly::DragonFly(const HostInfo &Host, const llvm::Triple& Triple)
Rafael Espindolae43cfa12010-10-29 20:14:02 +00001573 : Generic_ELF(Host, Triple) {
Daniel Dunbar11e1b402009-05-02 18:28:39 +00001574
1575 // Path mangling to find libexec
Daniel Dunbaredf29b02010-08-01 22:29:51 +00001576 getProgramPaths().push_back(getDriver().getInstalledDir());
Benjamin Kramer86643b82011-03-01 22:50:47 +00001577 if (getDriver().getInstalledDir() != getDriver().Dir)
Daniel Dunbaredf29b02010-08-01 22:29:51 +00001578 getProgramPaths().push_back(getDriver().Dir);
Daniel Dunbar11e1b402009-05-02 18:28:39 +00001579
Daniel Dunbaree788e72009-12-21 18:54:17 +00001580 getFilePaths().push_back(getDriver().Dir + "/../lib");
Daniel Dunbar11e1b402009-05-02 18:28:39 +00001581 getFilePaths().push_back("/usr/lib");
1582 getFilePaths().push_back("/usr/lib/gcc41");
1583}
1584
1585Tool &DragonFly::SelectTool(const Compilation &C, const JobAction &JA) const {
1586 Action::ActionClass Key;
Daniel Dunbaree788e72009-12-21 18:54:17 +00001587 if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
Daniel Dunbar11e1b402009-05-02 18:28:39 +00001588 Key = Action::AnalyzeJobClass;
1589 else
1590 Key = JA.getKind();
1591
1592 Tool *&T = Tools[Key];
1593 if (!T) {
1594 switch (Key) {
1595 case Action::AssembleJobClass:
1596 T = new tools::dragonfly::Assemble(*this); break;
1597 case Action::LinkJobClass:
1598 T = new tools::dragonfly::Link(*this); break;
1599 default:
1600 T = &Generic_GCC::SelectTool(C, JA);
1601 }
1602 }
1603
1604 return *T;
1605}
Michael J. Spencerff58e362010-08-21 21:55:07 +00001606
1607Windows::Windows(const HostInfo &Host, const llvm::Triple& Triple)
1608 : ToolChain(Host, Triple) {
1609}
1610
1611Tool &Windows::SelectTool(const Compilation &C, const JobAction &JA) const {
1612 Action::ActionClass Key;
1613 if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
1614 Key = Action::AnalyzeJobClass;
1615 else
1616 Key = JA.getKind();
1617
1618 Tool *&T = Tools[Key];
1619 if (!T) {
1620 switch (Key) {
1621 case Action::InputClass:
1622 case Action::BindArchClass:
Chandler Carruthe97673f2010-08-22 06:56:37 +00001623 case Action::LipoJobClass:
1624 case Action::DsymutilJobClass:
Michael J. Spencerff58e362010-08-21 21:55:07 +00001625 assert(0 && "Invalid tool kind.");
1626 case Action::PreprocessJobClass:
1627 case Action::PrecompileJobClass:
1628 case Action::AnalyzeJobClass:
1629 case Action::CompileJobClass:
1630 T = new tools::Clang(*this); break;
1631 case Action::AssembleJobClass:
1632 T = new tools::ClangAs(*this); break;
1633 case Action::LinkJobClass:
1634 T = new tools::visualstudio::Link(*this); break;
1635 }
1636 }
1637
1638 return *T;
1639}
1640
1641bool Windows::IsIntegratedAssemblerDefault() const {
1642 return true;
1643}
1644
1645bool Windows::IsUnwindTablesDefault() const {
1646 // FIXME: Gross; we should probably have some separate target
1647 // definition, possibly even reusing the one in clang.
1648 return getArchName() == "x86_64";
1649}
1650
1651const char *Windows::GetDefaultRelocationModel() const {
1652 return "static";
1653}
1654
1655const char *Windows::GetForcedPicModel() const {
1656 if (getArchName() == "x86_64")
1657 return "pic";
1658 return 0;
1659}