blob: 9af6263319ed7df662e1df96ace3bb1b93b859bc [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 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"
Rafael Espindolac1da9812010-11-07 20:14:31 +000026#include "llvm/Support/MemoryBuffer.h"
Daniel Dunbarec069ed2009-03-25 06:58:31 +000027#include "llvm/Support/raw_ostream.h"
Michael J. Spencer03013fa2010-11-29 18:12:39 +000028#include "llvm/Support/Path.h"
Michael J. Spencer3a321e22010-12-09 17:36:38 +000029#include "llvm/Support/system_error.h"
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000030
Daniel Dunbarf36a06a2009-04-10 21:00:07 +000031#include <cstdlib> // ::getenv
32
Daniel Dunbar39176082009-03-20 00:20:03 +000033using namespace clang::driver;
34using namespace clang::driver::toolchains;
35
Daniel Dunbarf3955282009-09-04 18:34:51 +000036/// Darwin - Darwin tool chain for i386 and x86_64.
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +000037
Daniel Dunbar25b58eb2010-08-02 05:44:07 +000038Darwin::Darwin(const HostInfo &Host, const llvm::Triple& Triple)
Daniel Dunbarcc8e1892010-01-27 00:56:44 +000039 : ToolChain(Host, Triple), TargetInitialized(false)
Daniel Dunbar1d4612b2009-09-18 08:15:13 +000040{
Daniel Dunbar25b58eb2010-08-02 05:44:07 +000041 // Compute the initial Darwin version based on the host.
42 bool HadExtra;
43 std::string OSName = Triple.getOSName();
44 if (!Driver::GetReleaseVersion(&OSName[6],
45 DarwinVersion[0], DarwinVersion[1],
46 DarwinVersion[2], HadExtra))
47 getDriver().Diag(clang::diag::err_drv_invalid_darwin_version) << OSName;
48
Daniel Dunbar02633b52009-03-26 16:23:12 +000049 llvm::raw_string_ostream(MacosxVersionMin)
Daniel Dunbar25b58eb2010-08-02 05:44:07 +000050 << "10." << std::max(0, (int)DarwinVersion[0] - 4) << '.'
51 << DarwinVersion[1];
Daniel Dunbar1d4612b2009-09-18 08:15:13 +000052}
53
Daniel Dunbar41800112010-08-02 05:43:56 +000054types::ID Darwin::LookupTypeForExtension(const char *Ext) const {
55 types::ID Ty = types::lookupTypeForExtension(Ext);
56
57 // Darwin always preprocesses assembly files (unless -x is used explicitly).
58 if (Ty == types::TY_PP_Asm)
59 return types::TY_Asm;
60
61 return Ty;
62}
63
Daniel Dunbarb993f5d2010-09-17 00:24:52 +000064bool Darwin::HasNativeLLVMSupport() const {
65 return true;
66}
67
Daniel Dunbareeff4062010-01-22 02:04:58 +000068// FIXME: Can we tablegen this?
69static const char *GetArmArchForMArch(llvm::StringRef Value) {
70 if (Value == "armv6k")
71 return "armv6";
72
73 if (Value == "armv5tej")
74 return "armv5";
75
76 if (Value == "xscale")
77 return "xscale";
78
79 if (Value == "armv4t")
80 return "armv4t";
81
82 if (Value == "armv7" || Value == "armv7-a" || Value == "armv7-r" ||
83 Value == "armv7-m" || Value == "armv7a" || Value == "armv7r" ||
84 Value == "armv7m")
85 return "armv7";
86
87 return 0;
88}
89
90// FIXME: Can we tablegen this?
91static const char *GetArmArchForMCpu(llvm::StringRef Value) {
92 if (Value == "arm10tdmi" || Value == "arm1020t" || Value == "arm9e" ||
93 Value == "arm946e-s" || Value == "arm966e-s" ||
94 Value == "arm968e-s" || Value == "arm10e" ||
95 Value == "arm1020e" || Value == "arm1022e" || Value == "arm926ej-s" ||
96 Value == "arm1026ej-s")
97 return "armv5";
98
99 if (Value == "xscale")
100 return "xscale";
101
102 if (Value == "arm1136j-s" || Value == "arm1136jf-s" ||
103 Value == "arm1176jz-s" || Value == "arm1176jzf-s")
104 return "armv6";
105
106 if (Value == "cortex-a8" || Value == "cortex-r4" || Value == "cortex-m3")
107 return "armv7";
108
109 return 0;
110}
111
112llvm::StringRef Darwin::getDarwinArchName(const ArgList &Args) const {
113 switch (getTriple().getArch()) {
114 default:
115 return getArchName();
116
117 case llvm::Triple::arm: {
118 if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
119 if (const char *Arch = GetArmArchForMArch(A->getValue(Args)))
120 return Arch;
121
122 if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
123 if (const char *Arch = GetArmArchForMCpu(A->getValue(Args)))
124 return Arch;
125
126 return "arm";
127 }
128 }
129}
130
Daniel Dunbar25b58eb2010-08-02 05:44:07 +0000131DarwinGCC::DarwinGCC(const HostInfo &Host, const llvm::Triple& Triple)
132 : Darwin(Host, Triple)
Daniel Dunbar1d4612b2009-09-18 08:15:13 +0000133{
Daniel Dunbarc2bda622010-08-02 05:44:01 +0000134 // We can only work with 4.2.1 currently.
135 GCCVersion[0] = 4;
136 GCCVersion[1] = 2;
137 GCCVersion[2] = 1;
Daniel Dunbar1d4612b2009-09-18 08:15:13 +0000138
139 // Set up the tool chain paths to match gcc.
Daniel Dunbarc50b00d2009-03-23 16:15:50 +0000140 ToolChainDir = "i686-apple-darwin";
Ted Kremenek55bac532009-10-07 03:21:11 +0000141 ToolChainDir += llvm::utostr(DarwinVersion[0]);
Daniel Dunbarc50b00d2009-03-23 16:15:50 +0000142 ToolChainDir += "/";
143 ToolChainDir += llvm::utostr(GCCVersion[0]);
144 ToolChainDir += '.';
145 ToolChainDir += llvm::utostr(GCCVersion[1]);
146 ToolChainDir += '.';
147 ToolChainDir += llvm::utostr(GCCVersion[2]);
148
Daniel Dunbar74782b02009-10-20 19:25:43 +0000149 // Try the next major version if that tool chain dir is invalid.
Daniel Dunbar080fb192009-10-22 00:12:00 +0000150 std::string Tmp = "/usr/lib/gcc/" + ToolChainDir;
151 if (!llvm::sys::Path(Tmp).exists()) {
Daniel Dunbar74782b02009-10-20 19:25:43 +0000152 std::string Next = "i686-apple-darwin";
153 Next += llvm::utostr(DarwinVersion[0] + 1);
154 Next += "/";
155 Next += llvm::utostr(GCCVersion[0]);
156 Next += '.';
157 Next += llvm::utostr(GCCVersion[1]);
158 Next += '.';
159 Next += llvm::utostr(GCCVersion[2]);
160
161 // Use that if it exists, otherwise hope the user isn't linking.
162 //
163 // FIXME: Drop dependency on gcc's tool chain.
Daniel Dunbar080fb192009-10-22 00:12:00 +0000164 Tmp = "/usr/lib/gcc/" + Next;
165 if (llvm::sys::Path(Tmp).exists())
Daniel Dunbar74782b02009-10-20 19:25:43 +0000166 ToolChainDir = Next;
167 }
168
Daniel Dunbarc50b00d2009-03-23 16:15:50 +0000169 std::string Path;
170 if (getArchName() == "x86_64") {
Daniel Dunbaree788e72009-12-21 18:54:17 +0000171 Path = getDriver().Dir;
Daniel Dunbarc50b00d2009-03-23 16:15:50 +0000172 Path += "/../lib/gcc/";
Daniel Dunbar6b200b22009-09-18 08:14:36 +0000173 Path += ToolChainDir;
Daniel Dunbarc50b00d2009-03-23 16:15:50 +0000174 Path += "/x86_64";
175 getFilePaths().push_back(Path);
176
177 Path = "/usr/lib/gcc/";
Daniel Dunbar6b200b22009-09-18 08:14:36 +0000178 Path += ToolChainDir;
Daniel Dunbarc50b00d2009-03-23 16:15:50 +0000179 Path += "/x86_64";
180 getFilePaths().push_back(Path);
181 }
Mike Stump1eb44332009-09-09 15:08:12 +0000182
Daniel Dunbaree788e72009-12-21 18:54:17 +0000183 Path = getDriver().Dir;
Daniel Dunbarc50b00d2009-03-23 16:15:50 +0000184 Path += "/../lib/gcc/";
Daniel Dunbar6b200b22009-09-18 08:14:36 +0000185 Path += ToolChainDir;
Daniel Dunbarc50b00d2009-03-23 16:15:50 +0000186 getFilePaths().push_back(Path);
187
188 Path = "/usr/lib/gcc/";
Daniel Dunbar6b200b22009-09-18 08:14:36 +0000189 Path += ToolChainDir;
Daniel Dunbarc50b00d2009-03-23 16:15:50 +0000190 getFilePaths().push_back(Path);
191
Daniel Dunbaree788e72009-12-21 18:54:17 +0000192 Path = getDriver().Dir;
Daniel Dunbarc50b00d2009-03-23 16:15:50 +0000193 Path += "/../libexec/gcc/";
Daniel Dunbar6b200b22009-09-18 08:14:36 +0000194 Path += ToolChainDir;
Daniel Dunbarc50b00d2009-03-23 16:15:50 +0000195 getProgramPaths().push_back(Path);
196
197 Path = "/usr/libexec/gcc/";
Daniel Dunbar6b200b22009-09-18 08:14:36 +0000198 Path += ToolChainDir;
Daniel Dunbarc50b00d2009-03-23 16:15:50 +0000199 getProgramPaths().push_back(Path);
200
Daniel Dunbaredf29b02010-08-01 22:29:51 +0000201 getProgramPaths().push_back(getDriver().getInstalledDir());
202 if (getDriver().getInstalledDir() != getDriver().Dir)
203 getProgramPaths().push_back(getDriver().Dir);
Daniel Dunbarc50b00d2009-03-23 16:15:50 +0000204}
205
Daniel Dunbarf3955282009-09-04 18:34:51 +0000206Darwin::~Darwin() {
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000207 // Free tool implementations.
208 for (llvm::DenseMap<unsigned, Tool*>::iterator
209 it = Tools.begin(), ie = Tools.end(); it != ie; ++it)
210 delete it->second;
211}
212
Daniel Dunbar00577ad2010-08-23 22:35:37 +0000213std::string Darwin::ComputeEffectiveClangTriple(const ArgList &Args) const {
214 llvm::Triple Triple(ComputeLLVMTriple(Args));
215
216 // If the target isn't initialized (e.g., an unknown Darwin platform, return
217 // the default triple).
218 if (!isTargetInitialized())
219 return Triple.getTriple();
220
221 unsigned Version[3];
222 getTargetVersion(Version);
223
224 // Mangle the target version into the OS triple component. For historical
225 // reasons that make little sense, the version passed here is the "darwin"
226 // version, which drops the 10 and offsets by 4. See inverse code when
227 // setting the OS version preprocessor define.
228 if (!isTargetIPhoneOS()) {
229 Version[0] = Version[1] + 4;
230 Version[1] = Version[2];
231 Version[2] = 0;
232 } else {
233 // Use the environment to communicate that we are targetting iPhoneOS.
234 Triple.setEnvironmentName("iphoneos");
235 }
236
237 llvm::SmallString<16> Str;
238 llvm::raw_svector_ostream(Str) << "darwin" << Version[0]
239 << "." << Version[1] << "." << Version[2];
240 Triple.setOSName(Str.str());
241
242 return Triple.getTriple();
243}
244
Daniel Dunbarf3955282009-09-04 18:34:51 +0000245Tool &Darwin::SelectTool(const Compilation &C, const JobAction &JA) const {
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000246 Action::ActionClass Key;
Daniel Dunbaree788e72009-12-21 18:54:17 +0000247 if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000248 Key = Action::AnalyzeJobClass;
249 else
250 Key = JA.getKind();
251
Daniel Dunbar0f602de2010-05-20 21:48:38 +0000252 // FIXME: This doesn't belong here, but ideally we will support static soon
253 // anyway.
254 bool HasStatic = (C.getArgs().hasArg(options::OPT_mkernel) ||
255 C.getArgs().hasArg(options::OPT_static) ||
256 C.getArgs().hasArg(options::OPT_fapple_kext));
257 bool IsIADefault = IsIntegratedAssemblerDefault() && !HasStatic;
258 bool UseIntegratedAs = C.getArgs().hasFlag(options::OPT_integrated_as,
259 options::OPT_no_integrated_as,
260 IsIADefault);
261
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000262 Tool *&T = Tools[Key];
263 if (!T) {
264 switch (Key) {
265 case Action::InputClass:
266 case Action::BindArchClass:
267 assert(0 && "Invalid tool kind.");
268 case Action::PreprocessJobClass:
Daniel Dunbar9120f172009-03-29 22:27:40 +0000269 T = new tools::darwin::Preprocess(*this); break;
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000270 case Action::AnalyzeJobClass:
271 T = new tools::Clang(*this); break;
Daniel Dunbar9120f172009-03-29 22:27:40 +0000272 case Action::PrecompileJobClass:
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000273 case Action::CompileJobClass:
Daniel Dunbar9120f172009-03-29 22:27:40 +0000274 T = new tools::darwin::Compile(*this); break;
Daniel Dunbar0f602de2010-05-20 21:48:38 +0000275 case Action::AssembleJobClass: {
276 if (UseIntegratedAs)
277 T = new tools::ClangAs(*this);
278 else
279 T = new tools::darwin::Assemble(*this);
280 break;
281 }
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000282 case Action::LinkJobClass:
Daniel Dunbar8f289622009-09-04 17:39:02 +0000283 T = new tools::darwin::Link(*this); break;
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000284 case Action::LipoJobClass:
285 T = new tools::darwin::Lipo(*this); break;
Daniel Dunbar6e0f2542010-06-04 18:28:36 +0000286 case Action::DsymutilJobClass:
287 T = new tools::darwin::Dsymutil(*this); break;
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000288 }
289 }
290
291 return *T;
292}
293
Daniel Dunbar1d4612b2009-09-18 08:15:13 +0000294void DarwinGCC::AddLinkSearchPathArgs(const ArgList &Args,
295 ArgStringList &CmdArgs) const {
Daniel Dunbare3c153a2010-04-10 18:18:57 +0000296 std::string Tmp;
297
Daniel Dunbar6b200b22009-09-18 08:14:36 +0000298 // FIXME: Derive these correctly.
299 if (getArchName() == "x86_64") {
300 CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir +
301 "/x86_64"));
302 // Intentionally duplicated for (temporary) gcc bug compatibility.
303 CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir +
304 "/x86_64"));
305 }
Daniel Dunbareab3bc42010-08-23 20:58:52 +0000306
Daniel Dunbar6b200b22009-09-18 08:14:36 +0000307 CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/" + ToolChainDir));
Daniel Dunbare3c153a2010-04-10 18:18:57 +0000308
309 Tmp = getDriver().Dir + "/../lib/gcc/" + ToolChainDir;
310 if (llvm::sys::Path(Tmp).exists())
311 CmdArgs.push_back(Args.MakeArgString("-L" + Tmp));
312 Tmp = getDriver().Dir + "/../lib/gcc";
313 if (llvm::sys::Path(Tmp).exists())
314 CmdArgs.push_back(Args.MakeArgString("-L" + Tmp));
Daniel Dunbar6b200b22009-09-18 08:14:36 +0000315 CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir));
316 // Intentionally duplicated for (temporary) gcc bug compatibility.
317 CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir));
Daniel Dunbare3c153a2010-04-10 18:18:57 +0000318 Tmp = getDriver().Dir + "/../lib/" + ToolChainDir;
319 if (llvm::sys::Path(Tmp).exists())
320 CmdArgs.push_back(Args.MakeArgString("-L" + Tmp));
321 Tmp = getDriver().Dir + "/../lib";
322 if (llvm::sys::Path(Tmp).exists())
323 CmdArgs.push_back(Args.MakeArgString("-L" + Tmp));
Daniel Dunbar6b200b22009-09-18 08:14:36 +0000324 CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir +
325 "/../../../" + ToolChainDir));
326 CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc/" + ToolChainDir +
327 "/../../.."));
328}
329
Daniel Dunbar1d4612b2009-09-18 08:15:13 +0000330void DarwinGCC::AddLinkRuntimeLibArgs(const ArgList &Args,
331 ArgStringList &CmdArgs) const {
Daniel Dunbarce3fdf22010-01-27 00:57:03 +0000332 // Note that this routine is only used for targetting OS X.
Daniel Dunbar6cd41542009-09-18 08:15:03 +0000333
334 // Derived from libgcc and lib specs but refactored.
335 if (Args.hasArg(options::OPT_static)) {
336 CmdArgs.push_back("-lgcc_static");
337 } else {
338 if (Args.hasArg(options::OPT_static_libgcc)) {
339 CmdArgs.push_back("-lgcc_eh");
340 } else if (Args.hasArg(options::OPT_miphoneos_version_min_EQ)) {
341 // Derived from darwin_iphoneos_libgcc spec.
Daniel Dunbar251ca6c2010-01-27 00:56:37 +0000342 if (isTargetIPhoneOS()) {
Daniel Dunbar6cd41542009-09-18 08:15:03 +0000343 CmdArgs.push_back("-lgcc_s.1");
344 } else {
345 CmdArgs.push_back("-lgcc_s.10.5");
346 }
347 } else if (Args.hasArg(options::OPT_shared_libgcc) ||
Daniel Dunbar8a0d94d2010-01-10 00:46:10 +0000348 Args.hasFlag(options::OPT_fexceptions,
349 options::OPT_fno_exceptions) ||
Daniel Dunbar6cd41542009-09-18 08:15:03 +0000350 Args.hasArg(options::OPT_fgnu_runtime)) {
351 // FIXME: This is probably broken on 10.3?
Daniel Dunbarce3fdf22010-01-27 00:57:03 +0000352 if (isMacosxVersionLT(10, 5))
Daniel Dunbar6cd41542009-09-18 08:15:03 +0000353 CmdArgs.push_back("-lgcc_s.10.4");
Daniel Dunbarce3fdf22010-01-27 00:57:03 +0000354 else if (isMacosxVersionLT(10, 6))
Daniel Dunbar6cd41542009-09-18 08:15:03 +0000355 CmdArgs.push_back("-lgcc_s.10.5");
356 } else {
Daniel Dunbarce3fdf22010-01-27 00:57:03 +0000357 if (isMacosxVersionLT(10, 3, 9))
Daniel Dunbar6cd41542009-09-18 08:15:03 +0000358 ; // Do nothing.
Daniel Dunbarce3fdf22010-01-27 00:57:03 +0000359 else if (isMacosxVersionLT(10, 5))
Daniel Dunbar6cd41542009-09-18 08:15:03 +0000360 CmdArgs.push_back("-lgcc_s.10.4");
Daniel Dunbarce3fdf22010-01-27 00:57:03 +0000361 else if (isMacosxVersionLT(10, 6))
Daniel Dunbar6cd41542009-09-18 08:15:03 +0000362 CmdArgs.push_back("-lgcc_s.10.5");
363 }
364
Daniel Dunbarce3fdf22010-01-27 00:57:03 +0000365 if (isTargetIPhoneOS() || isMacosxVersionLT(10, 6)) {
Daniel Dunbar6cd41542009-09-18 08:15:03 +0000366 CmdArgs.push_back("-lgcc");
367 CmdArgs.push_back("-lSystem");
368 } else {
369 CmdArgs.push_back("-lSystem");
370 CmdArgs.push_back("-lgcc");
371 }
372 }
373}
374
Daniel Dunbar25b58eb2010-08-02 05:44:07 +0000375DarwinClang::DarwinClang(const HostInfo &Host, const llvm::Triple& Triple)
376 : Darwin(Host, Triple)
Daniel Dunbar1d4612b2009-09-18 08:15:13 +0000377{
Daniel Dunbar0e50ee42010-09-17 08:22:12 +0000378 getProgramPaths().push_back(getDriver().getInstalledDir());
379 if (getDriver().getInstalledDir() != getDriver().Dir)
380 getProgramPaths().push_back(getDriver().Dir);
381
Daniel Dunbar1d4612b2009-09-18 08:15:13 +0000382 // We expect 'as', 'ld', etc. to be adjacent to our install dir.
Daniel Dunbaredf29b02010-08-01 22:29:51 +0000383 getProgramPaths().push_back(getDriver().getInstalledDir());
384 if (getDriver().getInstalledDir() != getDriver().Dir)
385 getProgramPaths().push_back(getDriver().Dir);
Daniel Dunbar0e50ee42010-09-17 08:22:12 +0000386
387 // For fallback, we need to know how to find the GCC cc1 executables, so we
388 // also add the GCC libexec paths. This is legiy code that can be removed once
389 // fallback is no longer useful.
390 std::string ToolChainDir = "i686-apple-darwin";
391 ToolChainDir += llvm::utostr(DarwinVersion[0]);
392 ToolChainDir += "/4.2.1";
393
394 std::string Path = getDriver().Dir;
395 Path += "/../libexec/gcc/";
396 Path += ToolChainDir;
397 getProgramPaths().push_back(Path);
398
399 Path = "/usr/libexec/gcc/";
400 Path += ToolChainDir;
401 getProgramPaths().push_back(Path);
Daniel Dunbar1d4612b2009-09-18 08:15:13 +0000402}
403
404void DarwinClang::AddLinkSearchPathArgs(const ArgList &Args,
405 ArgStringList &CmdArgs) const {
406 // The Clang toolchain uses explicit paths for internal libraries.
Daniel Dunbar424b6612010-06-30 23:56:13 +0000407
408 // Unfortunately, we still might depend on a few of the libraries that are
409 // only available in the gcc library directory (in particular
410 // libstdc++.dylib). For now, hardcode the path to the known install location.
411 llvm::sys::Path P(getDriver().Dir);
412 P.eraseComponent(); // .../usr/bin -> ../usr
413 P.appendComponent("lib");
414 P.appendComponent("gcc");
415 switch (getTriple().getArch()) {
416 default:
417 assert(0 && "Invalid Darwin arch!");
418 case llvm::Triple::x86:
419 case llvm::Triple::x86_64:
420 P.appendComponent("i686-apple-darwin10");
421 break;
422 case llvm::Triple::arm:
423 case llvm::Triple::thumb:
424 P.appendComponent("arm-apple-darwin10");
425 break;
426 case llvm::Triple::ppc:
427 case llvm::Triple::ppc64:
428 P.appendComponent("powerpc-apple-darwin10");
429 break;
430 }
431 P.appendComponent("4.2.1");
Daniel Dunbareab3bc42010-08-23 20:58:52 +0000432
433 // Determine the arch specific GCC subdirectory.
434 const char *ArchSpecificDir = 0;
435 switch (getTriple().getArch()) {
436 default:
437 break;
438 case llvm::Triple::arm:
Daniel Dunbar3a0e3922010-08-26 00:55:52 +0000439 case llvm::Triple::thumb: {
440 std::string Triple = ComputeLLVMTriple(Args);
441 llvm::StringRef TripleStr = Triple;
442 if (TripleStr.startswith("armv5") || TripleStr.startswith("thumbv5"))
443 ArchSpecificDir = "v5";
444 else if (TripleStr.startswith("armv6") || TripleStr.startswith("thumbv6"))
445 ArchSpecificDir = "v6";
446 else if (TripleStr.startswith("armv7") || TripleStr.startswith("thumbv7"))
447 ArchSpecificDir = "v7";
Daniel Dunbareab3bc42010-08-23 20:58:52 +0000448 break;
Daniel Dunbar3a0e3922010-08-26 00:55:52 +0000449 }
Daniel Dunbareab3bc42010-08-23 20:58:52 +0000450 case llvm::Triple::ppc64:
451 ArchSpecificDir = "ppc64";
452 break;
453 case llvm::Triple::x86_64:
454 ArchSpecificDir = "x86_64";
455 break;
456 }
457
458 if (ArchSpecificDir) {
459 P.appendComponent(ArchSpecificDir);
Daniel Dunbareab3bc42010-08-23 20:58:52 +0000460 if (P.exists())
461 CmdArgs.push_back(Args.MakeArgString("-L" + P.str()));
462 P.eraseComponent();
463 }
464
Daniel Dunbar424b6612010-06-30 23:56:13 +0000465 if (P.exists())
466 CmdArgs.push_back(Args.MakeArgString("-L" + P.str()));
Daniel Dunbar1d4612b2009-09-18 08:15:13 +0000467}
468
469void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args,
470 ArgStringList &CmdArgs) const {
Daniel Dunbareec99102010-01-22 03:38:14 +0000471 // Darwin doesn't support real static executables, don't link any runtime
472 // libraries with -static.
473 if (Args.hasArg(options::OPT_static))
Daniel Dunbar1d4612b2009-09-18 08:15:13 +0000474 return;
Daniel Dunbar1d4612b2009-09-18 08:15:13 +0000475
476 // Reject -static-libgcc for now, we can deal with this when and if someone
477 // cares. This is useful in situations where someone wants to statically link
478 // something like libstdc++, and needs its runtime support routines.
479 if (const Arg *A = Args.getLastArg(options::OPT_static_libgcc)) {
Daniel Dunbaree788e72009-12-21 18:54:17 +0000480 getDriver().Diag(clang::diag::err_drv_unsupported_opt)
Daniel Dunbar1d4612b2009-09-18 08:15:13 +0000481 << A->getAsString(Args);
482 return;
483 }
484
Daniel Dunbareec99102010-01-22 03:38:14 +0000485 // Otherwise link libSystem, then the dynamic runtime library, and finally any
486 // target specific static runtime library.
Daniel Dunbar1d4612b2009-09-18 08:15:13 +0000487 CmdArgs.push_back("-lSystem");
Daniel Dunbareec99102010-01-22 03:38:14 +0000488
489 // Select the dynamic runtime library and the target specific static library.
490 const char *DarwinStaticLib = 0;
Daniel Dunbar251ca6c2010-01-27 00:56:37 +0000491 if (isTargetIPhoneOS()) {
Daniel Dunbareec99102010-01-22 03:38:14 +0000492 CmdArgs.push_back("-lgcc_s.1");
493
494 // We may need some static functions for armv6/thumb which are required to
495 // be in the same linkage unit as their caller.
496 if (getDarwinArchName(Args) == "armv6")
497 DarwinStaticLib = "libclang_rt.armv6.a";
498 } else {
Daniel Dunbareec99102010-01-22 03:38:14 +0000499 // The dynamic runtime library was merged with libSystem for 10.6 and
500 // beyond; only 10.4 and 10.5 need an additional runtime library.
Daniel Dunbarce3fdf22010-01-27 00:57:03 +0000501 if (isMacosxVersionLT(10, 5))
Daniel Dunbareec99102010-01-22 03:38:14 +0000502 CmdArgs.push_back("-lgcc_s.10.4");
Daniel Dunbarce3fdf22010-01-27 00:57:03 +0000503 else if (isMacosxVersionLT(10, 6))
Daniel Dunbareec99102010-01-22 03:38:14 +0000504 CmdArgs.push_back("-lgcc_s.10.5");
505
Daniel Dunbar885b1db2010-09-22 00:03:52 +0000506 // For OS X, we thought we would only need a static runtime library when
507 // targetting 10.4, to provide versions of the static functions which were
508 // omitted from 10.4.dylib.
509 //
510 // Unfortunately, that turned out to not be true, because Darwin system
511 // headers can still use eprintf on i386, and it is not exported from
512 // libSystem. Therefore, we still must provide a runtime library just for
513 // the tiny tiny handful of projects that *might* use that symbol.
514 if (isMacosxVersionLT(10, 5)) {
Daniel Dunbareec99102010-01-22 03:38:14 +0000515 DarwinStaticLib = "libclang_rt.10.4.a";
Daniel Dunbar885b1db2010-09-22 00:03:52 +0000516 } else {
517 if (getTriple().getArch() == llvm::Triple::x86)
518 DarwinStaticLib = "libclang_rt.eprintf.a";
519 }
Daniel Dunbareec99102010-01-22 03:38:14 +0000520 }
521
522 /// Add the target specific static library, if needed.
523 if (DarwinStaticLib) {
524 llvm::sys::Path P(getDriver().ResourceDir);
525 P.appendComponent("lib");
526 P.appendComponent("darwin");
527 P.appendComponent(DarwinStaticLib);
528
529 // For now, allow missing resource libraries to support developers who may
530 // not have compiler-rt checked out or integrated into their build.
Daniel Dunbar362ed702010-10-11 23:31:07 +0000531 if (P.exists())
Daniel Dunbareec99102010-01-22 03:38:14 +0000532 CmdArgs.push_back(Args.MakeArgString(P.str()));
533 }
Daniel Dunbar1d4612b2009-09-18 08:15:13 +0000534}
535
Daniel Dunbar60baf0f2010-07-19 17:11:36 +0000536void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
Daniel Dunbaree788e72009-12-21 18:54:17 +0000537 const OptTable &Opts = getDriver().getOpts();
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000538
Daniel Dunbar26031372010-01-27 00:56:25 +0000539 Arg *OSXVersion = Args.getLastArg(options::OPT_mmacosx_version_min_EQ);
540 Arg *iPhoneVersion = Args.getLastArg(options::OPT_miphoneos_version_min_EQ);
Daniel Dunbarff8857a2009-04-10 20:11:50 +0000541 if (OSXVersion && iPhoneVersion) {
Daniel Dunbaree788e72009-12-21 18:54:17 +0000542 getDriver().Diag(clang::diag::err_drv_argument_not_allowed_with)
Daniel Dunbarff8857a2009-04-10 20:11:50 +0000543 << OSXVersion->getAsString(Args)
Mike Stump1eb44332009-09-09 15:08:12 +0000544 << iPhoneVersion->getAsString(Args);
Daniel Dunbar26031372010-01-27 00:56:25 +0000545 iPhoneVersion = 0;
Daniel Dunbarff8857a2009-04-10 20:11:50 +0000546 } else if (!OSXVersion && !iPhoneVersion) {
Daniel Dunbar816bc312010-01-26 01:45:19 +0000547 // If neither OS X nor iPhoneOS targets were specified, check for
548 // environment defines.
549 const char *OSXTarget = ::getenv("MACOSX_DEPLOYMENT_TARGET");
550 const char *iPhoneOSTarget = ::getenv("IPHONEOS_DEPLOYMENT_TARGET");
Daniel Dunbarf36a06a2009-04-10 21:00:07 +0000551
Daniel Dunbar816bc312010-01-26 01:45:19 +0000552 // Ignore empty strings.
553 if (OSXTarget && OSXTarget[0] == '\0')
554 OSXTarget = 0;
555 if (iPhoneOSTarget && iPhoneOSTarget[0] == '\0')
556 iPhoneOSTarget = 0;
557
Daniel Dunbar39053672010-02-02 17:31:12 +0000558 // Diagnose conflicting deployment targets, and choose default platform
559 // based on the tool chain.
560 //
561 // FIXME: Don't hardcode default here.
562 if (OSXTarget && iPhoneOSTarget) {
563 // FIXME: We should see if we can get away with warning or erroring on
564 // this. Perhaps put under -pedantic?
565 if (getTriple().getArch() == llvm::Triple::arm ||
566 getTriple().getArch() == llvm::Triple::thumb)
Daniel Dunbar84d1e6e2010-03-20 08:47:42 +0000567 OSXTarget = 0;
Daniel Dunbar39053672010-02-02 17:31:12 +0000568 else
Daniel Dunbar84d1e6e2010-03-20 08:47:42 +0000569 iPhoneOSTarget = 0;
Daniel Dunbar39053672010-02-02 17:31:12 +0000570 }
Daniel Dunbar1a3c1d92010-01-29 17:02:25 +0000571
Daniel Dunbar39053672010-02-02 17:31:12 +0000572 if (OSXTarget) {
Daniel Dunbar30392de2009-09-04 18:35:21 +0000573 const Option *O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
Daniel Dunbar60baf0f2010-07-19 17:11:36 +0000574 OSXVersion = Args.MakeJoinedArg(0, O, OSXTarget);
575 Args.append(OSXVersion);
Daniel Dunbar816bc312010-01-26 01:45:19 +0000576 } else if (iPhoneOSTarget) {
Daniel Dunbar30392de2009-09-04 18:35:21 +0000577 const Option *O = Opts.getOption(options::OPT_miphoneos_version_min_EQ);
Daniel Dunbar60baf0f2010-07-19 17:11:36 +0000578 iPhoneVersion = Args.MakeJoinedArg(0, O, iPhoneOSTarget);
579 Args.append(iPhoneVersion);
Daniel Dunbar816bc312010-01-26 01:45:19 +0000580 } else {
Daniel Dunbar2bb38d02010-07-15 16:18:06 +0000581 // Otherwise, assume we are targeting OS X.
582 const Option *O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
Daniel Dunbar60baf0f2010-07-19 17:11:36 +0000583 OSXVersion = Args.MakeJoinedArg(0, O, MacosxVersionMin);
584 Args.append(OSXVersion);
Daniel Dunbar30392de2009-09-04 18:35:21 +0000585 }
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000586 }
Mike Stump1eb44332009-09-09 15:08:12 +0000587
Daniel Dunbar26031372010-01-27 00:56:25 +0000588 // Set the tool chain target information.
589 unsigned Major, Minor, Micro;
590 bool HadExtra;
591 if (OSXVersion) {
592 assert(!iPhoneVersion && "Unknown target platform!");
593 if (!Driver::GetReleaseVersion(OSXVersion->getValue(Args), Major, Minor,
594 Micro, HadExtra) || HadExtra ||
595 Major != 10 || Minor >= 10 || Micro >= 10)
596 getDriver().Diag(clang::diag::err_drv_invalid_version_number)
597 << OSXVersion->getAsString(Args);
598 } else {
599 assert(iPhoneVersion && "Unknown target platform!");
600 if (!Driver::GetReleaseVersion(iPhoneVersion->getValue(Args), Major, Minor,
601 Micro, HadExtra) || HadExtra ||
602 Major >= 10 || Minor >= 100 || Micro >= 100)
603 getDriver().Diag(clang::diag::err_drv_invalid_version_number)
604 << iPhoneVersion->getAsString(Args);
605 }
606 setTarget(iPhoneVersion, Major, Minor, Micro);
Daniel Dunbarc0e665e2010-07-19 17:11:33 +0000607}
608
Daniel Dunbar132e35d2010-09-17 01:20:05 +0000609void DarwinClang::AddCXXStdlibLibArgs(const ArgList &Args,
Daniel Dunbarefe91ea2010-09-17 01:16:06 +0000610 ArgStringList &CmdArgs) const {
611 CXXStdlibType Type = GetCXXStdlibType(Args);
612
613 switch (Type) {
614 case ToolChain::CST_Libcxx:
615 CmdArgs.push_back("-lc++");
616 break;
617
618 case ToolChain::CST_Libstdcxx: {
619 // Unfortunately, -lstdc++ doesn't always exist in the standard search path;
620 // it was previously found in the gcc lib dir. However, for all the Darwin
621 // platforms we care about it was -lstdc++.6, so we search for that
622 // explicitly if we can't see an obvious -lstdc++ candidate.
623
624 // Check in the sysroot first.
625 if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
626 llvm::sys::Path P(A->getValue(Args));
627 P.appendComponent("usr");
628 P.appendComponent("lib");
629 P.appendComponent("libstdc++.dylib");
630
631 if (!P.exists()) {
632 P.eraseComponent();
633 P.appendComponent("libstdc++.6.dylib");
634 if (P.exists()) {
635 CmdArgs.push_back(Args.MakeArgString(P.str()));
636 return;
637 }
638 }
639 }
640
641 // Otherwise, look in the root.
642 if (!llvm::sys::Path("/usr/lib/libstdc++.dylib").exists() &&
643 llvm::sys::Path("/usr/lib/libstdc++.6.dylib").exists()) {
644 CmdArgs.push_back("/usr/lib/libstdc++.6.dylib");
645 return;
646 }
647
648 // Otherwise, let the linker search.
649 CmdArgs.push_back("-lstdc++");
650 break;
651 }
652 }
653}
654
Shantonu Sen7433fed2010-09-17 18:39:08 +0000655void DarwinClang::AddCCKextLibArgs(const ArgList &Args,
656 ArgStringList &CmdArgs) const {
657
658 // For Darwin platforms, use the compiler-rt-based support library
659 // instead of the gcc-provided one (which is also incidentally
660 // only present in the gcc lib dir, which makes it hard to find).
661
662 llvm::sys::Path P(getDriver().ResourceDir);
663 P.appendComponent("lib");
664 P.appendComponent("darwin");
665 P.appendComponent("libclang_rt.cc_kext.a");
666
667 // For now, allow missing resource libraries to support developers who may
668 // not have compiler-rt checked out or integrated into their build.
Daniel Dunbar362ed702010-10-11 23:31:07 +0000669 if (P.exists())
Shantonu Sen7433fed2010-09-17 18:39:08 +0000670 CmdArgs.push_back(Args.MakeArgString(P.str()));
671}
672
Daniel Dunbarc0e665e2010-07-19 17:11:33 +0000673DerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args,
674 const char *BoundArch) const {
675 DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
676 const OptTable &Opts = getDriver().getOpts();
677
678 // FIXME: We really want to get out of the tool chain level argument
679 // translation business, as it makes the driver functionality much
680 // more opaque. For now, we follow gcc closely solely for the
681 // purpose of easily achieving feature parity & testability. Once we
682 // have something that works, we should reevaluate each translation
683 // and try to push it down into tool specific logic.
Daniel Dunbar26031372010-01-27 00:56:25 +0000684
Daniel Dunbar279c1db2010-06-11 22:00:26 +0000685 for (ArgList::const_iterator it = Args.begin(),
686 ie = Args.end(); it != ie; ++it) {
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000687 Arg *A = *it;
688
689 if (A->getOption().matches(options::OPT_Xarch__)) {
690 // FIXME: Canonicalize name.
691 if (getArchName() != A->getValue(Args, 0))
692 continue;
693
Daniel Dunbar0e100312010-06-14 21:23:08 +0000694 unsigned Index = Args.getBaseArgs().MakeIndex(A->getValue(Args, 1));
695 unsigned Prev = Index;
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000696 Arg *XarchArg = Opts.ParseOneArg(Args, Index);
Mike Stump1eb44332009-09-09 15:08:12 +0000697
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000698 // If the argument parsing failed or more than one argument was
699 // consumed, the -Xarch_ argument's parameter tried to consume
700 // extra arguments. Emit an error and ignore.
701 //
702 // We also want to disallow any options which would alter the
703 // driver behavior; that isn't going to work in our model. We
704 // use isDriverOption() as an approximation, although things
705 // like -O4 are going to slip through.
Mike Stump1eb44332009-09-09 15:08:12 +0000706 if (!XarchArg || Index > Prev + 1 ||
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000707 XarchArg->getOption().isDriverOption()) {
Daniel Dunbaree788e72009-12-21 18:54:17 +0000708 getDriver().Diag(clang::diag::err_drv_invalid_Xarch_argument)
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000709 << A->getAsString(Args);
710 continue;
711 }
712
Daniel Dunbar478edc22009-03-29 22:29:05 +0000713 XarchArg->setBaseArg(A);
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000714 A = XarchArg;
Daniel Dunbar0e100312010-06-14 21:23:08 +0000715
716 DAL->AddSynthesizedArg(A);
Mike Stump1eb44332009-09-09 15:08:12 +0000717 }
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000718
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000719 // Sob. These is strictly gcc compatible for the time being. Apple
720 // gcc translates options twice, which means that self-expanding
721 // options add duplicates.
Daniel Dunbar9e1f9822009-11-19 04:14:53 +0000722 switch ((options::ID) A->getOption().getID()) {
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000723 default:
724 DAL->append(A);
725 break;
726
727 case options::OPT_mkernel:
728 case options::OPT_fapple_kext:
729 DAL->append(A);
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000730 DAL->AddFlagArg(A, Opts.getOption(options::OPT_static));
731 DAL->AddFlagArg(A, Opts.getOption(options::OPT_static));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000732 break;
Mike Stump1eb44332009-09-09 15:08:12 +0000733
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000734 case options::OPT_dependency_file:
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000735 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF),
736 A->getValue(Args));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000737 break;
738
739 case options::OPT_gfull:
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000740 DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag));
741 DAL->AddFlagArg(A,
742 Opts.getOption(options::OPT_fno_eliminate_unused_debug_symbols));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000743 break;
744
745 case options::OPT_gused:
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000746 DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag));
747 DAL->AddFlagArg(A,
748 Opts.getOption(options::OPT_feliminate_unused_debug_symbols));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000749 break;
750
751 case options::OPT_fterminated_vtables:
752 case options::OPT_findirect_virtual_calls:
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000753 DAL->AddFlagArg(A, Opts.getOption(options::OPT_fapple_kext));
754 DAL->AddFlagArg(A, Opts.getOption(options::OPT_static));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000755 break;
756
757 case options::OPT_shared:
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000758 DAL->AddFlagArg(A, Opts.getOption(options::OPT_dynamiclib));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000759 break;
760
761 case options::OPT_fconstant_cfstrings:
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000762 DAL->AddFlagArg(A, Opts.getOption(options::OPT_mconstant_cfstrings));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000763 break;
764
765 case options::OPT_fno_constant_cfstrings:
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000766 DAL->AddFlagArg(A, Opts.getOption(options::OPT_mno_constant_cfstrings));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000767 break;
768
769 case options::OPT_Wnonportable_cfstrings:
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000770 DAL->AddFlagArg(A,
771 Opts.getOption(options::OPT_mwarn_nonportable_cfstrings));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000772 break;
773
774 case options::OPT_Wno_nonportable_cfstrings:
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000775 DAL->AddFlagArg(A,
776 Opts.getOption(options::OPT_mno_warn_nonportable_cfstrings));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000777 break;
778
779 case options::OPT_fpascal_strings:
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000780 DAL->AddFlagArg(A, Opts.getOption(options::OPT_mpascal_strings));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000781 break;
782
783 case options::OPT_fno_pascal_strings:
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000784 DAL->AddFlagArg(A, Opts.getOption(options::OPT_mno_pascal_strings));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000785 break;
786 }
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000787 }
788
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000789 if (getTriple().getArch() == llvm::Triple::x86 ||
790 getTriple().getArch() == llvm::Triple::x86_64)
Daniel Dunbare4bdae72009-11-19 04:00:53 +0000791 if (!Args.hasArgNoClaim(options::OPT_mtune_EQ))
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000792 DAL->AddJoinedArg(0, Opts.getOption(options::OPT_mtune_EQ), "core2");
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000793
794 // Add the arch options based on the particular spelling of -arch, to match
795 // how the driver driver works.
796 if (BoundArch) {
797 llvm::StringRef Name = BoundArch;
798 const Option *MCpu = Opts.getOption(options::OPT_mcpu_EQ);
799 const Option *MArch = Opts.getOption(options::OPT_march_EQ);
800
801 // This code must be kept in sync with LLVM's getArchTypeForDarwinArch,
802 // which defines the list of which architectures we accept.
803 if (Name == "ppc")
804 ;
805 else if (Name == "ppc601")
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000806 DAL->AddJoinedArg(0, MCpu, "601");
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000807 else if (Name == "ppc603")
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000808 DAL->AddJoinedArg(0, MCpu, "603");
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000809 else if (Name == "ppc604")
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000810 DAL->AddJoinedArg(0, MCpu, "604");
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000811 else if (Name == "ppc604e")
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000812 DAL->AddJoinedArg(0, MCpu, "604e");
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000813 else if (Name == "ppc750")
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000814 DAL->AddJoinedArg(0, MCpu, "750");
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000815 else if (Name == "ppc7400")
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000816 DAL->AddJoinedArg(0, MCpu, "7400");
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000817 else if (Name == "ppc7450")
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000818 DAL->AddJoinedArg(0, MCpu, "7450");
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000819 else if (Name == "ppc970")
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000820 DAL->AddJoinedArg(0, MCpu, "970");
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000821
822 else if (Name == "ppc64")
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000823 DAL->AddFlagArg(0, Opts.getOption(options::OPT_m64));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000824
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000825 else if (Name == "i386")
826 ;
827 else if (Name == "i486")
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000828 DAL->AddJoinedArg(0, MArch, "i486");
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000829 else if (Name == "i586")
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000830 DAL->AddJoinedArg(0, MArch, "i586");
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000831 else if (Name == "i686")
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000832 DAL->AddJoinedArg(0, MArch, "i686");
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000833 else if (Name == "pentium")
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000834 DAL->AddJoinedArg(0, MArch, "pentium");
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000835 else if (Name == "pentium2")
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000836 DAL->AddJoinedArg(0, MArch, "pentium2");
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000837 else if (Name == "pentpro")
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000838 DAL->AddJoinedArg(0, MArch, "pentiumpro");
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000839 else if (Name == "pentIIm3")
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000840 DAL->AddJoinedArg(0, MArch, "pentium2");
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000841
842 else if (Name == "x86_64")
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000843 DAL->AddFlagArg(0, Opts.getOption(options::OPT_m64));
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000844
845 else if (Name == "arm")
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000846 DAL->AddJoinedArg(0, MArch, "armv4t");
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000847 else if (Name == "armv4t")
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000848 DAL->AddJoinedArg(0, MArch, "armv4t");
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000849 else if (Name == "armv5")
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000850 DAL->AddJoinedArg(0, MArch, "armv5tej");
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000851 else if (Name == "xscale")
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000852 DAL->AddJoinedArg(0, MArch, "xscale");
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000853 else if (Name == "armv6")
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000854 DAL->AddJoinedArg(0, MArch, "armv6k");
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000855 else if (Name == "armv7")
Daniel Dunbar9d0863b2010-06-14 20:20:41 +0000856 DAL->AddJoinedArg(0, MArch, "armv7a");
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000857
858 else
Jeffrey Yasskin9f61aa92009-12-12 05:05:38 +0000859 llvm_unreachable("invalid Darwin arch");
Daniel Dunbar84ec96c2009-09-09 22:33:15 +0000860 }
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000861
Daniel Dunbar60baf0f2010-07-19 17:11:36 +0000862 // Add an explicit version min argument for the deployment target. We do this
863 // after argument translation because -Xarch_ arguments may add a version min
864 // argument.
865 AddDeploymentTarget(*DAL);
866
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000867 return DAL;
Mike Stump1eb44332009-09-09 15:08:12 +0000868}
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000869
Daniel Dunbarf3955282009-09-04 18:34:51 +0000870bool Darwin::IsUnwindTablesDefault() const {
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000871 // FIXME: Gross; we should probably have some separate target
872 // definition, possibly even reusing the one in clang.
873 return getArchName() == "x86_64";
874}
875
Daniel Dunbarf2d8b9f2009-12-18 02:43:17 +0000876bool Darwin::UseDwarfDebugFlags() const {
877 if (const char *S = ::getenv("RC_DEBUG_OPTIONS"))
878 return S[0] != '\0';
879 return false;
880}
881
Daniel Dunbarb2987d12010-02-10 18:49:11 +0000882bool Darwin::UseSjLjExceptions() const {
883 // Darwin uses SjLj exceptions on ARM.
884 return (getTriple().getArch() == llvm::Triple::arm ||
885 getTriple().getArch() == llvm::Triple::thumb);
886}
887
Daniel Dunbarf3955282009-09-04 18:34:51 +0000888const char *Darwin::GetDefaultRelocationModel() const {
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000889 return "pic";
890}
891
Daniel Dunbarf3955282009-09-04 18:34:51 +0000892const char *Darwin::GetForcedPicModel() const {
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000893 if (getArchName() == "x86_64")
894 return "pic";
895 return 0;
896}
897
Daniel Dunbar43a9b322010-04-10 16:20:23 +0000898bool Darwin::SupportsObjCGC() const {
899 // Garbage collection is supported everywhere except on iPhone OS.
900 return !isTargetIPhoneOS();
901}
902
Daniel Dunbar00577ad2010-08-23 22:35:37 +0000903std::string
904Darwin_Generic_GCC::ComputeEffectiveClangTriple(const ArgList &Args) const {
905 return ComputeLLVMTriple(Args);
906}
907
Daniel Dunbar39176082009-03-20 00:20:03 +0000908/// Generic_GCC - A tool chain using the 'gcc' command to perform
909/// all subcommands; this relies on gcc translating the majority of
910/// command line options.
911
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000912Generic_GCC::Generic_GCC(const HostInfo &Host, const llvm::Triple& Triple)
Mike Stump1eb44332009-09-09 15:08:12 +0000913 : ToolChain(Host, Triple) {
Daniel Dunbaredf29b02010-08-01 22:29:51 +0000914 getProgramPaths().push_back(getDriver().getInstalledDir());
915 if (getDriver().getInstalledDir() != getDriver().Dir.c_str())
916 getProgramPaths().push_back(getDriver().Dir);
Daniel Dunbarc50b00d2009-03-23 16:15:50 +0000917}
918
Daniel Dunbar39176082009-03-20 00:20:03 +0000919Generic_GCC::~Generic_GCC() {
920 // Free tool implementations.
921 for (llvm::DenseMap<unsigned, Tool*>::iterator
922 it = Tools.begin(), ie = Tools.end(); it != ie; ++it)
923 delete it->second;
924}
925
Mike Stump1eb44332009-09-09 15:08:12 +0000926Tool &Generic_GCC::SelectTool(const Compilation &C,
Daniel Dunbar39176082009-03-20 00:20:03 +0000927 const JobAction &JA) const {
928 Action::ActionClass Key;
Daniel Dunbaree788e72009-12-21 18:54:17 +0000929 if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
Daniel Dunbar39176082009-03-20 00:20:03 +0000930 Key = Action::AnalyzeJobClass;
931 else
932 Key = JA.getKind();
933
934 Tool *&T = Tools[Key];
935 if (!T) {
936 switch (Key) {
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000937 case Action::InputClass:
938 case Action::BindArchClass:
Daniel Dunbar39176082009-03-20 00:20:03 +0000939 assert(0 && "Invalid tool kind.");
940 case Action::PreprocessJobClass:
941 T = new tools::gcc::Preprocess(*this); break;
942 case Action::PrecompileJobClass:
943 T = new tools::gcc::Precompile(*this); break;
944 case Action::AnalyzeJobClass:
945 T = new tools::Clang(*this); break;
946 case Action::CompileJobClass:
947 T = new tools::gcc::Compile(*this); break;
948 case Action::AssembleJobClass:
949 T = new tools::gcc::Assemble(*this); break;
950 case Action::LinkJobClass:
951 T = new tools::gcc::Link(*this); break;
Mike Stump1eb44332009-09-09 15:08:12 +0000952
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000953 // This is a bit ungeneric, but the only platform using a driver
954 // driver is Darwin.
955 case Action::LipoJobClass:
956 T = new tools::darwin::Lipo(*this); break;
Daniel Dunbar6e0f2542010-06-04 18:28:36 +0000957 case Action::DsymutilJobClass:
958 T = new tools::darwin::Dsymutil(*this); break;
Daniel Dunbar39176082009-03-20 00:20:03 +0000959 }
960 }
961
962 return *T;
963}
964
Daniel Dunbar39176082009-03-20 00:20:03 +0000965bool Generic_GCC::IsUnwindTablesDefault() const {
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000966 // FIXME: Gross; we should probably have some separate target
967 // definition, possibly even reusing the one in clang.
Daniel Dunbar39176082009-03-20 00:20:03 +0000968 return getArchName() == "x86_64";
969}
970
971const char *Generic_GCC::GetDefaultRelocationModel() const {
972 return "static";
973}
974
975const char *Generic_GCC::GetForcedPicModel() const {
976 return 0;
977}
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000978
Chris Lattner3a47c4e2010-03-04 21:07:38 +0000979/// TCEToolChain - A tool chain using the llvm bitcode tools to perform
980/// all subcommands. See http://tce.cs.tut.fi for our peculiar target.
981/// Currently does not support anything else but compilation.
982
983TCEToolChain::TCEToolChain(const HostInfo &Host, const llvm::Triple& Triple)
984 : ToolChain(Host, Triple) {
985 // Path mangling to find libexec
986 std::string Path(getDriver().Dir);
987
988 Path += "/../libexec";
989 getProgramPaths().push_back(Path);
990}
991
992TCEToolChain::~TCEToolChain() {
993 for (llvm::DenseMap<unsigned, Tool*>::iterator
994 it = Tools.begin(), ie = Tools.end(); it != ie; ++it)
995 delete it->second;
996}
997
998bool TCEToolChain::IsMathErrnoDefault() const {
999 return true;
1000}
1001
1002bool TCEToolChain::IsUnwindTablesDefault() const {
1003 return false;
1004}
1005
1006const char *TCEToolChain::GetDefaultRelocationModel() const {
1007 return "static";
1008}
1009
1010const char *TCEToolChain::GetForcedPicModel() const {
1011 return 0;
1012}
1013
1014Tool &TCEToolChain::SelectTool(const Compilation &C,
1015 const JobAction &JA) const {
1016 Action::ActionClass Key;
1017 Key = Action::AnalyzeJobClass;
1018
1019 Tool *&T = Tools[Key];
1020 if (!T) {
1021 switch (Key) {
1022 case Action::PreprocessJobClass:
1023 T = new tools::gcc::Preprocess(*this); break;
1024 case Action::AnalyzeJobClass:
1025 T = new tools::Clang(*this); break;
1026 default:
1027 assert(false && "Unsupported action for TCE target.");
1028 }
1029 }
1030 return *T;
1031}
1032
Daniel Dunbarf7b8eec2009-06-29 20:52:51 +00001033/// OpenBSD - OpenBSD tool chain which can call as(1) and ld(1) directly.
1034
1035OpenBSD::OpenBSD(const HostInfo &Host, const llvm::Triple& Triple)
Rafael Espindolae43cfa12010-10-29 20:14:02 +00001036 : Generic_ELF(Host, Triple) {
Daniel Dunbaree788e72009-12-21 18:54:17 +00001037 getFilePaths().push_back(getDriver().Dir + "/../lib");
Daniel Dunbarf7b8eec2009-06-29 20:52:51 +00001038 getFilePaths().push_back("/usr/lib");
1039}
1040
1041Tool &OpenBSD::SelectTool(const Compilation &C, const JobAction &JA) const {
1042 Action::ActionClass Key;
Daniel Dunbaree788e72009-12-21 18:54:17 +00001043 if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
Daniel Dunbarf7b8eec2009-06-29 20:52:51 +00001044 Key = Action::AnalyzeJobClass;
1045 else
1046 Key = JA.getKind();
1047
Rafael Espindoladda5b922010-11-07 23:13:01 +00001048 bool UseIntegratedAs = C.getArgs().hasFlag(options::OPT_integrated_as,
1049 options::OPT_no_integrated_as,
1050 IsIntegratedAssemblerDefault());
1051
Daniel Dunbarf7b8eec2009-06-29 20:52:51 +00001052 Tool *&T = Tools[Key];
1053 if (!T) {
1054 switch (Key) {
Rafael Espindoladda5b922010-11-07 23:13:01 +00001055 case Action::AssembleJobClass: {
1056 if (UseIntegratedAs)
1057 T = new tools::ClangAs(*this);
1058 else
1059 T = new tools::openbsd::Assemble(*this);
1060 break;
1061 }
Daniel Dunbarf7b8eec2009-06-29 20:52:51 +00001062 case Action::LinkJobClass:
1063 T = new tools::openbsd::Link(*this); break;
1064 default:
1065 T = &Generic_GCC::SelectTool(C, JA);
1066 }
1067 }
1068
1069 return *T;
1070}
1071
Daniel Dunbar75358d22009-03-30 21:06:03 +00001072/// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly.
1073
Daniel Dunbar214afe92010-08-02 05:43:59 +00001074FreeBSD::FreeBSD(const HostInfo &Host, const llvm::Triple& Triple)
Rafael Espindolae43cfa12010-10-29 20:14:02 +00001075 : Generic_ELF(Host, Triple) {
Daniel Dunbar214afe92010-08-02 05:43:59 +00001076
1077 // Determine if we are compiling 32-bit code on an x86_64 platform.
1078 bool Lib32 = false;
1079 if (Triple.getArch() == llvm::Triple::x86 &&
1080 llvm::Triple(getDriver().DefaultHostTriple).getArch() ==
1081 llvm::Triple::x86_64)
1082 Lib32 = true;
1083
Daniel Dunbar7fb2c252010-06-15 15:03:31 +00001084 getProgramPaths().push_back(getDriver().Dir + "/../libexec");
1085 getProgramPaths().push_back("/usr/libexec");
Daniel Dunbarbc534662009-04-02 18:30:04 +00001086 if (Lib32) {
Daniel Dunbaree788e72009-12-21 18:54:17 +00001087 getFilePaths().push_back(getDriver().Dir + "/../lib32");
Daniel Dunbarbc534662009-04-02 18:30:04 +00001088 getFilePaths().push_back("/usr/lib32");
1089 } else {
Daniel Dunbaree788e72009-12-21 18:54:17 +00001090 getFilePaths().push_back(getDriver().Dir + "/../lib");
Daniel Dunbarbc534662009-04-02 18:30:04 +00001091 getFilePaths().push_back("/usr/lib");
1092 }
Daniel Dunbar75358d22009-03-30 21:06:03 +00001093}
1094
1095Tool &FreeBSD::SelectTool(const Compilation &C, const JobAction &JA) const {
1096 Action::ActionClass Key;
Daniel Dunbaree788e72009-12-21 18:54:17 +00001097 if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
Daniel Dunbar75358d22009-03-30 21:06:03 +00001098 Key = Action::AnalyzeJobClass;
1099 else
1100 Key = JA.getKind();
1101
Roman Divacky67dece72010-11-08 17:46:39 +00001102 bool UseIntegratedAs = C.getArgs().hasFlag(options::OPT_integrated_as,
1103 options::OPT_no_integrated_as,
1104 IsIntegratedAssemblerDefault());
1105
Daniel Dunbar75358d22009-03-30 21:06:03 +00001106 Tool *&T = Tools[Key];
1107 if (!T) {
1108 switch (Key) {
Daniel Dunbar68a31d42009-03-31 17:45:15 +00001109 case Action::AssembleJobClass:
Roman Divacky67dece72010-11-08 17:46:39 +00001110 if (UseIntegratedAs)
1111 T = new tools::ClangAs(*this);
1112 else
1113 T = new tools::freebsd::Assemble(*this);
Roman Divackyfe3a7ea2010-11-08 19:39:10 +00001114 break;
Daniel Dunbar008f54a2009-04-01 19:36:32 +00001115 case Action::LinkJobClass:
1116 T = new tools::freebsd::Link(*this); break;
Daniel Dunbar75358d22009-03-30 21:06:03 +00001117 default:
1118 T = &Generic_GCC::SelectTool(C, JA);
1119 }
1120 }
1121
1122 return *T;
1123}
Daniel Dunbar11e1b402009-05-02 18:28:39 +00001124
Chris Lattner38e317d2010-07-07 16:01:42 +00001125/// Minix - Minix tool chain which can call as(1) and ld(1) directly.
1126
1127Minix::Minix(const HostInfo &Host, const llvm::Triple& Triple)
1128 : Generic_GCC(Host, Triple) {
1129 getFilePaths().push_back(getDriver().Dir + "/../lib");
1130 getFilePaths().push_back("/usr/lib");
1131 getFilePaths().push_back("/usr/gnu/lib");
1132 getFilePaths().push_back("/usr/gnu/lib/gcc/i686-pc-minix/4.4.3");
1133}
1134
1135Tool &Minix::SelectTool(const Compilation &C, const JobAction &JA) const {
1136 Action::ActionClass Key;
1137 if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
1138 Key = Action::AnalyzeJobClass;
1139 else
1140 Key = JA.getKind();
1141
1142 Tool *&T = Tools[Key];
1143 if (!T) {
1144 switch (Key) {
1145 case Action::AssembleJobClass:
1146 T = new tools::minix::Assemble(*this); break;
1147 case Action::LinkJobClass:
1148 T = new tools::minix::Link(*this); break;
1149 default:
1150 T = &Generic_GCC::SelectTool(C, JA);
1151 }
1152 }
1153
1154 return *T;
1155}
1156
Edward O'Callaghane7925a02009-08-22 01:06:46 +00001157/// AuroraUX - AuroraUX tool chain which can call as(1) and ld(1) directly.
1158
1159AuroraUX::AuroraUX(const HostInfo &Host, const llvm::Triple& Triple)
1160 : Generic_GCC(Host, Triple) {
1161
Daniel Dunbaredf29b02010-08-01 22:29:51 +00001162 getProgramPaths().push_back(getDriver().getInstalledDir());
1163 if (getDriver().getInstalledDir() != getDriver().Dir.c_str())
1164 getProgramPaths().push_back(getDriver().Dir);
Edward O'Callaghane7925a02009-08-22 01:06:46 +00001165
Daniel Dunbaree788e72009-12-21 18:54:17 +00001166 getFilePaths().push_back(getDriver().Dir + "/../lib");
Edward O'Callaghane7925a02009-08-22 01:06:46 +00001167 getFilePaths().push_back("/usr/lib");
1168 getFilePaths().push_back("/usr/sfw/lib");
1169 getFilePaths().push_back("/opt/gcc4/lib");
Edward O'Callaghan7adf9492009-10-15 07:44:07 +00001170 getFilePaths().push_back("/opt/gcc4/lib/gcc/i386-pc-solaris2.11/4.2.4");
Edward O'Callaghane7925a02009-08-22 01:06:46 +00001171
1172}
1173
1174Tool &AuroraUX::SelectTool(const Compilation &C, const JobAction &JA) const {
1175 Action::ActionClass Key;
Daniel Dunbaree788e72009-12-21 18:54:17 +00001176 if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
Edward O'Callaghane7925a02009-08-22 01:06:46 +00001177 Key = Action::AnalyzeJobClass;
1178 else
1179 Key = JA.getKind();
1180
1181 Tool *&T = Tools[Key];
1182 if (!T) {
1183 switch (Key) {
1184 case Action::AssembleJobClass:
1185 T = new tools::auroraux::Assemble(*this); break;
1186 case Action::LinkJobClass:
1187 T = new tools::auroraux::Link(*this); break;
1188 default:
1189 T = &Generic_GCC::SelectTool(C, JA);
1190 }
1191 }
1192
1193 return *T;
1194}
1195
1196
Eli Friedman6b3454a2009-05-26 07:52:18 +00001197/// Linux toolchain (very bare-bones at the moment).
1198
Rafael Espindolac1da9812010-11-07 20:14:31 +00001199enum LinuxDistro {
1200 DebianLenny,
1201 DebianSqueeze,
Rafael Espindola0a84aee2010-11-11 02:07:13 +00001202 Exherbo,
Rafael Espindolac1da9812010-11-07 20:14:31 +00001203 Fedora13,
1204 Fedora14,
1205 OpenSuse11_3,
Rafael Espindola021aaa42010-11-10 05:00:22 +00001206 UbuntuJaunty,
Zhongxing Xu5ede8072010-11-15 09:01:52 +00001207 UbuntuKarmic,
Rafael Espindolac1da9812010-11-07 20:14:31 +00001208 UbuntuLucid,
1209 UbuntuMaverick,
1210 UnknownDistro
1211};
1212
1213static bool IsFedora(enum LinuxDistro Distro) {
1214 return Distro == Fedora13 || Distro == Fedora14;
1215}
1216
1217static bool IsOpenSuse(enum LinuxDistro Distro) {
1218 return Distro == OpenSuse11_3;
1219}
1220
1221static bool IsDebian(enum LinuxDistro Distro) {
1222 return Distro == DebianLenny || Distro == DebianSqueeze;
1223}
1224
1225static bool IsUbuntu(enum LinuxDistro Distro) {
Zhongxing Xu5ede8072010-11-15 09:01:52 +00001226 return Distro == UbuntuLucid || Distro == UbuntuMaverick ||
1227 Distro == UbuntuJaunty || Distro == UbuntuKarmic;
Rafael Espindolac1da9812010-11-07 20:14:31 +00001228}
1229
1230static bool IsDebianBased(enum LinuxDistro Distro) {
1231 return IsDebian(Distro) || IsUbuntu(Distro);
1232}
1233
1234static bool HasMultilib(llvm::Triple::ArchType Arch, enum LinuxDistro Distro) {
Rafael Espindola0a84aee2010-11-11 02:07:13 +00001235 if (Arch == llvm::Triple::x86_64) {
1236 if (Distro == Exherbo && !llvm::sys::Path("/usr/lib32/libc.so").exists())
1237 return false;
1238
Rafael Espindolac1da9812010-11-07 20:14:31 +00001239 return true;
Rafael Espindola0a84aee2010-11-11 02:07:13 +00001240 }
Rafael Espindolac1da9812010-11-07 20:14:31 +00001241 if (Arch == llvm::Triple::x86 && IsDebianBased(Distro))
1242 return true;
1243 return false;
1244}
1245
1246static LinuxDistro DetectLinuxDistro(llvm::Triple::ArchType Arch) {
Michael J. Spencer3a321e22010-12-09 17:36:38 +00001247 llvm::error_code ec;
Rafael Espindolac1da9812010-11-07 20:14:31 +00001248 llvm::OwningPtr<const llvm::MemoryBuffer>
Michael J. Spencer3a321e22010-12-09 17:36:38 +00001249 LsbRelease(llvm::MemoryBuffer::getFile("/etc/lsb-release", ec));
Rafael Espindolac1da9812010-11-07 20:14:31 +00001250 if (LsbRelease) {
1251 llvm::StringRef Data = LsbRelease.get()->getBuffer();
1252 llvm::SmallVector<llvm::StringRef, 8> Lines;
1253 Data.split(Lines, "\n");
1254 for (unsigned int i = 0, s = Lines.size(); i < s; ++ i) {
1255 if (Lines[i] == "DISTRIB_CODENAME=maverick")
1256 return UbuntuMaverick;
1257 else if (Lines[i] == "DISTRIB_CODENAME=lucid")
1258 return UbuntuLucid;
Rafael Espindola021aaa42010-11-10 05:00:22 +00001259 else if (Lines[i] == "DISTRIB_CODENAME=jaunty")
1260 return UbuntuJaunty;
Zhongxing Xu5ede8072010-11-15 09:01:52 +00001261 else if (Lines[i] == "DISTRIB_CODENAME=karmic")
1262 return UbuntuKarmic;
Rafael Espindolac1da9812010-11-07 20:14:31 +00001263 }
1264 return UnknownDistro;
1265 }
1266
1267 llvm::OwningPtr<const llvm::MemoryBuffer>
Michael J. Spencer3a321e22010-12-09 17:36:38 +00001268 RHRelease(llvm::MemoryBuffer::getFile("/etc/redhat-release", ec));
Rafael Espindolac1da9812010-11-07 20:14:31 +00001269 if (RHRelease) {
1270 llvm::StringRef Data = RHRelease.get()->getBuffer();
1271 if (Data.startswith("Fedora release 14 (Laughlin)"))
1272 return Fedora14;
1273 else if (Data.startswith("Fedora release 13 (Goddard)"))
1274 return Fedora13;
1275 return UnknownDistro;
1276 }
1277
1278 llvm::OwningPtr<const llvm::MemoryBuffer>
Michael J. Spencer3a321e22010-12-09 17:36:38 +00001279 DebianVersion(llvm::MemoryBuffer::getFile("/etc/debian_version", ec));
Rafael Espindolac1da9812010-11-07 20:14:31 +00001280 if (DebianVersion) {
1281 llvm::StringRef Data = DebianVersion.get()->getBuffer();
1282 if (Data[0] == '5')
1283 return DebianLenny;
1284 else if (Data.startswith("squeeze/sid"))
1285 return DebianSqueeze;
1286 return UnknownDistro;
1287 }
1288
1289 llvm::OwningPtr<const llvm::MemoryBuffer>
Michael J. Spencer3a321e22010-12-09 17:36:38 +00001290 SuseRelease(llvm::MemoryBuffer::getFile("/etc/SuSE-release", ec));
Rafael Espindolac1da9812010-11-07 20:14:31 +00001291 if (SuseRelease) {
1292 llvm::StringRef Data = SuseRelease.get()->getBuffer();
1293 if (Data.startswith("openSUSE 11.3"))
1294 return OpenSuse11_3;
1295 return UnknownDistro;
1296 }
1297
Rafael Espindola0a84aee2010-11-11 02:07:13 +00001298 if (llvm::sys::Path("/etc/exherbo-release").exists())
1299 return Exherbo;
1300
Rafael Espindolac1da9812010-11-07 20:14:31 +00001301 return UnknownDistro;
1302}
1303
Eli Friedman6b3454a2009-05-26 07:52:18 +00001304Linux::Linux(const HostInfo &Host, const llvm::Triple& Triple)
Rafael Espindolae43cfa12010-10-29 20:14:02 +00001305 : Generic_ELF(Host, Triple) {
Rafael Espindolac1da9812010-11-07 20:14:31 +00001306 llvm::Triple::ArchType Arch =
1307 llvm::Triple(getDriver().DefaultHostTriple).getArch();
Daniel Dunbara9822de2009-08-06 01:47:11 +00001308
Rafael Espindolac1da9812010-11-07 20:14:31 +00001309 std::string Suffix32 = "";
1310 if (Arch == llvm::Triple::x86_64)
1311 Suffix32 = "/32";
Daniel Dunbara9822de2009-08-06 01:47:11 +00001312
Rafael Espindolac1da9812010-11-07 20:14:31 +00001313 std::string Suffix64 = "";
1314 if (Arch == llvm::Triple::x86)
1315 Suffix64 = "/64";
1316
1317 std::string Lib32 = "lib";
1318
1319 if ( llvm::sys::Path("/lib32").exists())
1320 Lib32 = "lib32";
1321
1322 std::string Lib64 = "lib";
1323 llvm::sys::Path Lib64Path("/lib64");
1324 if (Lib64Path.exists() && !Lib64Path.isSymLink())
1325 Lib64 = "lib64";
1326
1327 std::string GccTriple = "";
1328 if (Arch == llvm::Triple::arm) {
1329 if (llvm::sys::Path("/usr/lib/gcc/arm-linux-gnueabi").exists())
1330 GccTriple = "arm-linux-gnueabi";
1331 } else if (Arch == llvm::Triple::x86_64) {
1332 if (llvm::sys::Path("/usr/lib/gcc/x86_64-linux-gnu").exists())
1333 GccTriple = "x86_64-linux-gnu";
Rafael Espindola53dd00b2010-11-17 00:25:26 +00001334 else if (llvm::sys::Path("/usr/lib/gcc/x86_64-unknown-linux-gnu").exists())
1335 GccTriple = "x86_64-unknown-linux-gnu";
Rafael Espindola0a84aee2010-11-11 02:07:13 +00001336 else if (llvm::sys::Path("/usr/lib/gcc/x86_64-pc-linux-gnu").exists())
1337 GccTriple = "x86_64-pc-linux-gnu";
Rafael Espindolac1da9812010-11-07 20:14:31 +00001338 else if (llvm::sys::Path("/usr/lib/gcc/x86_64-redhat-linux").exists())
1339 GccTriple = "x86_64-redhat-linux";
1340 else if (llvm::sys::Path("/usr/lib64/gcc/x86_64-suse-linux").exists())
1341 GccTriple = "x86_64-suse-linux";
1342 } else if (Arch == llvm::Triple::x86) {
1343 if (llvm::sys::Path("/usr/lib/gcc/i686-linux-gnu").exists())
1344 GccTriple = "i686-linux-gnu";
Rafael Espindola1d636c22010-11-28 01:08:36 +00001345 else if (llvm::sys::Path("/usr/lib/gcc/i686-pc-linux-gnu").exists())
Nuno Lopes2a69ddd2010-11-19 17:26:57 +00001346 GccTriple = "i686-pc-linux-gnu";
Rafael Espindolac1da9812010-11-07 20:14:31 +00001347 else if (llvm::sys::Path("/usr/lib/gcc/i486-linux-gnu").exists())
1348 GccTriple = "i486-linux-gnu";
1349 else if (llvm::sys::Path("/usr/lib/gcc/i686-redhat-linux").exists())
1350 GccTriple = "i686-redhat-linux";
1351 else if (llvm::sys::Path("/usr/lib/gcc/i586-suse-linux").exists())
1352 GccTriple = "i586-suse-linux";
1353 }
1354
Zhongxing Xu5ede8072010-11-15 09:01:52 +00001355 const char* GccVersions[] = {"4.5.1", "4.5", "4.4.5", "4.4.4", "4.4.3", "4.4",
Rafael Espindolae4539ef2010-11-19 21:02:06 +00001356 "4.3.4", "4.3.3", "4.3.2"};
Rafael Espindolac1da9812010-11-07 20:14:31 +00001357 std::string Base = "";
1358 for (unsigned i = 0; i < sizeof(GccVersions)/sizeof(char*); ++i) {
1359 std::string Suffix = GccTriple + "/" + GccVersions[i];
1360 std::string t1 = "/usr/lib/gcc/" + Suffix;
1361 if (llvm::sys::Path(t1 + "/crtbegin.o").exists()) {
1362 Base = t1;
1363 break;
1364 }
1365 std::string t2 = "/usr/lib64/gcc/" + Suffix;
1366 if (llvm::sys::Path(t2 + "/crtbegin.o").exists()) {
1367 Base = t2;
1368 break;
1369 }
1370 }
1371
1372 path_list &Paths = getFilePaths();
1373 bool Is32Bits = getArch() == llvm::Triple::x86;
1374
1375 std::string Suffix;
1376 std::string Lib;
1377
1378 if (Is32Bits) {
1379 Suffix = Suffix32;
1380 Lib = Lib32;
1381 } else {
1382 Suffix = Suffix64;
1383 Lib = Lib64;
1384 }
1385
1386 llvm::sys::Path LinkerPath(Base + "/../../../../" + GccTriple + "/bin/ld");
1387 if (LinkerPath.exists())
1388 Linker = LinkerPath.str();
1389 else
1390 Linker = GetProgramPath("ld");
1391
1392 LinuxDistro Distro = DetectLinuxDistro(Arch);
1393
Rafael Espindola94c80222010-11-08 14:48:47 +00001394 if (IsUbuntu(Distro)) {
1395 ExtraOpts.push_back("-z");
1396 ExtraOpts.push_back("relro");
1397 }
Rafael Espindolac1da9812010-11-07 20:14:31 +00001398
1399 if (Arch == llvm::Triple::arm)
1400 ExtraOpts.push_back("-X");
1401
1402 if (IsFedora(Distro) || Distro == UbuntuMaverick)
1403 ExtraOpts.push_back("--hash-style=gnu");
1404
Zhongxing Xu5ede8072010-11-15 09:01:52 +00001405 if (IsDebian(Distro) || Distro == UbuntuLucid || Distro == UbuntuJaunty ||
1406 Distro == UbuntuKarmic)
Rafael Espindolac1da9812010-11-07 20:14:31 +00001407 ExtraOpts.push_back("--hash-style=both");
1408
1409 if (IsFedora(Distro))
1410 ExtraOpts.push_back("--no-add-needed");
1411
Rafael Espindola021aaa42010-11-10 05:00:22 +00001412 if (Distro == DebianSqueeze || IsOpenSuse(Distro) ||
Zhongxing Xu5ede8072010-11-15 09:01:52 +00001413 IsFedora(Distro) || Distro == UbuntuLucid || Distro == UbuntuMaverick ||
1414 Distro == UbuntuKarmic)
Rafael Espindolac1da9812010-11-07 20:14:31 +00001415 ExtraOpts.push_back("--build-id");
1416
1417 Paths.push_back(Base + Suffix);
1418 if (HasMultilib(Arch, Distro)) {
1419 if (IsOpenSuse(Distro) && Is32Bits)
1420 Paths.push_back(Base + "/../../../../" + GccTriple + "/lib/../lib");
1421 Paths.push_back(Base + "/../../../../" + Lib);
1422 Paths.push_back("/lib/../" + Lib);
1423 Paths.push_back("/usr/lib/../" + Lib);
1424 }
1425 if (!Suffix.empty())
1426 Paths.push_back(Base);
1427 if (IsOpenSuse(Distro))
1428 Paths.push_back(Base + "/../../../../" + GccTriple + "/lib");
1429 Paths.push_back(Base + "/../../..");
1430 if (Arch == getArch() && IsUbuntu(Distro))
1431 Paths.push_back("/usr/lib/" + GccTriple);
1432}
1433
1434bool Linux::HasNativeLLVMSupport() const {
1435 return true;
Eli Friedman6b3454a2009-05-26 07:52:18 +00001436}
1437
Rafael Espindolaba30bbe2010-08-10 00:25:48 +00001438Tool &Linux::SelectTool(const Compilation &C, const JobAction &JA) const {
1439 Action::ActionClass Key;
1440 if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
1441 Key = Action::AnalyzeJobClass;
1442 else
1443 Key = JA.getKind();
1444
Rafael Espindoladda5b922010-11-07 23:13:01 +00001445 bool UseIntegratedAs = C.getArgs().hasFlag(options::OPT_integrated_as,
1446 options::OPT_no_integrated_as,
1447 IsIntegratedAssemblerDefault());
1448
Rafael Espindolaba30bbe2010-08-10 00:25:48 +00001449 Tool *&T = Tools[Key];
1450 if (!T) {
1451 switch (Key) {
1452 case Action::AssembleJobClass:
Rafael Espindoladda5b922010-11-07 23:13:01 +00001453 if (UseIntegratedAs)
1454 T = new tools::ClangAs(*this);
1455 else
1456 T = new tools::linuxtools::Assemble(*this);
1457 break;
Rafael Espindolac1da9812010-11-07 20:14:31 +00001458 case Action::LinkJobClass:
1459 T = new tools::linuxtools::Link(*this); break;
Rafael Espindolaba30bbe2010-08-10 00:25:48 +00001460 default:
1461 T = &Generic_GCC::SelectTool(C, JA);
1462 }
1463 }
1464
1465 return *T;
1466}
1467
Daniel Dunbar11e1b402009-05-02 18:28:39 +00001468/// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly.
1469
Daniel Dunbarcb8ab232009-05-22 02:53:45 +00001470DragonFly::DragonFly(const HostInfo &Host, const llvm::Triple& Triple)
Rafael Espindolae43cfa12010-10-29 20:14:02 +00001471 : Generic_ELF(Host, Triple) {
Daniel Dunbar11e1b402009-05-02 18:28:39 +00001472
1473 // Path mangling to find libexec
Daniel Dunbaredf29b02010-08-01 22:29:51 +00001474 getProgramPaths().push_back(getDriver().getInstalledDir());
1475 if (getDriver().getInstalledDir() != getDriver().Dir.c_str())
1476 getProgramPaths().push_back(getDriver().Dir);
Daniel Dunbar11e1b402009-05-02 18:28:39 +00001477
Daniel Dunbaree788e72009-12-21 18:54:17 +00001478 getFilePaths().push_back(getDriver().Dir + "/../lib");
Daniel Dunbar11e1b402009-05-02 18:28:39 +00001479 getFilePaths().push_back("/usr/lib");
1480 getFilePaths().push_back("/usr/lib/gcc41");
1481}
1482
1483Tool &DragonFly::SelectTool(const Compilation &C, const JobAction &JA) const {
1484 Action::ActionClass Key;
Daniel Dunbaree788e72009-12-21 18:54:17 +00001485 if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
Daniel Dunbar11e1b402009-05-02 18:28:39 +00001486 Key = Action::AnalyzeJobClass;
1487 else
1488 Key = JA.getKind();
1489
1490 Tool *&T = Tools[Key];
1491 if (!T) {
1492 switch (Key) {
1493 case Action::AssembleJobClass:
1494 T = new tools::dragonfly::Assemble(*this); break;
1495 case Action::LinkJobClass:
1496 T = new tools::dragonfly::Link(*this); break;
1497 default:
1498 T = &Generic_GCC::SelectTool(C, JA);
1499 }
1500 }
1501
1502 return *T;
1503}
Michael J. Spencerff58e362010-08-21 21:55:07 +00001504
1505Windows::Windows(const HostInfo &Host, const llvm::Triple& Triple)
1506 : ToolChain(Host, Triple) {
1507}
1508
1509Tool &Windows::SelectTool(const Compilation &C, const JobAction &JA) const {
1510 Action::ActionClass Key;
1511 if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
1512 Key = Action::AnalyzeJobClass;
1513 else
1514 Key = JA.getKind();
1515
1516 Tool *&T = Tools[Key];
1517 if (!T) {
1518 switch (Key) {
1519 case Action::InputClass:
1520 case Action::BindArchClass:
Chandler Carruthe97673f2010-08-22 06:56:37 +00001521 case Action::LipoJobClass:
1522 case Action::DsymutilJobClass:
Michael J. Spencerff58e362010-08-21 21:55:07 +00001523 assert(0 && "Invalid tool kind.");
1524 case Action::PreprocessJobClass:
1525 case Action::PrecompileJobClass:
1526 case Action::AnalyzeJobClass:
1527 case Action::CompileJobClass:
1528 T = new tools::Clang(*this); break;
1529 case Action::AssembleJobClass:
1530 T = new tools::ClangAs(*this); break;
1531 case Action::LinkJobClass:
1532 T = new tools::visualstudio::Link(*this); break;
1533 }
1534 }
1535
1536 return *T;
1537}
1538
1539bool Windows::IsIntegratedAssemblerDefault() const {
1540 return true;
1541}
1542
1543bool Windows::IsUnwindTablesDefault() const {
1544 // FIXME: Gross; we should probably have some separate target
1545 // definition, possibly even reusing the one in clang.
1546 return getArchName() == "x86_64";
1547}
1548
1549const char *Windows::GetDefaultRelocationModel() const {
1550 return "static";
1551}
1552
1553const char *Windows::GetForcedPicModel() const {
1554 if (getArchName() == "x86_64")
1555 return "pic";
1556 return 0;
1557}