blob: 79f96cdaeac80b9d77808125ecf1ee3841394346 [file] [log] [blame]
Hans Wennborgdcfba332015-10-06 23:40:43 +00001//===--- ToolChains.cpp - ToolChain Implementations -------------*- C++ -*-===//
Daniel Dunbar59e5e882009-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"
Justin Lebarc43ad9e2016-07-07 18:17:52 +000011#include "clang/Basic/Cuda.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000012#include "clang/Basic/ObjCRuntime.h"
13#include "clang/Basic/Version.h"
Benjamin Kramerd45b2052015-10-07 15:48:01 +000014#include "clang/Basic/VirtualFileSystem.h"
Alp Toker1d257e12014-06-04 03:28:55 +000015#include "clang/Config/config.h" // for GCC_INSTALL_PREFIX
Daniel Dunbar6232d342010-05-20 21:48:38 +000016#include "clang/Driver/Compilation.h"
Daniel Dunbar76ce7412009-03-23 16:15:50 +000017#include "clang/Driver/Driver.h"
Daniel Dunbaraabb0b12009-03-25 06:12:34 +000018#include "clang/Driver/DriverDiagnostic.h"
Daniel Dunbarda13faf2009-11-19 04:25:22 +000019#include "clang/Driver/Options.h"
Alexey Samsonov609213f92013-08-19 09:14:21 +000020#include "clang/Driver/SanitizerArgs.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000021#include "llvm/ADT/STLExtras.h"
Daniel Dunbar82eb4ce2010-08-23 22:35:37 +000022#include "llvm/ADT/SmallString.h"
Daniel Dunbar76ce7412009-03-23 16:15:50 +000023#include "llvm/ADT/StringExtras.h"
Bob Wilson997a97f2011-10-07 00:37:57 +000024#include "llvm/ADT/StringSwitch.h"
Reid Kleckner898229a2013-06-14 17:17:23 +000025#include "llvm/Option/Arg.h"
26#include "llvm/Option/ArgList.h"
27#include "llvm/Option/OptTable.h"
28#include "llvm/Option/Option.h"
Xinliang David Li170cd102015-10-27 05:15:35 +000029#include "llvm/ProfileData/InstrProf.h"
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +000030#include "llvm/Support/ErrorHandling.h"
Michael J. Spencerf6efe582011-01-10 02:34:13 +000031#include "llvm/Support/FileSystem.h"
Rafael Espindolac8f008f2010-11-07 20:14:31 +000032#include "llvm/Support/MemoryBuffer.h"
Michael J. Spencer8aaf4992010-11-29 18:12:39 +000033#include "llvm/Support/Path.h"
Chandler Carruth5553d0d2014-01-07 11:51:46 +000034#include "llvm/Support/Program.h"
Renato Golin33e1f822015-05-28 15:49:28 +000035#include "llvm/Support/TargetParser.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000036#include "llvm/Support/raw_ostream.h"
Daniel Dunbarb5023e92009-04-10 21:00:07 +000037#include <cstdlib> // ::getenv
Rafael Espindola8a8e5542014-06-12 17:19:42 +000038#include <system_error>
Daniel Dunbarb5023e92009-04-10 21:00:07 +000039
Daniel Dunbar59e5e882009-03-20 00:20:03 +000040using namespace clang::driver;
41using namespace clang::driver::toolchains;
Chris Lattner0e62c1c2011-07-23 10:55:15 +000042using namespace clang;
Reid Kleckner898229a2013-06-14 17:17:23 +000043using namespace llvm::opt;
Daniel Dunbar59e5e882009-03-20 00:20:03 +000044
Douglas Katzmana67e50c2015-06-26 15:47:46 +000045MachO::MachO(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
46 : ToolChain(D, Triple, Args) {
Tim Northover15ff71d2014-05-22 13:12:14 +000047 // We expect 'as', 'ld', etc. to be adjacent to our install dir.
48 getProgramPaths().push_back(getDriver().getInstalledDir());
49 if (getDriver().getInstalledDir() != getDriver().Dir)
50 getProgramPaths().push_back(getDriver().Dir);
Tim Northover157d9112014-01-16 08:48:16 +000051}
Daniel Dunbar03e0a4f2009-03-20 00:57:52 +000052
Tim Northover157d9112014-01-16 08:48:16 +000053/// Darwin - Darwin tool chain for i386 and x86_64.
Alexey Samsonov905c8022015-06-18 21:46:05 +000054Darwin::Darwin(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
55 : MachO(D, Triple, Args), TargetInitialized(false) {}
Daniel Dunbar6276f992009-09-18 08:15:13 +000056
Tim Northover157d9112014-01-16 08:48:16 +000057types::ID MachO::LookupTypeForExtension(const char *Ext) const {
Daniel Dunbarcc7df6c2010-08-02 05:43:56 +000058 types::ID Ty = types::lookupTypeForExtension(Ext);
59
60 // Darwin always preprocesses assembly files (unless -x is used explicitly).
61 if (Ty == types::TY_PP_Asm)
62 return types::TY_Asm;
63
64 return Ty;
65}
66
Douglas Katzmana67e50c2015-06-26 15:47:46 +000067bool MachO::HasNativeLLVMSupport() const { return true; }
Daniel Dunbar62123a12010-09-17 00:24:52 +000068
Jonas Hahnfeldaae83742016-02-12 07:48:37 +000069ToolChain::CXXStdlibType Darwin::GetDefaultCXXStdlibType() const {
70 // Default to use libc++ on OS X 10.9+ and iOS 7+.
71 if ((isTargetMacOS() && !isMacosxVersionLT(10, 9)) ||
72 (isTargetIOSBased() && !isIPhoneOSVersionLT(7, 0)) ||
73 isTargetWatchOSBased())
74 return ToolChain::CST_Libcxx;
75
76 return ToolChain::CST_Libstdcxx;
77}
78
John McCall24fc0de2011-07-06 00:26:06 +000079/// Darwin provides an ARC runtime starting in MacOS X 10.7 and iOS 5.0.
John McCall5fb5df92012-06-20 06:18:46 +000080ObjCRuntime Darwin::getDefaultObjCRuntime(bool isNonFragile) const {
Tim Northover6f3ff222015-10-30 16:30:27 +000081 if (isTargetWatchOSBased())
Tim Northover756447a2015-10-30 16:30:36 +000082 return ObjCRuntime(ObjCRuntime::WatchOS, TargetVersion);
Tim Northover9c7e0352013-12-12 11:55:52 +000083 if (isTargetIOSBased())
John McCall5fb5df92012-06-20 06:18:46 +000084 return ObjCRuntime(ObjCRuntime::iOS, TargetVersion);
Bob Wilson5ad5a952012-11-09 01:59:30 +000085 if (isNonFragile)
86 return ObjCRuntime(ObjCRuntime::MacOSX, TargetVersion);
87 return ObjCRuntime(ObjCRuntime::FragileMacOSX, TargetVersion);
John McCall24fc0de2011-07-06 00:26:06 +000088}
89
John McCall7959fee2011-09-09 20:41:01 +000090/// Darwin provides a blocks runtime starting in MacOS X 10.6 and iOS 3.2.
91bool Darwin::hasBlocksRuntime() const {
Tim Northover6f3ff222015-10-30 16:30:27 +000092 if (isTargetWatchOSBased())
93 return true;
94 else if (isTargetIOSBased())
John McCall7959fee2011-09-09 20:41:01 +000095 return !isIPhoneOSVersionLT(3, 2);
Tim Northover9c7e0352013-12-12 11:55:52 +000096 else {
Tim Northover157d9112014-01-16 08:48:16 +000097 assert(isTargetMacOS() && "unexpected darwin target");
98 return !isMacosxVersionLT(10, 6);
Tim Northover9c7e0352013-12-12 11:55:52 +000099 }
John McCall7959fee2011-09-09 20:41:01 +0000100}
101
Renato Golin33e1f822015-05-28 15:49:28 +0000102// This is just a MachO name translation routine and there's no
103// way to join this into ARMTargetParser without breaking all
104// other assumptions. Maybe MachO should consider standardising
105// their nomenclature.
106static const char *ArmMachOArchName(StringRef Arch) {
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000107 return llvm::StringSwitch<const char *>(Arch)
108 .Case("armv6k", "armv6")
109 .Case("armv6m", "armv6m")
110 .Case("armv5tej", "armv5")
111 .Case("xscale", "xscale")
112 .Case("armv4t", "armv4t")
113 .Case("armv7", "armv7")
114 .Cases("armv7a", "armv7-a", "armv7")
115 .Cases("armv7r", "armv7-r", "armv7")
116 .Cases("armv7em", "armv7e-m", "armv7em")
117 .Cases("armv7k", "armv7-k", "armv7k")
118 .Cases("armv7m", "armv7-m", "armv7m")
119 .Cases("armv7s", "armv7-s", "armv7s")
120 .Default(nullptr);
Daniel Dunbardcc3b652010-01-22 02:04:58 +0000121}
122
Renato Golin33e1f822015-05-28 15:49:28 +0000123static const char *ArmMachOArchNameCPU(StringRef CPU) {
Chandler Carruthaa0caeb2015-08-30 02:16:36 +0000124 unsigned ArchKind = llvm::ARM::parseCPUArch(CPU);
Renato Golin33e1f822015-05-28 15:49:28 +0000125 if (ArchKind == llvm::ARM::AK_INVALID)
126 return nullptr;
Chandler Carruthaa0caeb2015-08-30 02:16:36 +0000127 StringRef Arch = llvm::ARM::getArchName(ArchKind);
Renato Golin33e1f822015-05-28 15:49:28 +0000128
129 // FIXME: Make sure this MachO triple mangling is really necessary.
130 // ARMv5* normalises to ARMv5.
131 if (Arch.startswith("armv5"))
132 Arch = Arch.substr(0, 5);
133 // ARMv6*, except ARMv6M, normalises to ARMv6.
134 else if (Arch.startswith("armv6") && !Arch.endswith("6m"))
135 Arch = Arch.substr(0, 5);
136 // ARMv7A normalises to ARMv7.
137 else if (Arch.endswith("v7a"))
138 Arch = Arch.substr(0, 5);
139 return Arch.data();
Daniel Dunbardcc3b652010-01-22 02:04:58 +0000140}
141
Tim Northover9c7e0352013-12-12 11:55:52 +0000142static bool isSoftFloatABI(const ArgList &Args) {
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +0000143 Arg *A = Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
Tim Northover9c7e0352013-12-12 11:55:52 +0000144 options::OPT_mfloat_abi_EQ);
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +0000145 if (!A)
146 return false;
Rafael Auler3f7abf72014-09-29 21:50:34 +0000147
Tim Northover9c7e0352013-12-12 11:55:52 +0000148 return A->getOption().matches(options::OPT_msoft_float) ||
149 (A->getOption().matches(options::OPT_mfloat_abi_EQ) &&
150 A->getValue() == StringRef("soft"));
151}
152
Tim Northover157d9112014-01-16 08:48:16 +0000153StringRef MachO::getMachOArchName(const ArgList &Args) const {
Daniel Dunbardcc3b652010-01-22 02:04:58 +0000154 switch (getTriple().getArch()) {
155 default:
Rafael Espindolaed1233e2014-08-28 21:23:05 +0000156 return getDefaultUniversalArchName();
NAKAMURA Takumi8b73b3e2011-06-03 03:49:51 +0000157
Tim Northover40956e62014-07-23 12:32:58 +0000158 case llvm::Triple::aarch64:
159 return "arm64";
160
Douglas Gregord9bb1522011-03-06 19:11:49 +0000161 case llvm::Triple::thumb:
Hans Wennborgdcfba332015-10-06 23:40:43 +0000162 case llvm::Triple::arm:
Daniel Dunbardcc3b652010-01-22 02:04:58 +0000163 if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
Renato Golin33e1f822015-05-28 15:49:28 +0000164 if (const char *Arch = ArmMachOArchName(A->getValue()))
Daniel Dunbardcc3b652010-01-22 02:04:58 +0000165 return Arch;
166
167 if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
Renato Golin33e1f822015-05-28 15:49:28 +0000168 if (const char *Arch = ArmMachOArchNameCPU(A->getValue()))
Daniel Dunbardcc3b652010-01-22 02:04:58 +0000169 return Arch;
170
171 return "arm";
172 }
Daniel Dunbardcc3b652010-01-22 02:04:58 +0000173}
174
Angel Garcia Gomez637d1e62015-10-20 13:23:58 +0000175Darwin::~Darwin() {}
Daniel Dunbar03e0a4f2009-03-20 00:57:52 +0000176
Angel Garcia Gomez637d1e62015-10-20 13:23:58 +0000177MachO::~MachO() {}
Tim Northover157d9112014-01-16 08:48:16 +0000178
179std::string MachO::ComputeEffectiveClangTriple(const ArgList &Args,
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000180 types::ID InputType) const {
Tim Northover157d9112014-01-16 08:48:16 +0000181 llvm::Triple Triple(ComputeLLVMTriple(Args, InputType));
182
183 return Triple.getTriple();
184}
185
Chad Rosierd3a0f952011-09-20 20:44:06 +0000186std::string Darwin::ComputeEffectiveClangTriple(const ArgList &Args,
187 types::ID InputType) const {
188 llvm::Triple Triple(ComputeLLVMTriple(Args, InputType));
Daniel Dunbar82eb4ce2010-08-23 22:35:37 +0000189
190 // If the target isn't initialized (e.g., an unknown Darwin platform, return
191 // the default triple).
192 if (!isTargetInitialized())
193 return Triple.getTriple();
NAKAMURA Takumi8b73b3e2011-06-03 03:49:51 +0000194
Tim Northover157d9112014-01-16 08:48:16 +0000195 SmallString<16> Str;
Tim Northover6f3ff222015-10-30 16:30:27 +0000196 if (isTargetWatchOSBased())
197 Str += "watchos";
198 else if (isTargetTvOSBased())
199 Str += "tvos";
200 else if (isTargetIOSBased())
201 Str += "ios";
202 else
203 Str += "macosx";
Tim Northover157d9112014-01-16 08:48:16 +0000204 Str += getTargetVersion().getAsString();
205 Triple.setOSName(Str);
Daniel Dunbar82eb4ce2010-08-23 22:35:37 +0000206
207 return Triple.getTriple();
208}
209
David Blaikie68e081d2011-12-20 02:48:34 +0000210void Generic_ELF::anchor() {}
211
Tim Northover157d9112014-01-16 08:48:16 +0000212Tool *MachO::getTool(Action::ActionClass AC) const {
Rafael Espindola260e28d2013-03-18 20:48:54 +0000213 switch (AC) {
Rafael Espindolac8e3a012013-03-18 18:50:01 +0000214 case Action::LipoJobClass:
Rafael Espindola7cf32212013-03-20 03:05:54 +0000215 if (!Lipo)
216 Lipo.reset(new tools::darwin::Lipo(*this));
217 return Lipo.get();
Rafael Espindolac8e3a012013-03-18 18:50:01 +0000218 case Action::DsymutilJobClass:
Rafael Espindola7cf32212013-03-20 03:05:54 +0000219 if (!Dsymutil)
220 Dsymutil.reset(new tools::darwin::Dsymutil(*this));
221 return Dsymutil.get();
Ben Langmuir9b9a8d32014-02-06 18:53:25 +0000222 case Action::VerifyDebugInfoJobClass:
Rafael Espindola7cf32212013-03-20 03:05:54 +0000223 if (!VerifyDebug)
224 VerifyDebug.reset(new tools::darwin::VerifyDebug(*this));
225 return VerifyDebug.get();
Rafael Espindolad15a8912013-03-19 00:36:57 +0000226 default:
Rafael Espindola7cf32212013-03-20 03:05:54 +0000227 return ToolChain::getTool(AC);
Daniel Dunbar03e0a4f2009-03-20 00:57:52 +0000228 }
Daniel Dunbar03e0a4f2009-03-20 00:57:52 +0000229}
230
Douglas Katzman95354292015-06-23 20:42:09 +0000231Tool *MachO::buildLinker() const { return new tools::darwin::Linker(*this); }
Rafael Espindola7cf32212013-03-20 03:05:54 +0000232
Tim Northover157d9112014-01-16 08:48:16 +0000233Tool *MachO::buildAssembler() const {
Douglas Katzman95354292015-06-23 20:42:09 +0000234 return new tools::darwin::Assembler(*this);
Rafael Espindola7cf32212013-03-20 03:05:54 +0000235}
Daniel Dunbar26d482a2009-09-18 08:15:03 +0000236
Douglas Katzman95354292015-06-23 20:42:09 +0000237DarwinClang::DarwinClang(const Driver &D, const llvm::Triple &Triple,
Rafael Espindola84b588b2013-03-18 18:10:27 +0000238 const ArgList &Args)
Douglas Katzman95354292015-06-23 20:42:09 +0000239 : Darwin(D, Triple, Args) {}
Daniel Dunbar6276f992009-09-18 08:15:13 +0000240
Tim Northover336f1892014-03-29 13:16:12 +0000241void DarwinClang::addClangWarningOptions(ArgStringList &CC1Args) const {
Tim Northover6f3ff222015-10-30 16:30:27 +0000242 // For modern targets, promote certain warnings to errors.
243 if (isTargetWatchOSBased() || getTriple().isArch64Bit()) {
Tim Northover336f1892014-03-29 13:16:12 +0000244 // Always enable -Wdeprecated-objc-isa-usage and promote it
245 // to an error.
246 CC1Args.push_back("-Wdeprecated-objc-isa-usage");
247 CC1Args.push_back("-Werror=deprecated-objc-isa-usage");
248
Tim Northover6f3ff222015-10-30 16:30:27 +0000249 // For iOS and watchOS, also error about implicit function declarations,
250 // as that can impact calling conventions.
251 if (!isTargetMacOS())
252 CC1Args.push_back("-Werror=implicit-function-declaration");
Tim Northover336f1892014-03-29 13:16:12 +0000253 }
254}
255
Tim Northover157d9112014-01-16 08:48:16 +0000256/// \brief Determine whether Objective-C automated reference counting is
257/// enabled.
258static bool isObjCAutoRefCount(const ArgList &Args) {
259 return Args.hasFlag(options::OPT_fobjc_arc, options::OPT_fno_objc_arc, false);
260}
261
John McCall31168b02011-06-15 23:02:42 +0000262void DarwinClang::AddLinkARCArgs(const ArgList &Args,
263 ArgStringList &CmdArgs) const {
Tim Northover157d9112014-01-16 08:48:16 +0000264 // Avoid linking compatibility stubs on i386 mac.
265 if (isTargetMacOS() && getArch() == llvm::Triple::x86)
266 return;
267
268 ObjCRuntime runtime = getDefaultObjCRuntime(/*nonfragile*/ true);
269
270 if ((runtime.hasNativeARC() || !isObjCAutoRefCount(Args)) &&
271 runtime.hasSubscripting())
272 return;
Eric Christopher551ef452011-08-23 17:56:55 +0000273
274 CmdArgs.push_back("-force_load");
Rafael Espindola358256c2013-06-26 02:13:00 +0000275 SmallString<128> P(getDriver().ClangExecutable);
276 llvm::sys::path::remove_filename(P); // 'clang'
277 llvm::sys::path::remove_filename(P); // 'bin'
Benjamin Kramer17381a02013-06-28 16:25:46 +0000278 llvm::sys::path::append(P, "lib", "arc", "libarclite_");
John McCall31168b02011-06-15 23:02:42 +0000279 // Mash in the platform.
Tim Northover6f3ff222015-10-30 16:30:27 +0000280 if (isTargetWatchOSSimulator())
281 P += "watchsimulator";
282 else if (isTargetWatchOS())
283 P += "watchos";
284 else if (isTargetTvOSSimulator())
285 P += "appletvsimulator";
286 else if (isTargetTvOS())
287 P += "appletvos";
288 else if (isTargetIOSSimulator())
Rafael Espindola358256c2013-06-26 02:13:00 +0000289 P += "iphonesimulator";
Argyrios Kyrtzidis058b4512011-10-18 17:40:15 +0000290 else if (isTargetIPhoneOS())
Rafael Espindola358256c2013-06-26 02:13:00 +0000291 P += "iphoneos";
John McCall31168b02011-06-15 23:02:42 +0000292 else
Rafael Espindola358256c2013-06-26 02:13:00 +0000293 P += "macosx";
294 P += ".a";
John McCall31168b02011-06-15 23:02:42 +0000295
Rafael Espindola358256c2013-06-26 02:13:00 +0000296 CmdArgs.push_back(Args.MakeArgString(P));
John McCall31168b02011-06-15 23:02:42 +0000297}
298
Tim Northover157d9112014-01-16 08:48:16 +0000299void MachO::AddLinkRuntimeLib(const ArgList &Args, ArgStringList &CmdArgs,
Kuba Brecka2735a0252014-10-31 00:08:57 +0000300 StringRef DarwinLibName, bool AlwaysLink,
Kuba Brecka9ff912d2014-11-04 17:35:17 +0000301 bool IsEmbedded, bool AddRPath) const {
302 SmallString<128> Dir(getDriver().ResourceDir);
303 llvm::sys::path::append(Dir, "lib", IsEmbedded ? "macho_embedded" : "darwin");
304
305 SmallString<128> P(Dir);
306 llvm::sys::path::append(P, DarwinLibName);
Eric Christopher551ef452011-08-23 17:56:55 +0000307
Eric Christopherc235d0c62011-06-22 17:41:40 +0000308 // For now, allow missing resource libraries to support developers who may
Alexey Samsonov8368b372012-11-21 14:17:42 +0000309 // not have compiler-rt checked out or integrated into their build (unless
310 // we explicitly force linking with this library).
Benjamin Kramerd45b2052015-10-07 15:48:01 +0000311 if (AlwaysLink || getVFS().exists(P))
Yaron Keren92e1b622015-03-18 10:17:07 +0000312 CmdArgs.push_back(Args.MakeArgString(P));
Kuba Brecka9ff912d2014-11-04 17:35:17 +0000313
314 // Adding the rpaths might negatively interact when other rpaths are involved,
315 // so we should make sure we add the rpaths last, after all user-specified
316 // rpaths. This is currently true from this place, but we need to be
317 // careful if this function is ever called before user's rpaths are emitted.
318 if (AddRPath) {
319 assert(DarwinLibName.endswith(".dylib") && "must be a dynamic library");
320
321 // Add @executable_path to rpath to support having the dylib copied with
322 // the executable.
323 CmdArgs.push_back("-rpath");
324 CmdArgs.push_back("@executable_path");
325
326 // Add the path to the resource dir to rpath to support using the dylib
327 // from the default location without copying.
328 CmdArgs.push_back("-rpath");
Yaron Keren92e1b622015-03-18 10:17:07 +0000329 CmdArgs.push_back(Args.MakeArgString(Dir));
Kuba Brecka9ff912d2014-11-04 17:35:17 +0000330 }
Eric Christopherc235d0c62011-06-22 17:41:40 +0000331}
332
Chris Bienemane60e7c22016-04-29 22:28:34 +0000333StringRef Darwin::getPlatformFamily() const {
334 switch (TargetPlatform) {
335 case DarwinPlatformKind::MacOS:
336 return "MacOSX";
337 case DarwinPlatformKind::IPhoneOS:
338 case DarwinPlatformKind::IPhoneOSSimulator:
339 return "iPhone";
340 case DarwinPlatformKind::TvOS:
341 case DarwinPlatformKind::TvOSSimulator:
342 return "AppleTV";
343 case DarwinPlatformKind::WatchOS:
344 case DarwinPlatformKind::WatchOSSimulator:
345 return "Watch";
346 }
347 llvm_unreachable("Unsupported platform");
348}
349
350StringRef Darwin::getSDKName(StringRef isysroot) {
351 // Assume SDK has path: SOME_PATH/SDKs/PlatformXX.YY.sdk
352 llvm::sys::path::const_iterator SDKDir;
353 auto BeginSDK = llvm::sys::path::begin(isysroot);
354 auto EndSDK = llvm::sys::path::end(isysroot);
355 for (auto IT = BeginSDK; IT != EndSDK; ++IT) {
356 StringRef SDK = *IT;
357 if (SDK.endswith(".sdk"))
358 return SDK.slice(0, SDK.size() - 4);
359 }
360 return "";
361}
362
Anna Zakse67b4022016-02-02 02:04:48 +0000363StringRef Darwin::getOSLibraryNameSuffix() const {
364 switch(TargetPlatform) {
365 case DarwinPlatformKind::MacOS:
366 return "osx";
367 case DarwinPlatformKind::IPhoneOS:
368 return "ios";
369 case DarwinPlatformKind::IPhoneOSSimulator:
370 return "iossim";
371 case DarwinPlatformKind::TvOS:
372 return "tvos";
373 case DarwinPlatformKind::TvOSSimulator:
374 return "tvossim";
375 case DarwinPlatformKind::WatchOS:
376 return "watchos";
377 case DarwinPlatformKind::WatchOSSimulator:
378 return "watchossim";
379 }
380 llvm_unreachable("Unsupported platform");
381}
382
Vedant Kumarbf51e702016-07-18 19:56:38 +0000383void Darwin::addProfileRTLibs(const llvm::Triple &EffectiveTriple,
384 const ArgList &Args,
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000385 ArgStringList &CmdArgs) const {
Vedant Kumarbf51e702016-07-18 19:56:38 +0000386 if (!needsProfileRT(Args))
387 return;
Justin Bognerc7701242015-05-12 05:44:36 +0000388
Vedant Kumarbf51e702016-07-18 19:56:38 +0000389 AddLinkRuntimeLib(
390 Args, CmdArgs,
391 (Twine("libclang_rt.profile_") + getOSLibraryNameSuffix() + ".a").str(),
392 /*AlwaysLink*/ true);
Justin Bognerc7701242015-05-12 05:44:36 +0000393}
394
Alexey Samsonov498f3c32015-03-23 23:14:05 +0000395void DarwinClang::AddLinkSanitizerLibArgs(const ArgList &Args,
396 ArgStringList &CmdArgs,
397 StringRef Sanitizer) const {
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000398 AddLinkRuntimeLib(
399 Args, CmdArgs,
Anna Zakse67b4022016-02-02 02:04:48 +0000400 (Twine("libclang_rt.") + Sanitizer + "_" +
401 getOSLibraryNameSuffix() + "_dynamic.dylib").str(),
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000402 /*AlwaysLink*/ true, /*IsEmbedded*/ false,
403 /*AddRPath*/ true);
Alexey Samsonov498f3c32015-03-23 23:14:05 +0000404}
405
Vedant Kumarbf51e702016-07-18 19:56:38 +0000406void DarwinClang::AddLinkRuntimeLibArgs(const llvm::Triple &EffectiveTriple,
407 const ArgList &Args,
Daniel Dunbar6276f992009-09-18 08:15:13 +0000408 ArgStringList &CmdArgs) const {
Daniel Dunbarf4916cd2011-12-07 23:03:15 +0000409 // Darwin only supports the compiler-rt based runtime libraries.
410 switch (GetRuntimeLibType(Args)) {
411 case ToolChain::RLT_CompilerRT:
412 break;
413 default:
414 getDriver().Diag(diag::err_drv_unsupported_rtlib_for_platform)
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000415 << Args.getLastArg(options::OPT_rtlib_EQ)->getValue() << "darwin";
Daniel Dunbarf4916cd2011-12-07 23:03:15 +0000416 return;
417 }
418
Daniel Dunbar7cde09a2010-01-22 03:38:14 +0000419 // Darwin doesn't support real static executables, don't link any runtime
420 // libraries with -static.
Daniel Dunbarbd847cc2012-10-15 22:23:53 +0000421 if (Args.hasArg(options::OPT_static) ||
422 Args.hasArg(options::OPT_fapple_kext) ||
423 Args.hasArg(options::OPT_mkernel))
Daniel Dunbar6276f992009-09-18 08:15:13 +0000424 return;
Daniel Dunbar6276f992009-09-18 08:15:13 +0000425
426 // Reject -static-libgcc for now, we can deal with this when and if someone
427 // cares. This is useful in situations where someone wants to statically link
428 // something like libstdc++, and needs its runtime support routines.
429 if (const Arg *A = Args.getLastArg(options::OPT_static_libgcc)) {
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000430 getDriver().Diag(diag::err_drv_unsupported_opt) << A->getAsString(Args);
Daniel Dunbar6276f992009-09-18 08:15:13 +0000431 return;
432 }
433
Peter Collingbourne32701642013-11-01 18:16:25 +0000434 const SanitizerArgs &Sanitize = getSanitizerArgs();
Alexey Samsonov7f2a0d22015-06-19 21:36:47 +0000435 if (Sanitize.needsAsanRt())
436 AddLinkSanitizerLibArgs(Args, CmdArgs, "asan");
437 if (Sanitize.needsUbsanRt())
438 AddLinkSanitizerLibArgs(Args, CmdArgs, "ubsan");
Kuba Brecka85e01c02015-11-06 15:09:20 +0000439 if (Sanitize.needsTsanRt())
440 AddLinkSanitizerLibArgs(Args, CmdArgs, "tsan");
Peter Collingbournedc134532016-01-16 00:31:22 +0000441 if (Sanitize.needsStatsRt()) {
442 StringRef OS = isTargetMacOS() ? "osx" : "iossim";
443 AddLinkRuntimeLib(Args, CmdArgs,
444 (Twine("libclang_rt.stats_client_") + OS + ".a").str(),
445 /*AlwaysLink=*/true);
446 AddLinkSanitizerLibArgs(Args, CmdArgs, "stats");
447 }
Derek Bruening256c2e12016-04-21 21:32:04 +0000448 if (Sanitize.needsEsanRt())
449 AddLinkSanitizerLibArgs(Args, CmdArgs, "esan");
Daniel Dunbar1d6469f2011-12-01 23:40:18 +0000450
Daniel Dunbar7cde09a2010-01-22 03:38:14 +0000451 // Otherwise link libSystem, then the dynamic runtime library, and finally any
452 // target specific static runtime library.
Daniel Dunbar6276f992009-09-18 08:15:13 +0000453 CmdArgs.push_back("-lSystem");
Daniel Dunbar7cde09a2010-01-22 03:38:14 +0000454
455 // Select the dynamic runtime library and the target specific static library.
Tim Northover6f3ff222015-10-30 16:30:27 +0000456 if (isTargetWatchOSBased()) {
457 // We currently always need a static runtime library for watchOS.
458 AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.watchos.a");
459 } else if (isTargetTvOSBased()) {
460 // We currently always need a static runtime library for tvOS.
461 AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.tvos.a");
462 } else if (isTargetIOSBased()) {
Daniel Dunbar2f31fb92011-04-30 04:25:16 +0000463 // If we are compiling as iOS / simulator, don't attempt to link libgcc_s.1,
464 // it never went into the SDK.
Bob Wilson102be442011-10-07 17:54:41 +0000465 // Linking against libgcc_s.1 isn't needed for iOS 5.0+
Tim Northovera2ee4332014-03-29 15:09:45 +0000466 if (isIPhoneOSVersionLT(5, 0) && !isTargetIOSSimulator() &&
Tim Northover40956e62014-07-23 12:32:58 +0000467 getTriple().getArch() != llvm::Triple::aarch64)
Bob Wilson102be442011-10-07 17:54:41 +0000468 CmdArgs.push_back("-lgcc_s.1");
Daniel Dunbar7cde09a2010-01-22 03:38:14 +0000469
Daniel Dunbard1076382011-04-18 23:48:36 +0000470 // We currently always need a static runtime library for iOS.
Eric Christopherc235d0c62011-06-22 17:41:40 +0000471 AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.ios.a");
Daniel Dunbar7cde09a2010-01-22 03:38:14 +0000472 } else {
Tim Northover9c7e0352013-12-12 11:55:52 +0000473 assert(isTargetMacOS() && "unexpected non MacOS platform");
Daniel Dunbar7cde09a2010-01-22 03:38:14 +0000474 // The dynamic runtime library was merged with libSystem for 10.6 and
475 // beyond; only 10.4 and 10.5 need an additional runtime library.
Daniel Dunbar6d23b2f2010-01-27 00:57:03 +0000476 if (isMacosxVersionLT(10, 5))
Daniel Dunbar7cde09a2010-01-22 03:38:14 +0000477 CmdArgs.push_back("-lgcc_s.10.4");
Daniel Dunbar6d23b2f2010-01-27 00:57:03 +0000478 else if (isMacosxVersionLT(10, 6))
Daniel Dunbar7cde09a2010-01-22 03:38:14 +0000479 CmdArgs.push_back("-lgcc_s.10.5");
480
Daniel Dunbarda4f6b52010-09-22 00:03:52 +0000481 // For OS X, we thought we would only need a static runtime library when
Chris Lattner57540c52011-04-15 05:22:18 +0000482 // targeting 10.4, to provide versions of the static functions which were
Daniel Dunbarda4f6b52010-09-22 00:03:52 +0000483 // omitted from 10.4.dylib.
484 //
485 // Unfortunately, that turned out to not be true, because Darwin system
486 // headers can still use eprintf on i386, and it is not exported from
487 // libSystem. Therefore, we still must provide a runtime library just for
488 // the tiny tiny handful of projects that *might* use that symbol.
489 if (isMacosxVersionLT(10, 5)) {
Eric Christopherc235d0c62011-06-22 17:41:40 +0000490 AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.10.4.a");
Daniel Dunbarda4f6b52010-09-22 00:03:52 +0000491 } else {
492 if (getTriple().getArch() == llvm::Triple::x86)
Eric Christopherc235d0c62011-06-22 17:41:40 +0000493 AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.eprintf.a");
494 AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.osx.a");
Daniel Dunbarda4f6b52010-09-22 00:03:52 +0000495 }
Daniel Dunbar7cde09a2010-01-22 03:38:14 +0000496 }
Daniel Dunbar6276f992009-09-18 08:15:13 +0000497}
498
Daniel Dunbar354e96d2010-07-19 17:11:36 +0000499void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
Daniel Dunbar083edf72009-12-21 18:54:17 +0000500 const OptTable &Opts = getDriver().getOpts();
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000501
Daniel Dunbar455a0492012-08-17 18:43:50 +0000502 // Support allowing the SDKROOT environment variable used by xcrun and other
503 // Xcode tools to define the default sysroot, by making it the default for
504 // isysroot.
Chad Rosier6c2b11c2012-12-19 23:41:50 +0000505 if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
506 // Warn if the path does not exist.
Benjamin Kramerd45b2052015-10-07 15:48:01 +0000507 if (!getVFS().exists(A->getValue()))
Chad Rosier6c2b11c2012-12-19 23:41:50 +0000508 getDriver().Diag(clang::diag::warn_missing_sysroot) << A->getValue();
509 } else {
Daniel Dunbar455a0492012-08-17 18:43:50 +0000510 if (char *env = ::getenv("SDKROOT")) {
Daniel Dunbarb2543042013-01-15 20:33:56 +0000511 // We only use this value as the default if it is an absolute path,
512 // exists, and it is not the root path.
Benjamin Kramerd45b2052015-10-07 15:48:01 +0000513 if (llvm::sys::path::is_absolute(env) && getVFS().exists(env) &&
Daniel Dunbarb2543042013-01-15 20:33:56 +0000514 StringRef(env) != "/") {
Daniel Dunbar455a0492012-08-17 18:43:50 +0000515 Args.append(Args.MakeSeparateArg(
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000516 nullptr, Opts.getOption(options::OPT_isysroot), env));
Daniel Dunbar455a0492012-08-17 18:43:50 +0000517 }
518 }
519 }
520
Daniel Dunbar3b8e50d2010-01-27 00:56:25 +0000521 Arg *OSXVersion = Args.getLastArg(options::OPT_mmacosx_version_min_EQ);
Daniel Dunbar9aaeb642011-04-30 04:15:58 +0000522 Arg *iOSVersion = Args.getLastArg(options::OPT_miphoneos_version_min_EQ);
Tim Northover6f3ff222015-10-30 16:30:27 +0000523 Arg *TvOSVersion = Args.getLastArg(options::OPT_mtvos_version_min_EQ);
524 Arg *WatchOSVersion = Args.getLastArg(options::OPT_mwatchos_version_min_EQ);
Eli Friedman027e9c32012-01-11 02:41:15 +0000525
Tim Northover6f3ff222015-10-30 16:30:27 +0000526 if (OSXVersion && (iOSVersion || TvOSVersion || WatchOSVersion)) {
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000527 getDriver().Diag(diag::err_drv_argument_not_allowed_with)
Tim Northover6f3ff222015-10-30 16:30:27 +0000528 << OSXVersion->getAsString(Args)
529 << (iOSVersion ? iOSVersion :
530 TvOSVersion ? TvOSVersion : WatchOSVersion)->getAsString(Args);
531 iOSVersion = TvOSVersion = WatchOSVersion = nullptr;
532 } else if (iOSVersion && (TvOSVersion || WatchOSVersion)) {
533 getDriver().Diag(diag::err_drv_argument_not_allowed_with)
534 << iOSVersion->getAsString(Args)
535 << (TvOSVersion ? TvOSVersion : WatchOSVersion)->getAsString(Args);
536 TvOSVersion = WatchOSVersion = nullptr;
537 } else if (TvOSVersion && WatchOSVersion) {
538 getDriver().Diag(diag::err_drv_argument_not_allowed_with)
539 << TvOSVersion->getAsString(Args)
540 << WatchOSVersion->getAsString(Args);
541 WatchOSVersion = nullptr;
542 } else if (!OSXVersion && !iOSVersion && !TvOSVersion && !WatchOSVersion) {
Chad Rosier64707fe2011-08-31 20:56:25 +0000543 // If no deployment target was specified on the command line, check for
Daniel Dunbard54669d2010-01-26 01:45:19 +0000544 // environment defines.
Alexey Samsonov905c8022015-06-18 21:46:05 +0000545 std::string OSXTarget;
546 std::string iOSTarget;
Tim Northover6f3ff222015-10-30 16:30:27 +0000547 std::string TvOSTarget;
548 std::string WatchOSTarget;
549
Chad Rosier64707fe2011-08-31 20:56:25 +0000550 if (char *env = ::getenv("MACOSX_DEPLOYMENT_TARGET"))
551 OSXTarget = env;
552 if (char *env = ::getenv("IPHONEOS_DEPLOYMENT_TARGET"))
553 iOSTarget = env;
Tim Northover6f3ff222015-10-30 16:30:27 +0000554 if (char *env = ::getenv("TVOS_DEPLOYMENT_TARGET"))
555 TvOSTarget = env;
556 if (char *env = ::getenv("WATCHOS_DEPLOYMENT_TARGET"))
557 WatchOSTarget = env;
Daniel Dunbarb5023e92009-04-10 21:00:07 +0000558
Steven Wu7a1372c2015-06-25 01:59:35 +0000559 // If there is no command-line argument to specify the Target version and
560 // no environment variable defined, see if we can set the default based
561 // on -isysroot.
Tim Northover6f3ff222015-10-30 16:30:27 +0000562 if (OSXTarget.empty() && iOSTarget.empty() && WatchOSTarget.empty() &&
Frederic Riss3ad83bd2016-01-12 23:47:59 +0000563 TvOSTarget.empty() && Args.hasArg(options::OPT_isysroot)) {
Chad Rosier64707fe2011-08-31 20:56:25 +0000564 if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
Richard Smithbd55daf2012-11-01 04:30:05 +0000565 StringRef isysroot = A->getValue();
Chris Bienemane60e7c22016-04-29 22:28:34 +0000566 StringRef SDK = getSDKName(isysroot);
567 if (SDK.size() > 0) {
Steven Wu7a1372c2015-06-25 01:59:35 +0000568 // Slice the version number out.
569 // Version number is between the first and the last number.
570 size_t StartVer = SDK.find_first_of("0123456789");
571 size_t EndVer = SDK.find_last_of("0123456789");
572 if (StartVer != StringRef::npos && EndVer > StartVer) {
573 StringRef Version = SDK.slice(StartVer, EndVer + 1);
574 if (SDK.startswith("iPhoneOS") ||
575 SDK.startswith("iPhoneSimulator"))
576 iOSTarget = Version;
577 else if (SDK.startswith("MacOSX"))
578 OSXTarget = Version;
Tim Northover6f3ff222015-10-30 16:30:27 +0000579 else if (SDK.startswith("WatchOS") ||
580 SDK.startswith("WatchSimulator"))
581 WatchOSTarget = Version;
582 else if (SDK.startswith("AppleTVOS") ||
583 SDK.startswith("AppleTVSimulator"))
584 TvOSTarget = Version;
Steven Wu7a1372c2015-06-25 01:59:35 +0000585 }
586 }
Chad Rosier64707fe2011-08-31 20:56:25 +0000587 }
588 }
Daniel Dunbard54669d2010-01-26 01:45:19 +0000589
Alexey Samsonovfd0bb3a2015-06-18 00:36:38 +0000590 // If no OSX or iOS target has been specified, try to guess platform
Alexey Samsonov905c8022015-06-18 21:46:05 +0000591 // from arch name and compute the version from the triple.
Tim Northover6f3ff222015-10-30 16:30:27 +0000592 if (OSXTarget.empty() && iOSTarget.empty() && TvOSTarget.empty() &&
593 WatchOSTarget.empty()) {
Alexey Samsonovfd0bb3a2015-06-18 00:36:38 +0000594 StringRef MachOArchName = getMachOArchName(Args);
Alexey Samsonov905c8022015-06-18 21:46:05 +0000595 unsigned Major, Minor, Micro;
Alexey Samsonovfd0bb3a2015-06-18 00:36:38 +0000596 if (MachOArchName == "armv7" || MachOArchName == "armv7s" ||
Alexey Samsonov905c8022015-06-18 21:46:05 +0000597 MachOArchName == "arm64") {
598 getTriple().getiOSVersion(Major, Minor, Micro);
599 llvm::raw_string_ostream(iOSTarget) << Major << '.' << Minor << '.'
600 << Micro;
Tim Northover6f3ff222015-10-30 16:30:27 +0000601 } else if (MachOArchName == "armv7k") {
602 getTriple().getWatchOSVersion(Major, Minor, Micro);
603 llvm::raw_string_ostream(WatchOSTarget) << Major << '.' << Minor << '.'
604 << Micro;
Alexey Samsonov905c8022015-06-18 21:46:05 +0000605 } else if (MachOArchName != "armv6m" && MachOArchName != "armv7m" &&
606 MachOArchName != "armv7em") {
607 if (!getTriple().getMacOSXVersion(Major, Minor, Micro)) {
608 getDriver().Diag(diag::err_drv_invalid_darwin_version)
609 << getTriple().getOSName();
610 }
611 llvm::raw_string_ostream(OSXTarget) << Major << '.' << Minor << '.'
612 << Micro;
613 }
Alexey Samsonovfd0bb3a2015-06-18 00:36:38 +0000614 }
Chad Rosierfe6fd362011-09-28 00:46:32 +0000615
Tim Northover6f3ff222015-10-30 16:30:27 +0000616 // Do not allow conflicts with the watchOS target.
617 if (!WatchOSTarget.empty() && (!iOSTarget.empty() || !TvOSTarget.empty())) {
618 getDriver().Diag(diag::err_drv_conflicting_deployment_targets)
619 << "WATCHOS_DEPLOYMENT_TARGET"
620 << (!iOSTarget.empty() ? "IPHONEOS_DEPLOYMENT_TARGET" :
621 "TVOS_DEPLOYMENT_TARGET");
622 }
623
624 // Do not allow conflicts with the tvOS target.
625 if (!TvOSTarget.empty() && !iOSTarget.empty()) {
626 getDriver().Diag(diag::err_drv_conflicting_deployment_targets)
627 << "TVOS_DEPLOYMENT_TARGET"
628 << "IPHONEOS_DEPLOYMENT_TARGET";
629 }
630
Daniel Dunbar9aaeb642011-04-30 04:15:58 +0000631 // Allow conflicts among OSX and iOS for historical reasons, but choose the
632 // default platform.
Tim Northover6f3ff222015-10-30 16:30:27 +0000633 if (!OSXTarget.empty() && (!iOSTarget.empty() ||
634 !WatchOSTarget.empty() ||
635 !TvOSTarget.empty())) {
Daniel Dunbarffa70e82010-02-02 17:31:12 +0000636 if (getTriple().getArch() == llvm::Triple::arm ||
Tim Northover573cbee2014-05-24 12:52:07 +0000637 getTriple().getArch() == llvm::Triple::aarch64 ||
Daniel Dunbarffa70e82010-02-02 17:31:12 +0000638 getTriple().getArch() == llvm::Triple::thumb)
Chad Rosier64707fe2011-08-31 20:56:25 +0000639 OSXTarget = "";
Daniel Dunbarffa70e82010-02-02 17:31:12 +0000640 else
Tim Northover6f3ff222015-10-30 16:30:27 +0000641 iOSTarget = WatchOSTarget = TvOSTarget = "";
Daniel Dunbarffa70e82010-02-02 17:31:12 +0000642 }
Daniel Dunbar65969842010-01-29 17:02:25 +0000643
Chad Rosier64707fe2011-08-31 20:56:25 +0000644 if (!OSXTarget.empty()) {
Michael J. Spencerfc790902012-10-19 22:36:40 +0000645 const Option O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
Craig Topper92fc2df2014-05-17 16:56:41 +0000646 OSXVersion = Args.MakeJoinedArg(nullptr, O, OSXTarget);
Daniel Dunbar354e96d2010-07-19 17:11:36 +0000647 Args.append(OSXVersion);
Chad Rosier64707fe2011-08-31 20:56:25 +0000648 } else if (!iOSTarget.empty()) {
Michael J. Spencerfc790902012-10-19 22:36:40 +0000649 const Option O = Opts.getOption(options::OPT_miphoneos_version_min_EQ);
Craig Topper92fc2df2014-05-17 16:56:41 +0000650 iOSVersion = Args.MakeJoinedArg(nullptr, O, iOSTarget);
Daniel Dunbar9aaeb642011-04-30 04:15:58 +0000651 Args.append(iOSVersion);
Tim Northover6f3ff222015-10-30 16:30:27 +0000652 } else if (!TvOSTarget.empty()) {
653 const Option O = Opts.getOption(options::OPT_mtvos_version_min_EQ);
654 TvOSVersion = Args.MakeJoinedArg(nullptr, O, TvOSTarget);
655 Args.append(TvOSVersion);
656 } else if (!WatchOSTarget.empty()) {
657 const Option O = Opts.getOption(options::OPT_mwatchos_version_min_EQ);
658 WatchOSVersion = Args.MakeJoinedArg(nullptr, O, WatchOSTarget);
659 Args.append(WatchOSVersion);
Daniel Dunbar84e727f2009-09-04 18:35:21 +0000660 }
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000661 }
Mike Stump11289f42009-09-09 15:08:12 +0000662
Tim Northover9c7e0352013-12-12 11:55:52 +0000663 DarwinPlatformKind Platform;
664 if (OSXVersion)
665 Platform = MacOS;
666 else if (iOSVersion)
667 Platform = IPhoneOS;
Tim Northover6f3ff222015-10-30 16:30:27 +0000668 else if (TvOSVersion)
669 Platform = TvOS;
670 else if (WatchOSVersion)
671 Platform = WatchOS;
Tim Northover9c7e0352013-12-12 11:55:52 +0000672 else
Tim Northover157d9112014-01-16 08:48:16 +0000673 llvm_unreachable("Unable to infer Darwin variant");
Tim Northover9c7e0352013-12-12 11:55:52 +0000674
Daniel Dunbar3b8e50d2010-01-27 00:56:25 +0000675 // Set the tool chain target information.
676 unsigned Major, Minor, Micro;
677 bool HadExtra;
Tim Northover9c7e0352013-12-12 11:55:52 +0000678 if (Platform == MacOS) {
Tim Northover6f3ff222015-10-30 16:30:27 +0000679 assert((!iOSVersion && !TvOSVersion && !WatchOSVersion) &&
680 "Unknown target platform!");
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000681 if (!Driver::GetReleaseVersion(OSXVersion->getValue(), Major, Minor, Micro,
682 HadExtra) ||
683 HadExtra || Major != 10 || Minor >= 100 || Micro >= 100)
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000684 getDriver().Diag(diag::err_drv_invalid_version_number)
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000685 << OSXVersion->getAsString(Args);
Bob Wilson7f294b52014-10-10 23:10:10 +0000686 } else if (Platform == IPhoneOS) {
687 assert(iOSVersion && "Unknown target platform!");
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000688 if (!Driver::GetReleaseVersion(iOSVersion->getValue(), Major, Minor, Micro,
689 HadExtra) ||
Bob Wilson4cf27c42016-07-18 20:29:14 +0000690 HadExtra || Major >= 100 || Minor >= 100 || Micro >= 100)
Eli Friedman027e9c32012-01-11 02:41:15 +0000691 getDriver().Diag(diag::err_drv_invalid_version_number)
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000692 << iOSVersion->getAsString(Args);
Tim Northover6f3ff222015-10-30 16:30:27 +0000693 } else if (Platform == TvOS) {
694 if (!Driver::GetReleaseVersion(TvOSVersion->getValue(), Major, Minor,
695 Micro, HadExtra) || HadExtra ||
Bob Wilson4cf27c42016-07-18 20:29:14 +0000696 Major >= 100 || Minor >= 100 || Micro >= 100)
Tim Northover6f3ff222015-10-30 16:30:27 +0000697 getDriver().Diag(diag::err_drv_invalid_version_number)
698 << TvOSVersion->getAsString(Args);
699 } else if (Platform == WatchOS) {
700 if (!Driver::GetReleaseVersion(WatchOSVersion->getValue(), Major, Minor,
701 Micro, HadExtra) || HadExtra ||
702 Major >= 10 || Minor >= 100 || Micro >= 100)
703 getDriver().Diag(diag::err_drv_invalid_version_number)
704 << WatchOSVersion->getAsString(Args);
Tim Northover157d9112014-01-16 08:48:16 +0000705 } else
706 llvm_unreachable("unknown kind of Darwin platform");
Daniel Dunbar9aaeb642011-04-30 04:15:58 +0000707
Bob Wilson7f294b52014-10-10 23:10:10 +0000708 // Recognize iOS targets with an x86 architecture as the iOS simulator.
Daniel Dunbarb1189432011-04-30 04:18:16 +0000709 if (iOSVersion && (getTriple().getArch() == llvm::Triple::x86 ||
710 getTriple().getArch() == llvm::Triple::x86_64))
Tim Northover9c7e0352013-12-12 11:55:52 +0000711 Platform = IPhoneOSSimulator;
Tim Northover6f3ff222015-10-30 16:30:27 +0000712 if (TvOSVersion && (getTriple().getArch() == llvm::Triple::x86 ||
713 getTriple().getArch() == llvm::Triple::x86_64))
714 Platform = TvOSSimulator;
715 if (WatchOSVersion && (getTriple().getArch() == llvm::Triple::x86 ||
716 getTriple().getArch() == llvm::Triple::x86_64))
717 Platform = WatchOSSimulator;
Daniel Dunbarb1189432011-04-30 04:18:16 +0000718
Tim Northover9c7e0352013-12-12 11:55:52 +0000719 setTarget(Platform, Major, Minor, Micro);
Chris Bienemane60e7c22016-04-29 22:28:34 +0000720
721 if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
722 StringRef SDK = getSDKName(A->getValue());
723 if (SDK.size() > 0) {
724 size_t StartVer = SDK.find_first_of("0123456789");
725 StringRef SDKName = SDK.slice(0, StartVer);
726 if (!SDKName.startswith(getPlatformFamily()))
727 getDriver().Diag(diag::warn_incompatible_sysroot)
728 << SDKName << getPlatformFamily();
729 }
730 }
Daniel Dunbarb2b8a912010-07-19 17:11:33 +0000731}
732
Daniel Dunbar3f7796f2010-09-17 01:20:05 +0000733void DarwinClang::AddCXXStdlibLibArgs(const ArgList &Args,
Daniel Dunbar8fa86b12010-09-17 01:16:06 +0000734 ArgStringList &CmdArgs) const {
735 CXXStdlibType Type = GetCXXStdlibType(Args);
736
737 switch (Type) {
738 case ToolChain::CST_Libcxx:
739 CmdArgs.push_back("-lc++");
740 break;
741
Hans Wennborgdcfba332015-10-06 23:40:43 +0000742 case ToolChain::CST_Libstdcxx:
Daniel Dunbar8fa86b12010-09-17 01:16:06 +0000743 // Unfortunately, -lstdc++ doesn't always exist in the standard search path;
744 // it was previously found in the gcc lib dir. However, for all the Darwin
745 // platforms we care about it was -lstdc++.6, so we search for that
746 // explicitly if we can't see an obvious -lstdc++ candidate.
747
748 // Check in the sysroot first.
749 if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
Rafael Espindola358256c2013-06-26 02:13:00 +0000750 SmallString<128> P(A->getValue());
Benjamin Kramer17381a02013-06-28 16:25:46 +0000751 llvm::sys::path::append(P, "usr", "lib", "libstdc++.dylib");
Daniel Dunbar8fa86b12010-09-17 01:16:06 +0000752
Benjamin Kramerd45b2052015-10-07 15:48:01 +0000753 if (!getVFS().exists(P)) {
Rafael Espindola358256c2013-06-26 02:13:00 +0000754 llvm::sys::path::remove_filename(P);
755 llvm::sys::path::append(P, "libstdc++.6.dylib");
Benjamin Kramerd45b2052015-10-07 15:48:01 +0000756 if (getVFS().exists(P)) {
Yaron Keren92e1b622015-03-18 10:17:07 +0000757 CmdArgs.push_back(Args.MakeArgString(P));
Daniel Dunbar8fa86b12010-09-17 01:16:06 +0000758 return;
759 }
760 }
761 }
762
763 // Otherwise, look in the root.
Bob Wilson1a9ad0f2011-11-11 07:47:04 +0000764 // FIXME: This should be removed someday when we don't have to care about
765 // 10.6 and earlier, where /usr/lib/libstdc++.dylib does not exist.
Benjamin Kramerd45b2052015-10-07 15:48:01 +0000766 if (!getVFS().exists("/usr/lib/libstdc++.dylib") &&
767 getVFS().exists("/usr/lib/libstdc++.6.dylib")) {
Daniel Dunbar8fa86b12010-09-17 01:16:06 +0000768 CmdArgs.push_back("/usr/lib/libstdc++.6.dylib");
769 return;
770 }
771
772 // Otherwise, let the linker search.
773 CmdArgs.push_back("-lstdc++");
774 break;
775 }
Daniel Dunbar8fa86b12010-09-17 01:16:06 +0000776}
777
Shantonu Senafeb03b2010-09-17 18:39:08 +0000778void DarwinClang::AddCCKextLibArgs(const ArgList &Args,
779 ArgStringList &CmdArgs) const {
Shantonu Senafeb03b2010-09-17 18:39:08 +0000780 // For Darwin platforms, use the compiler-rt-based support library
781 // instead of the gcc-provided one (which is also incidentally
782 // only present in the gcc lib dir, which makes it hard to find).
783
Rafael Espindola358256c2013-06-26 02:13:00 +0000784 SmallString<128> P(getDriver().ResourceDir);
Benjamin Kramer17381a02013-06-28 16:25:46 +0000785 llvm::sys::path::append(P, "lib", "darwin");
Daniel Dunbarbd847cc2012-10-15 22:23:53 +0000786
787 // Use the newer cc_kext for iOS ARM after 6.0.
Tim Northover6f3ff222015-10-30 16:30:27 +0000788 if (isTargetWatchOS()) {
789 llvm::sys::path::append(P, "libclang_rt.cc_kext_watchos.a");
790 } else if (isTargetTvOS()) {
791 llvm::sys::path::append(P, "libclang_rt.cc_kext_tvos.a");
792 } else if (isTargetIPhoneOS()) {
Chris Bieneman25bc0de2015-09-23 22:52:35 +0000793 llvm::sys::path::append(P, "libclang_rt.cc_kext_ios.a");
Daniel Dunbarbd847cc2012-10-15 22:23:53 +0000794 } else {
Chris Bieneman25bc0de2015-09-23 22:52:35 +0000795 llvm::sys::path::append(P, "libclang_rt.cc_kext.a");
Daniel Dunbarbd847cc2012-10-15 22:23:53 +0000796 }
NAKAMURA Takumi8b73b3e2011-06-03 03:49:51 +0000797
Shantonu Senafeb03b2010-09-17 18:39:08 +0000798 // For now, allow missing resource libraries to support developers who may
799 // not have compiler-rt checked out or integrated into their build.
Benjamin Kramerd45b2052015-10-07 15:48:01 +0000800 if (getVFS().exists(P))
Yaron Keren92e1b622015-03-18 10:17:07 +0000801 CmdArgs.push_back(Args.MakeArgString(P));
Shantonu Senafeb03b2010-09-17 18:39:08 +0000802}
803
Tim Northover157d9112014-01-16 08:48:16 +0000804DerivedArgList *MachO::TranslateArgs(const DerivedArgList &Args,
805 const char *BoundArch) const {
Daniel Dunbarb2b8a912010-07-19 17:11:33 +0000806 DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
807 const OptTable &Opts = getDriver().getOpts();
808
809 // FIXME: We really want to get out of the tool chain level argument
810 // translation business, as it makes the driver functionality much
811 // more opaque. For now, we follow gcc closely solely for the
812 // purpose of easily achieving feature parity & testability. Once we
813 // have something that works, we should reevaluate each translation
814 // and try to push it down into tool specific logic.
Daniel Dunbar3b8e50d2010-01-27 00:56:25 +0000815
Simon Atanasyan6f657c42014-05-08 19:32:46 +0000816 for (Arg *A : Args) {
Daniel Dunbaraabb0b12009-03-25 06:12:34 +0000817 if (A->getOption().matches(options::OPT_Xarch__)) {
Daniel Dunbar471c4f82011-06-21 00:20:17 +0000818 // Skip this argument unless the architecture matches either the toolchain
819 // triple arch, or the arch being bound.
Rafael Espindola35ca7d92012-10-07 04:44:33 +0000820 llvm::Triple::ArchType XarchArch =
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000821 tools::darwin::getArchTypeForMachOArchName(A->getValue(0));
822 if (!(XarchArch == getArch() ||
823 (BoundArch &&
824 XarchArch ==
825 tools::darwin::getArchTypeForMachOArchName(BoundArch))))
Daniel Dunbaraabb0b12009-03-25 06:12:34 +0000826 continue;
827
Daniel Dunbar1094bb12011-02-19 05:33:51 +0000828 Arg *OriginalArg = A;
Richard Smithbd55daf2012-11-01 04:30:05 +0000829 unsigned Index = Args.getBaseArgs().MakeIndex(A->getValue(1));
Daniel Dunbar3f1a1ff2010-06-14 21:23:08 +0000830 unsigned Prev = Index;
Nico Webera04d5f82014-05-11 17:27:13 +0000831 std::unique_ptr<Arg> XarchArg(Opts.ParseOneArg(Args, Index));
Mike Stump11289f42009-09-09 15:08:12 +0000832
Daniel Dunbaraabb0b12009-03-25 06:12:34 +0000833 // If the argument parsing failed or more than one argument was
834 // consumed, the -Xarch_ argument's parameter tried to consume
835 // extra arguments. Emit an error and ignore.
836 //
837 // We also want to disallow any options which would alter the
838 // driver behavior; that isn't going to work in our model. We
839 // use isDriverOption() as an approximation, although things
840 // like -O4 are going to slip through.
Daniel Dunbar5a784c82011-04-21 17:41:34 +0000841 if (!XarchArg || Index > Prev + 1) {
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000842 getDriver().Diag(diag::err_drv_invalid_Xarch_argument_with_args)
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000843 << A->getAsString(Args);
Daniel Dunbar6914a982011-04-21 17:32:21 +0000844 continue;
Michael J. Spencer66e2b202012-10-19 22:37:06 +0000845 } else if (XarchArg->getOption().hasFlag(options::DriverOption)) {
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000846 getDriver().Diag(diag::err_drv_invalid_Xarch_argument_isdriver)
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000847 << A->getAsString(Args);
Daniel Dunbaraabb0b12009-03-25 06:12:34 +0000848 continue;
849 }
850
Daniel Dunbar53b406f2009-03-29 22:29:05 +0000851 XarchArg->setBaseArg(A);
Daniel Dunbar3f1a1ff2010-06-14 21:23:08 +0000852
Nico Webera04d5f82014-05-11 17:27:13 +0000853 A = XarchArg.release();
Daniel Dunbar3f1a1ff2010-06-14 21:23:08 +0000854 DAL->AddSynthesizedArg(A);
Daniel Dunbar1094bb12011-02-19 05:33:51 +0000855
856 // Linker input arguments require custom handling. The problem is that we
857 // have already constructed the phase actions, so we can not treat them as
858 // "input arguments".
Michael J. Spencer66e2b202012-10-19 22:37:06 +0000859 if (A->getOption().hasFlag(options::LinkerInput)) {
Daniel Dunbar1094bb12011-02-19 05:33:51 +0000860 // Convert the argument into individual Zlinker_input_args.
Douglas Katzman6bbffc42015-06-25 18:51:37 +0000861 for (const char *Value : A->getValues()) {
862 DAL->AddSeparateArg(
863 OriginalArg, Opts.getOption(options::OPT_Zlinker_input), Value);
Daniel Dunbar1094bb12011-02-19 05:33:51 +0000864 }
865 continue;
866 }
Mike Stump11289f42009-09-09 15:08:12 +0000867 }
Daniel Dunbaraabb0b12009-03-25 06:12:34 +0000868
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000869 // Sob. These is strictly gcc compatible for the time being. Apple
870 // gcc translates options twice, which means that self-expanding
871 // options add duplicates.
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000872 switch ((options::ID)A->getOption().getID()) {
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000873 default:
874 DAL->append(A);
875 break;
876
877 case options::OPT_mkernel:
878 case options::OPT_fapple_kext:
879 DAL->append(A);
Daniel Dunbar2d6e9ee2010-06-14 20:20:41 +0000880 DAL->AddFlagArg(A, Opts.getOption(options::OPT_static));
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000881 break;
Mike Stump11289f42009-09-09 15:08:12 +0000882
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000883 case options::OPT_dependency_file:
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000884 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue());
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000885 break;
886
887 case options::OPT_gfull:
Daniel Dunbar2d6e9ee2010-06-14 20:20:41 +0000888 DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag));
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000889 DAL->AddFlagArg(
890 A, Opts.getOption(options::OPT_fno_eliminate_unused_debug_symbols));
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000891 break;
892
893 case options::OPT_gused:
Daniel Dunbar2d6e9ee2010-06-14 20:20:41 +0000894 DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag));
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000895 DAL->AddFlagArg(
896 A, Opts.getOption(options::OPT_feliminate_unused_debug_symbols));
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000897 break;
898
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000899 case options::OPT_shared:
Daniel Dunbar2d6e9ee2010-06-14 20:20:41 +0000900 DAL->AddFlagArg(A, Opts.getOption(options::OPT_dynamiclib));
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000901 break;
902
903 case options::OPT_fconstant_cfstrings:
Daniel Dunbar2d6e9ee2010-06-14 20:20:41 +0000904 DAL->AddFlagArg(A, Opts.getOption(options::OPT_mconstant_cfstrings));
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000905 break;
906
907 case options::OPT_fno_constant_cfstrings:
Daniel Dunbar2d6e9ee2010-06-14 20:20:41 +0000908 DAL->AddFlagArg(A, Opts.getOption(options::OPT_mno_constant_cfstrings));
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000909 break;
910
911 case options::OPT_Wnonportable_cfstrings:
Daniel Dunbar2d6e9ee2010-06-14 20:20:41 +0000912 DAL->AddFlagArg(A,
913 Opts.getOption(options::OPT_mwarn_nonportable_cfstrings));
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000914 break;
915
916 case options::OPT_Wno_nonportable_cfstrings:
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000917 DAL->AddFlagArg(
918 A, Opts.getOption(options::OPT_mno_warn_nonportable_cfstrings));
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000919 break;
920
921 case options::OPT_fpascal_strings:
Daniel Dunbar2d6e9ee2010-06-14 20:20:41 +0000922 DAL->AddFlagArg(A, Opts.getOption(options::OPT_mpascal_strings));
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000923 break;
924
925 case options::OPT_fno_pascal_strings:
Daniel Dunbar2d6e9ee2010-06-14 20:20:41 +0000926 DAL->AddFlagArg(A, Opts.getOption(options::OPT_mno_pascal_strings));
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000927 break;
928 }
Daniel Dunbaraabb0b12009-03-25 06:12:34 +0000929 }
930
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000931 if (getTriple().getArch() == llvm::Triple::x86 ||
932 getTriple().getArch() == llvm::Triple::x86_64)
Daniel Dunbarfffd1812009-11-19 04:00:53 +0000933 if (!Args.hasArgNoClaim(options::OPT_mtune_EQ))
Craig Topper92fc2df2014-05-17 16:56:41 +0000934 DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_mtune_EQ),
935 "core2");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000936
937 // Add the arch options based on the particular spelling of -arch, to match
Chad Rosier7c5d9082012-04-27 14:58:16 +0000938 // how the driver driver works.
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000939 if (BoundArch) {
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000940 StringRef Name = BoundArch;
Michael J. Spencerfc790902012-10-19 22:36:40 +0000941 const Option MCpu = Opts.getOption(options::OPT_mcpu_EQ);
942 const Option MArch = Opts.getOption(options::OPT_march_EQ);
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000943
944 // This code must be kept in sync with LLVM's getArchTypeForDarwinArch,
945 // which defines the list of which architectures we accept.
946 if (Name == "ppc")
947 ;
948 else if (Name == "ppc601")
Craig Topper92fc2df2014-05-17 16:56:41 +0000949 DAL->AddJoinedArg(nullptr, MCpu, "601");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000950 else if (Name == "ppc603")
Craig Topper92fc2df2014-05-17 16:56:41 +0000951 DAL->AddJoinedArg(nullptr, MCpu, "603");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000952 else if (Name == "ppc604")
Craig Topper92fc2df2014-05-17 16:56:41 +0000953 DAL->AddJoinedArg(nullptr, MCpu, "604");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000954 else if (Name == "ppc604e")
Craig Topper92fc2df2014-05-17 16:56:41 +0000955 DAL->AddJoinedArg(nullptr, MCpu, "604e");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000956 else if (Name == "ppc750")
Craig Topper92fc2df2014-05-17 16:56:41 +0000957 DAL->AddJoinedArg(nullptr, MCpu, "750");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000958 else if (Name == "ppc7400")
Craig Topper92fc2df2014-05-17 16:56:41 +0000959 DAL->AddJoinedArg(nullptr, MCpu, "7400");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000960 else if (Name == "ppc7450")
Craig Topper92fc2df2014-05-17 16:56:41 +0000961 DAL->AddJoinedArg(nullptr, MCpu, "7450");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000962 else if (Name == "ppc970")
Craig Topper92fc2df2014-05-17 16:56:41 +0000963 DAL->AddJoinedArg(nullptr, MCpu, "970");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000964
Bill Schmidt778d3872013-07-26 01:36:11 +0000965 else if (Name == "ppc64" || Name == "ppc64le")
Craig Topper92fc2df2014-05-17 16:56:41 +0000966 DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64));
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000967
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000968 else if (Name == "i386")
969 ;
970 else if (Name == "i486")
Craig Topper92fc2df2014-05-17 16:56:41 +0000971 DAL->AddJoinedArg(nullptr, MArch, "i486");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000972 else if (Name == "i586")
Craig Topper92fc2df2014-05-17 16:56:41 +0000973 DAL->AddJoinedArg(nullptr, MArch, "i586");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000974 else if (Name == "i686")
Craig Topper92fc2df2014-05-17 16:56:41 +0000975 DAL->AddJoinedArg(nullptr, MArch, "i686");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000976 else if (Name == "pentium")
Craig Topper92fc2df2014-05-17 16:56:41 +0000977 DAL->AddJoinedArg(nullptr, MArch, "pentium");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000978 else if (Name == "pentium2")
Craig Topper92fc2df2014-05-17 16:56:41 +0000979 DAL->AddJoinedArg(nullptr, MArch, "pentium2");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000980 else if (Name == "pentpro")
Craig Topper92fc2df2014-05-17 16:56:41 +0000981 DAL->AddJoinedArg(nullptr, MArch, "pentiumpro");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000982 else if (Name == "pentIIm3")
Craig Topper92fc2df2014-05-17 16:56:41 +0000983 DAL->AddJoinedArg(nullptr, MArch, "pentium2");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000984
985 else if (Name == "x86_64")
Craig Topper92fc2df2014-05-17 16:56:41 +0000986 DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64));
Jim Grosbach82eee262013-11-16 00:53:35 +0000987 else if (Name == "x86_64h") {
Craig Topper92fc2df2014-05-17 16:56:41 +0000988 DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64));
989 DAL->AddJoinedArg(nullptr, MArch, "x86_64h");
Jim Grosbach82eee262013-11-16 00:53:35 +0000990 }
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000991
992 else if (Name == "arm")
Craig Topper92fc2df2014-05-17 16:56:41 +0000993 DAL->AddJoinedArg(nullptr, MArch, "armv4t");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000994 else if (Name == "armv4t")
Craig Topper92fc2df2014-05-17 16:56:41 +0000995 DAL->AddJoinedArg(nullptr, MArch, "armv4t");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000996 else if (Name == "armv5")
Craig Topper92fc2df2014-05-17 16:56:41 +0000997 DAL->AddJoinedArg(nullptr, MArch, "armv5tej");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000998 else if (Name == "xscale")
Craig Topper92fc2df2014-05-17 16:56:41 +0000999 DAL->AddJoinedArg(nullptr, MArch, "xscale");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +00001000 else if (Name == "armv6")
Craig Topper92fc2df2014-05-17 16:56:41 +00001001 DAL->AddJoinedArg(nullptr, MArch, "armv6k");
Bob Wilson743bf672013-03-04 22:37:49 +00001002 else if (Name == "armv6m")
Craig Topper92fc2df2014-05-17 16:56:41 +00001003 DAL->AddJoinedArg(nullptr, MArch, "armv6m");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +00001004 else if (Name == "armv7")
Craig Topper92fc2df2014-05-17 16:56:41 +00001005 DAL->AddJoinedArg(nullptr, MArch, "armv7a");
Bob Wilson743bf672013-03-04 22:37:49 +00001006 else if (Name == "armv7em")
Craig Topper92fc2df2014-05-17 16:56:41 +00001007 DAL->AddJoinedArg(nullptr, MArch, "armv7em");
Bob Wilsond7cf1042012-09-29 23:52:50 +00001008 else if (Name == "armv7k")
Craig Topper92fc2df2014-05-17 16:56:41 +00001009 DAL->AddJoinedArg(nullptr, MArch, "armv7k");
Bob Wilson743bf672013-03-04 22:37:49 +00001010 else if (Name == "armv7m")
Craig Topper92fc2df2014-05-17 16:56:41 +00001011 DAL->AddJoinedArg(nullptr, MArch, "armv7m");
Bob Wilsond7cf1042012-09-29 23:52:50 +00001012 else if (Name == "armv7s")
Craig Topper92fc2df2014-05-17 16:56:41 +00001013 DAL->AddJoinedArg(nullptr, MArch, "armv7s");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +00001014 }
Daniel Dunbar0af75a12009-03-25 06:58:31 +00001015
Tim Northover157d9112014-01-16 08:48:16 +00001016 return DAL;
1017}
1018
Vedant Kumarbf51e702016-07-18 19:56:38 +00001019void MachO::AddLinkRuntimeLibArgs(const llvm::Triple &EffectiveTriple,
1020 const ArgList &Args,
Douglas Katzmanf08fadf2015-06-04 14:40:44 +00001021 ArgStringList &CmdArgs) const {
Tim Northover157d9112014-01-16 08:48:16 +00001022 // Embedded targets are simple at the moment, not supporting sanitizers and
1023 // with different libraries for each member of the product { static, PIC } x
1024 // { hard-float, soft-float }
1025 llvm::SmallString<32> CompilerRT = StringRef("libclang_rt.");
Vedant Kumarbf51e702016-07-18 19:56:38 +00001026 CompilerRT += (tools::arm::getARMFloatABI(*this, EffectiveTriple, Args) ==
1027 tools::arm::FloatABI::Hard)
1028 ? "hard"
1029 : "soft";
Tim Northover157d9112014-01-16 08:48:16 +00001030 CompilerRT += Args.hasArg(options::OPT_fPIC) ? "_pic.a" : "_static.a";
1031
1032 AddLinkRuntimeLib(Args, CmdArgs, CompilerRT, false, true);
1033}
1034
Tim Northover157d9112014-01-16 08:48:16 +00001035DerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args,
1036 const char *BoundArch) const {
1037 // First get the generic Apple args, before moving onto Darwin-specific ones.
1038 DerivedArgList *DAL = MachO::TranslateArgs(Args, BoundArch);
Tim Northoverb534ce42016-02-12 22:30:42 +00001039 const OptTable &Opts = getDriver().getOpts();
Tim Northover157d9112014-01-16 08:48:16 +00001040
Bob Wilsonf8cf1612014-02-21 00:20:07 +00001041 // If no architecture is bound, none of the translations here are relevant.
1042 if (!BoundArch)
1043 return DAL;
1044
Daniel Dunbar354e96d2010-07-19 17:11:36 +00001045 // Add an explicit version min argument for the deployment target. We do this
1046 // after argument translation because -Xarch_ arguments may add a version min
1047 // argument.
Bob Wilsonf8cf1612014-02-21 00:20:07 +00001048 AddDeploymentTarget(*DAL);
Daniel Dunbar354e96d2010-07-19 17:11:36 +00001049
Daniel Dunbarbd847cc2012-10-15 22:23:53 +00001050 // For iOS 6, undo the translation to add -static for -mkernel/-fapple-kext.
1051 // FIXME: It would be far better to avoid inserting those -static arguments,
1052 // but we can't check the deployment target in the translation code until
1053 // it is set here.
Tim Northover6f3ff222015-10-30 16:30:27 +00001054 if (isTargetWatchOSBased() ||
1055 (isTargetIOSBased() && !isIPhoneOSVersionLT(6, 0))) {
1056 for (ArgList::iterator it = DAL->begin(), ie = DAL->end(); it != ie; ) {
Daniel Dunbarbd847cc2012-10-15 22:23:53 +00001057 Arg *A = *it;
1058 ++it;
1059 if (A->getOption().getID() != options::OPT_mkernel &&
1060 A->getOption().getID() != options::OPT_fapple_kext)
1061 continue;
1062 assert(it != ie && "unexpected argument translation");
1063 A = *it;
1064 assert(A->getOption().getID() == options::OPT_static &&
1065 "missing expected -static argument");
1066 it = DAL->getArgs().erase(it);
1067 }
1068 }
1069
Tim Northoverb534ce42016-02-12 22:30:42 +00001070 if (!Args.getLastArg(options::OPT_stdlib_EQ) &&
Tim Northover3a098c12016-02-15 16:38:10 +00001071 GetCXXStdlibType(Args) == ToolChain::CST_Libcxx)
Tim Northoverb534ce42016-02-12 22:30:42 +00001072 DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_stdlib_EQ),
1073 "libc++");
1074
Bob Wilson102be442011-10-07 17:54:41 +00001075 // Validate the C++ standard library choice.
1076 CXXStdlibType Type = GetCXXStdlibType(*DAL);
1077 if (Type == ToolChain::CST_Libcxx) {
John McCall5fb5df92012-06-20 06:18:46 +00001078 // Check whether the target provides libc++.
1079 StringRef where;
1080
Alp Tokerf6a24ce2013-12-05 16:25:25 +00001081 // Complain about targeting iOS < 5.0 in any way.
Tim Northover9c7e0352013-12-12 11:55:52 +00001082 if (isTargetIOSBased() && isIPhoneOSVersionLT(5, 0))
Bob Wilson5ad5a952012-11-09 01:59:30 +00001083 where = "iOS 5.0";
John McCall5fb5df92012-06-20 06:18:46 +00001084
1085 if (where != StringRef()) {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00001086 getDriver().Diag(clang::diag::err_drv_invalid_libcxx_deployment) << where;
Bob Wilson102be442011-10-07 17:54:41 +00001087 }
1088 }
1089
Daniel Dunbaraabb0b12009-03-25 06:12:34 +00001090 return DAL;
Mike Stump11289f42009-09-09 15:08:12 +00001091}
Daniel Dunbar03e0a4f2009-03-20 00:57:52 +00001092
Tim Northover157d9112014-01-16 08:48:16 +00001093bool MachO::IsUnwindTablesDefault() const {
Rafael Espindolae8bd4e52012-10-07 03:23:40 +00001094 return getArch() == llvm::Triple::x86_64;
Daniel Dunbar03e0a4f2009-03-20 00:57:52 +00001095}
1096
Tim Northover157d9112014-01-16 08:48:16 +00001097bool MachO::UseDwarfDebugFlags() const {
Daniel Dunbar24c7f5e2009-12-18 02:43:17 +00001098 if (const char *S = ::getenv("RC_DEBUG_OPTIONS"))
1099 return S[0] != '\0';
1100 return false;
1101}
1102
Tim Northovere931f9f2015-10-30 16:30:41 +00001103bool Darwin::UseSjLjExceptions(const ArgList &Args) const {
Daniel Dunbar3241d402010-02-10 18:49:11 +00001104 // Darwin uses SjLj exceptions on ARM.
Tim Northovere931f9f2015-10-30 16:30:41 +00001105 if (getTriple().getArch() != llvm::Triple::arm &&
1106 getTriple().getArch() != llvm::Triple::thumb)
1107 return false;
1108
Tim Northoverc741b042015-11-17 18:27:27 +00001109 // Only watchOS uses the new DWARF/Compact unwinding method.
Tim Northoverd88ecb32016-01-27 19:32:40 +00001110 llvm::Triple Triple(ComputeLLVMTriple(Args));
Tim Northover4c9ac7d2016-01-27 22:14:02 +00001111 return !Triple.isWatchABI();
Daniel Dunbar3241d402010-02-10 18:49:11 +00001112}
1113
Steven Wu574b0f22016-03-01 01:07:58 +00001114bool Darwin::SupportsEmbeddedBitcode() const {
1115 assert(TargetInitialized && "Target not initialized!");
1116 if (isTargetIPhoneOS() && isIPhoneOSVersionLT(6, 0))
1117 return false;
1118 return true;
1119}
1120
Douglas Katzmana67e50c2015-06-26 15:47:46 +00001121bool MachO::isPICDefault() const { return true; }
Daniel Dunbar03e0a4f2009-03-20 00:57:52 +00001122
Douglas Katzmana67e50c2015-06-26 15:47:46 +00001123bool MachO::isPIEDefault() const { return false; }
Peter Collingbourne54d770c2013-04-09 04:35:11 +00001124
Tim Northover157d9112014-01-16 08:48:16 +00001125bool MachO::isPICDefaultForced() const {
Tim Northovera2ee4332014-03-29 15:09:45 +00001126 return (getArch() == llvm::Triple::x86_64 ||
Tim Northover573cbee2014-05-24 12:52:07 +00001127 getArch() == llvm::Triple::aarch64);
Daniel Dunbar03e0a4f2009-03-20 00:57:52 +00001128}
1129
Tim Northover157d9112014-01-16 08:48:16 +00001130bool MachO::SupportsProfiling() const {
Daniel Dunbar733b0f82011-03-01 18:49:30 +00001131 // Profiling instrumentation is only supported on x86.
Rafael Espindola35ca7d92012-10-07 04:44:33 +00001132 return getArch() == llvm::Triple::x86 || getArch() == llvm::Triple::x86_64;
Daniel Dunbar733b0f82011-03-01 18:49:30 +00001133}
1134
Douglas Katzmanf08fadf2015-06-04 14:40:44 +00001135void Darwin::addMinVersionArgs(const ArgList &Args,
1136 ArgStringList &CmdArgs) const {
Tim Northover157d9112014-01-16 08:48:16 +00001137 VersionTuple TargetVersion = getTargetVersion();
1138
Tim Northover6f3ff222015-10-30 16:30:27 +00001139 if (isTargetWatchOS())
1140 CmdArgs.push_back("-watchos_version_min");
1141 else if (isTargetWatchOSSimulator())
1142 CmdArgs.push_back("-watchos_simulator_version_min");
1143 else if (isTargetTvOS())
1144 CmdArgs.push_back("-tvos_version_min");
1145 else if (isTargetTvOSSimulator())
1146 CmdArgs.push_back("-tvos_simulator_version_min");
1147 else if (isTargetIOSSimulator())
Tim Northover157d9112014-01-16 08:48:16 +00001148 CmdArgs.push_back("-ios_simulator_version_min");
Bob Wilson5cfc55e2014-02-01 21:06:21 +00001149 else if (isTargetIOSBased())
Tim Northover157d9112014-01-16 08:48:16 +00001150 CmdArgs.push_back("-iphoneos_version_min");
1151 else {
1152 assert(isTargetMacOS() && "unexpected target");
1153 CmdArgs.push_back("-macosx_version_min");
1154 }
1155
1156 CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString()));
1157}
1158
Douglas Katzmanf08fadf2015-06-04 14:40:44 +00001159void Darwin::addStartObjectFileArgs(const ArgList &Args,
1160 ArgStringList &CmdArgs) const {
Tim Northover157d9112014-01-16 08:48:16 +00001161 // Derived from startfile spec.
1162 if (Args.hasArg(options::OPT_dynamiclib)) {
1163 // Derived from darwin_dylib1 spec.
Tim Northover6f3ff222015-10-30 16:30:27 +00001164 if (isTargetWatchOSBased()) {
1165 ; // watchOS does not need dylib1.o.
1166 } else if (isTargetIOSSimulator()) {
Bob Wilson74b6cd12014-01-21 00:17:10 +00001167 ; // iOS simulator does not need dylib1.o.
Tim Northover157d9112014-01-16 08:48:16 +00001168 } else if (isTargetIPhoneOS()) {
1169 if (isIPhoneOSVersionLT(3, 1))
1170 CmdArgs.push_back("-ldylib1.o");
1171 } else {
1172 if (isMacosxVersionLT(10, 5))
1173 CmdArgs.push_back("-ldylib1.o");
1174 else if (isMacosxVersionLT(10, 6))
1175 CmdArgs.push_back("-ldylib1.10.5.o");
1176 }
1177 } else {
1178 if (Args.hasArg(options::OPT_bundle)) {
1179 if (!Args.hasArg(options::OPT_static)) {
1180 // Derived from darwin_bundle1 spec.
Tim Northover6f3ff222015-10-30 16:30:27 +00001181 if (isTargetWatchOSBased()) {
1182 ; // watchOS does not need bundle1.o.
1183 } else if (isTargetIOSSimulator()) {
Bob Wilson74b6cd12014-01-21 00:17:10 +00001184 ; // iOS simulator does not need bundle1.o.
Tim Northover157d9112014-01-16 08:48:16 +00001185 } else if (isTargetIPhoneOS()) {
1186 if (isIPhoneOSVersionLT(3, 1))
1187 CmdArgs.push_back("-lbundle1.o");
1188 } else {
1189 if (isMacosxVersionLT(10, 6))
1190 CmdArgs.push_back("-lbundle1.o");
1191 }
1192 }
1193 } else {
1194 if (Args.hasArg(options::OPT_pg) && SupportsProfiling()) {
1195 if (Args.hasArg(options::OPT_static) ||
1196 Args.hasArg(options::OPT_object) ||
1197 Args.hasArg(options::OPT_preload)) {
1198 CmdArgs.push_back("-lgcrt0.o");
1199 } else {
1200 CmdArgs.push_back("-lgcrt1.o");
1201
1202 // darwin_crt2 spec is empty.
1203 }
1204 // By default on OS X 10.8 and later, we don't link with a crt1.o
1205 // file and the linker knows to use _main as the entry point. But,
1206 // when compiling with -pg, we need to link with the gcrt1.o file,
1207 // so pass the -no_new_main option to tell the linker to use the
1208 // "start" symbol as the entry point.
1209 if (isTargetMacOS() && !isMacosxVersionLT(10, 8))
1210 CmdArgs.push_back("-no_new_main");
1211 } else {
1212 if (Args.hasArg(options::OPT_static) ||
1213 Args.hasArg(options::OPT_object) ||
1214 Args.hasArg(options::OPT_preload)) {
1215 CmdArgs.push_back("-lcrt0.o");
1216 } else {
1217 // Derived from darwin_crt1 spec.
Tim Northover6f3ff222015-10-30 16:30:27 +00001218 if (isTargetWatchOSBased()) {
1219 ; // watchOS does not need crt1.o.
1220 } else if (isTargetIOSSimulator()) {
Bob Wilson74b6cd12014-01-21 00:17:10 +00001221 ; // iOS simulator does not need crt1.o.
Tim Northover157d9112014-01-16 08:48:16 +00001222 } else if (isTargetIPhoneOS()) {
Tim Northover40956e62014-07-23 12:32:58 +00001223 if (getArch() == llvm::Triple::aarch64)
Tim Northovera2ee4332014-03-29 15:09:45 +00001224 ; // iOS does not need any crt1 files for arm64
1225 else if (isIPhoneOSVersionLT(3, 1))
Tim Northover157d9112014-01-16 08:48:16 +00001226 CmdArgs.push_back("-lcrt1.o");
1227 else if (isIPhoneOSVersionLT(6, 0))
1228 CmdArgs.push_back("-lcrt1.3.1.o");
1229 } else {
1230 if (isMacosxVersionLT(10, 5))
1231 CmdArgs.push_back("-lcrt1.o");
1232 else if (isMacosxVersionLT(10, 6))
1233 CmdArgs.push_back("-lcrt1.10.5.o");
1234 else if (isMacosxVersionLT(10, 8))
1235 CmdArgs.push_back("-lcrt1.10.6.o");
1236
1237 // darwin_crt2 spec is empty.
1238 }
1239 }
1240 }
1241 }
1242 }
1243
1244 if (!isTargetIPhoneOS() && Args.hasArg(options::OPT_shared_libgcc) &&
Tim Northover6f3ff222015-10-30 16:30:27 +00001245 !isTargetWatchOS() &&
Tim Northover157d9112014-01-16 08:48:16 +00001246 isMacosxVersionLT(10, 5)) {
1247 const char *Str = Args.MakeArgString(GetFilePath("crt3.o"));
1248 CmdArgs.push_back(Str);
1249 }
1250}
1251
Douglas Katzmana67e50c2015-06-26 15:47:46 +00001252bool Darwin::SupportsObjCGC() const { return isTargetMacOS(); }
Daniel Dunbar16334e12010-04-10 16:20:23 +00001253
John McCall3deb1ad2012-08-21 02:47:43 +00001254void Darwin::CheckObjCARC() const {
Tim Northover6f3ff222015-10-30 16:30:27 +00001255 if (isTargetIOSBased() || isTargetWatchOSBased() ||
1256 (isTargetMacOS() && !isMacosxVersionLT(10, 6)))
John McCall3deb1ad2012-08-21 02:47:43 +00001257 return;
John McCall93207072012-08-27 01:56:21 +00001258 getDriver().Diag(diag::err_arc_unsupported_on_toolchain);
Argyrios Kyrtzidis3dbeb552012-02-29 03:43:52 +00001259}
1260
Alexey Samsonov7f2a0d22015-06-19 21:36:47 +00001261SanitizerMask Darwin::getSupportedSanitizers() const {
Devin Coughlinfcfa38c2016-03-20 18:24:33 +00001262 const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64;
Alexey Samsonov7f2a0d22015-06-19 21:36:47 +00001263 SanitizerMask Res = ToolChain::getSupportedSanitizers();
Anna Zakse67b4022016-02-02 02:04:48 +00001264 Res |= SanitizerKind::Address;
Alexey Samsonov1d4cff22015-06-25 00:58:02 +00001265 if (isTargetMacOS()) {
1266 if (!isMacosxVersionLT(10, 9))
1267 Res |= SanitizerKind::Vptr;
Alexey Samsonov7f2a0d22015-06-19 21:36:47 +00001268 Res |= SanitizerKind::SafeStack;
Devin Coughlinfcfa38c2016-03-20 18:24:33 +00001269 if (IsX86_64)
1270 Res |= SanitizerKind::Thread;
1271 } else if (isTargetIOSSimulator() || isTargetTvOSSimulator()) {
1272 if (IsX86_64)
1273 Res |= SanitizerKind::Thread;
Alexey Samsonov1d4cff22015-06-25 00:58:02 +00001274 }
Alexey Samsonov7f2a0d22015-06-19 21:36:47 +00001275 return Res;
1276}
1277
Daniel Dunbar59e5e882009-03-20 00:20:03 +00001278/// Generic_GCC - A tool chain using the 'gcc' command to perform
1279/// all subcommands; this relies on gcc translating the majority of
1280/// command line options.
1281
Chandler Carruth4c90fba2011-11-06 23:39:34 +00001282/// \brief Parse a GCCVersion object out of a string of text.
1283///
1284/// This is the primary means of forming GCCVersion objects.
1285/*static*/
1286Generic_GCC::GCCVersion Linux::GCCVersion::Parse(StringRef VersionText) {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00001287 const GCCVersion BadVersion = {VersionText.str(), -1, -1, -1, "", "", ""};
Chandler Carruth4c90fba2011-11-06 23:39:34 +00001288 std::pair<StringRef, StringRef> First = VersionText.split('.');
1289 std::pair<StringRef, StringRef> Second = First.second.split('.');
1290
Douglas Katzmana67e50c2015-06-26 15:47:46 +00001291 GCCVersion GoodVersion = {VersionText.str(), -1, -1, -1, "", "", ""};
1292 if (First.first.getAsInteger(10, GoodVersion.Major) || GoodVersion.Major < 0)
Chandler Carruth4c90fba2011-11-06 23:39:34 +00001293 return BadVersion;
Chandler Carruth1f2b2f82013-08-26 08:59:53 +00001294 GoodVersion.MajorStr = First.first.str();
Bryan Chand346ae62016-06-17 16:47:14 +00001295 if (First.second.empty())
1296 return GoodVersion;
Douglas Katzmana67e50c2015-06-26 15:47:46 +00001297 if (Second.first.getAsInteger(10, GoodVersion.Minor) || GoodVersion.Minor < 0)
Chandler Carruth4c90fba2011-11-06 23:39:34 +00001298 return BadVersion;
Chandler Carruth1f2b2f82013-08-26 08:59:53 +00001299 GoodVersion.MinorStr = Second.first.str();
Chandler Carruth4c90fba2011-11-06 23:39:34 +00001300
1301 // First look for a number prefix and parse that if present. Otherwise just
1302 // stash the entire patch string in the suffix, and leave the number
1303 // unspecified. This covers versions strings such as:
Bryan Chand346ae62016-06-17 16:47:14 +00001304 // 5 (handled above)
Chandler Carruth4c90fba2011-11-06 23:39:34 +00001305 // 4.4
1306 // 4.4.0
1307 // 4.4.x
1308 // 4.4.2-rc4
1309 // 4.4.x-patched
1310 // And retains any patch number it finds.
1311 StringRef PatchText = GoodVersion.PatchSuffix = Second.second.str();
1312 if (!PatchText.empty()) {
Will Dietza38608b2013-01-10 22:20:02 +00001313 if (size_t EndNumber = PatchText.find_first_not_of("0123456789")) {
Chandler Carruth4c90fba2011-11-06 23:39:34 +00001314 // Try to parse the number and any suffix.
1315 if (PatchText.slice(0, EndNumber).getAsInteger(10, GoodVersion.Patch) ||
1316 GoodVersion.Patch < 0)
1317 return BadVersion;
Chandler Carruth1f2b2f82013-08-26 08:59:53 +00001318 GoodVersion.PatchSuffix = PatchText.substr(EndNumber);
Chandler Carruth4c90fba2011-11-06 23:39:34 +00001319 }
1320 }
1321
1322 return GoodVersion;
1323}
1324
1325/// \brief Less-than for GCCVersion, implementing a Strict Weak Ordering.
Benjamin Kramer604e8482013-08-09 17:17:48 +00001326bool Generic_GCC::GCCVersion::isOlderThan(int RHSMajor, int RHSMinor,
1327 int RHSPatch,
1328 StringRef RHSPatchSuffix) const {
1329 if (Major != RHSMajor)
1330 return Major < RHSMajor;
1331 if (Minor != RHSMinor)
1332 return Minor < RHSMinor;
1333 if (Patch != RHSPatch) {
Chandler Carruth5193dfc2012-12-29 12:01:08 +00001334 // Note that versions without a specified patch sort higher than those with
1335 // a patch.
Benjamin Kramer604e8482013-08-09 17:17:48 +00001336 if (RHSPatch == -1)
Chandler Carruth5193dfc2012-12-29 12:01:08 +00001337 return true;
1338 if (Patch == -1)
1339 return false;
Chandler Carruth4c90fba2011-11-06 23:39:34 +00001340
Chandler Carruth5193dfc2012-12-29 12:01:08 +00001341 // Otherwise just sort on the patch itself.
Benjamin Kramer604e8482013-08-09 17:17:48 +00001342 return Patch < RHSPatch;
Chandler Carruth5193dfc2012-12-29 12:01:08 +00001343 }
Benjamin Kramer604e8482013-08-09 17:17:48 +00001344 if (PatchSuffix != RHSPatchSuffix) {
Chandler Carruth5193dfc2012-12-29 12:01:08 +00001345 // Sort empty suffixes higher.
Benjamin Kramer604e8482013-08-09 17:17:48 +00001346 if (RHSPatchSuffix.empty())
Chandler Carruth5193dfc2012-12-29 12:01:08 +00001347 return true;
1348 if (PatchSuffix.empty())
Chandler Carruth19e8bea2012-12-29 13:00:47 +00001349 return false;
Chandler Carruth4c90fba2011-11-06 23:39:34 +00001350
Chandler Carruth5193dfc2012-12-29 12:01:08 +00001351 // Provide a lexicographic sort to make this a total ordering.
Benjamin Kramer604e8482013-08-09 17:17:48 +00001352 return PatchSuffix < RHSPatchSuffix;
Chandler Carruth5193dfc2012-12-29 12:01:08 +00001353 }
1354
1355 // The versions are equal.
Chandler Carruth4c90fba2011-11-06 23:39:34 +00001356 return false;
1357}
1358
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00001359static llvm::StringRef getGCCToolchainDir(const ArgList &Args) {
Rafael Espindola1af7c212012-02-19 01:38:32 +00001360 const Arg *A = Args.getLastArg(options::OPT_gcc_toolchain);
1361 if (A)
Richard Smithbd55daf2012-11-01 04:30:05 +00001362 return A->getValue();
Rafael Espindola1af7c212012-02-19 01:38:32 +00001363 return GCC_INSTALL_PREFIX;
1364}
1365
Roman Divacky326d9982013-12-06 18:32:18 +00001366/// \brief Initialize a GCCInstallationDetector from the driver.
Chandler Carruth4c90fba2011-11-06 23:39:34 +00001367///
1368/// This performs all of the autodetection and sets up the various paths.
Gabor Greif8a45d572012-04-17 11:16:26 +00001369/// Once constructed, a GCCInstallationDetector is essentially immutable.
Chandler Carruth866faab2012-01-25 07:21:38 +00001370///
1371/// FIXME: We shouldn't need an explicit TargetTriple parameter here, and
1372/// should instead pull the target out of the driver. This is currently
1373/// necessary because the driver doesn't store the final version of the target
1374/// triple.
Douglas Katzmana67e50c2015-06-26 15:47:46 +00001375void Generic_GCC::GCCInstallationDetector::init(
Benjamin Kramerd45b2052015-10-07 15:48:01 +00001376 const llvm::Triple &TargetTriple, const ArgList &Args,
Douglas Katzman8c39e6a2015-09-18 15:23:16 +00001377 ArrayRef<std::string> ExtraTripleAliases) {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00001378 llvm::Triple BiarchVariantTriple = TargetTriple.isArch32Bit()
1379 ? TargetTriple.get64BitArchVariant()
1380 : TargetTriple.get32BitArchVariant();
Chandler Carruth4c90fba2011-11-06 23:39:34 +00001381 // The library directories which may contain GCC installations.
Chandler Carruthb427c562013-06-22 11:35:51 +00001382 SmallVector<StringRef, 4> CandidateLibDirs, CandidateBiarchLibDirs;
Chandler Carruth4c90fba2011-11-06 23:39:34 +00001383 // The compatible GCC triples for this particular architecture.
Hans Wennborg90aa63f2014-08-11 18:09:28 +00001384 SmallVector<StringRef, 16> CandidateTripleAliases;
1385 SmallVector<StringRef, 16> CandidateBiarchTripleAliases;
Chandler Carruthb427c562013-06-22 11:35:51 +00001386 CollectLibDirsAndTriples(TargetTriple, BiarchVariantTriple, CandidateLibDirs,
1387 CandidateTripleAliases, CandidateBiarchLibDirs,
1388 CandidateBiarchTripleAliases);
Chandler Carruth4c90fba2011-11-06 23:39:34 +00001389
1390 // Compute the set of prefixes for our search.
1391 SmallVector<std::string, 8> Prefixes(D.PrefixDirs.begin(),
1392 D.PrefixDirs.end());
Rafael Espindolac29af942012-02-03 01:01:20 +00001393
Rafael Espindola1af7c212012-02-19 01:38:32 +00001394 StringRef GCCToolchainDir = getGCCToolchainDir(Args);
1395 if (GCCToolchainDir != "") {
1396 if (GCCToolchainDir.back() == '/')
1397 GCCToolchainDir = GCCToolchainDir.drop_back(); // remove the /
Rafael Espindolac29af942012-02-03 01:01:20 +00001398
Rafael Espindola1af7c212012-02-19 01:38:32 +00001399 Prefixes.push_back(GCCToolchainDir);
Rafael Espindolac29af942012-02-03 01:01:20 +00001400 } else {
Rafael Espindola0f4b04e2013-08-28 23:17:47 +00001401 // If we have a SysRoot, try that first.
1402 if (!D.SysRoot.empty()) {
1403 Prefixes.push_back(D.SysRoot);
1404 Prefixes.push_back(D.SysRoot + "/usr");
1405 }
1406
1407 // Then look for gcc installed alongside clang.
Rafael Espindolac29af942012-02-03 01:01:20 +00001408 Prefixes.push_back(D.InstalledDir + "/..");
Rafael Espindola0f4b04e2013-08-28 23:17:47 +00001409
Rafael Espindola2edca412016-05-09 13:03:10 +00001410 // Then look for distribution supplied gcc installations.
1411 if (D.SysRoot.empty()) {
1412 // Look for RHEL devtoolsets.
1413 Prefixes.push_back("/opt/rh/devtoolset-4/root/usr");
1414 Prefixes.push_back("/opt/rh/devtoolset-3/root/usr");
1415 Prefixes.push_back("/opt/rh/devtoolset-2/root/usr");
1416 Prefixes.push_back("/opt/rh/devtoolset-1.1/root/usr");
1417 Prefixes.push_back("/opt/rh/devtoolset-1.0/root/usr");
1418 // And finally in /usr.
Rafael Espindola0f4b04e2013-08-28 23:17:47 +00001419 Prefixes.push_back("/usr");
Rafael Espindola2edca412016-05-09 13:03:10 +00001420 }
Rafael Espindolac29af942012-02-03 01:01:20 +00001421 }
Chandler Carruth4c90fba2011-11-06 23:39:34 +00001422
1423 // Loop over the various components which exist and select the best GCC
1424 // installation available. GCC installs are ranked by version number.
1425 Version = GCCVersion::Parse("0.0.0");
Douglas Katzman6bbffc42015-06-25 18:51:37 +00001426 for (const std::string &Prefix : Prefixes) {
Benjamin Kramerd45b2052015-10-07 15:48:01 +00001427 if (!D.getVFS().exists(Prefix))
Chandler Carruth4c90fba2011-11-06 23:39:34 +00001428 continue;
Benjamin Kramer72e64312015-09-24 14:48:49 +00001429 for (StringRef Suffix : CandidateLibDirs) {
Douglas Katzman6bbffc42015-06-25 18:51:37 +00001430 const std::string LibDir = Prefix + Suffix.str();
Benjamin Kramerd45b2052015-10-07 15:48:01 +00001431 if (!D.getVFS().exists(LibDir))
Chandler Carruth4c90fba2011-11-06 23:39:34 +00001432 continue;
Benjamin Kramer72e64312015-09-24 14:48:49 +00001433 for (StringRef Candidate : ExtraTripleAliases) // Try these first.
Douglas Katzmand6e597c2015-09-17 19:56:40 +00001434 ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, Candidate);
Benjamin Kramer72e64312015-09-24 14:48:49 +00001435 for (StringRef Candidate : CandidateTripleAliases)
Douglas Katzman6bbffc42015-06-25 18:51:37 +00001436 ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, Candidate);
Chandler Carruth866faab2012-01-25 07:21:38 +00001437 }
Benjamin Kramer72e64312015-09-24 14:48:49 +00001438 for (StringRef Suffix : CandidateBiarchLibDirs) {
Douglas Katzman6bbffc42015-06-25 18:51:37 +00001439 const std::string LibDir = Prefix + Suffix.str();
Benjamin Kramerd45b2052015-10-07 15:48:01 +00001440 if (!D.getVFS().exists(LibDir))
Chandler Carruth866faab2012-01-25 07:21:38 +00001441 continue;
Benjamin Kramer72e64312015-09-24 14:48:49 +00001442 for (StringRef Candidate : CandidateBiarchTripleAliases)
Douglas Katzman6bbffc42015-06-25 18:51:37 +00001443 ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, Candidate,
Chandler Carruthb427c562013-06-22 11:35:51 +00001444 /*NeedsBiarchSuffix=*/ true);
Chandler Carruth4c90fba2011-11-06 23:39:34 +00001445 }
1446 }
1447}
1448
Chandler Carruth0ae39aa2013-07-30 17:57:09 +00001449void Generic_GCC::GCCInstallationDetector::print(raw_ostream &OS) const {
Simon Atanasyan6f657c42014-05-08 19:32:46 +00001450 for (const auto &InstallPath : CandidateGCCInstallPaths)
1451 OS << "Found candidate GCC installation: " << InstallPath << "\n";
Chandler Carruth0ae39aa2013-07-30 17:57:09 +00001452
Yunzhong Gaoe3f902c2014-02-19 19:06:58 +00001453 if (!GCCInstallPath.empty())
1454 OS << "Selected GCC installation: " << GCCInstallPath << "\n";
1455
Simon Atanasyan6f657c42014-05-08 19:32:46 +00001456 for (const auto &Multilib : Multilibs)
1457 OS << "Candidate multilib: " << Multilib << "\n";
Yunzhong Gaoe3f902c2014-02-19 19:06:58 +00001458
1459 if (Multilibs.size() != 0 || !SelectedMultilib.isDefault())
1460 OS << "Selected multilib: " << SelectedMultilib << "\n";
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00001461}
1462
1463bool Generic_GCC::GCCInstallationDetector::getBiarchSibling(Multilib &M) const {
1464 if (BiarchSibling.hasValue()) {
1465 M = BiarchSibling.getValue();
1466 return true;
1467 }
1468 return false;
Chandler Carruth0ae39aa2013-07-30 17:57:09 +00001469}
1470
Chandler Carruth4c90fba2011-11-06 23:39:34 +00001471/*static*/ void Generic_GCC::GCCInstallationDetector::CollectLibDirsAndTriples(
Chandler Carruthb427c562013-06-22 11:35:51 +00001472 const llvm::Triple &TargetTriple, const llvm::Triple &BiarchTriple,
Chandler Carruth866faab2012-01-25 07:21:38 +00001473 SmallVectorImpl<StringRef> &LibDirs,
1474 SmallVectorImpl<StringRef> &TripleAliases,
Chandler Carruthb427c562013-06-22 11:35:51 +00001475 SmallVectorImpl<StringRef> &BiarchLibDirs,
1476 SmallVectorImpl<StringRef> &BiarchTripleAliases) {
Chandler Carruth866faab2012-01-25 07:21:38 +00001477 // Declare a bunch of static data sets that we'll select between below. These
1478 // are specifically designed to always refer to string literals to avoid any
1479 // lifetime or initialization issues.
Douglas Katzmana67e50c2015-06-26 15:47:46 +00001480 static const char *const AArch64LibDirs[] = {"/lib64", "/lib"};
1481 static const char *const AArch64Triples[] = {
1482 "aarch64-none-linux-gnu", "aarch64-linux-gnu", "aarch64-linux-android",
1483 "aarch64-redhat-linux"};
1484 static const char *const AArch64beLibDirs[] = {"/lib"};
1485 static const char *const AArch64beTriples[] = {"aarch64_be-none-linux-gnu",
1486 "aarch64_be-linux-gnu"};
Tim Northover9bb857a2013-01-31 12:13:10 +00001487
Douglas Katzmana67e50c2015-06-26 15:47:46 +00001488 static const char *const ARMLibDirs[] = {"/lib"};
1489 static const char *const ARMTriples[] = {"arm-linux-gnueabi",
1490 "arm-linux-androideabi"};
1491 static const char *const ARMHFTriples[] = {"arm-linux-gnueabihf",
1492 "armv7hl-redhat-linux-gnueabi"};
1493 static const char *const ARMebLibDirs[] = {"/lib"};
1494 static const char *const ARMebTriples[] = {"armeb-linux-gnueabi",
1495 "armeb-linux-androideabi"};
1496 static const char *const ARMebHFTriples[] = {
1497 "armeb-linux-gnueabihf", "armebv7hl-redhat-linux-gnueabi"};
Chandler Carruth866faab2012-01-25 07:21:38 +00001498
Douglas Katzmana67e50c2015-06-26 15:47:46 +00001499 static const char *const X86_64LibDirs[] = {"/lib64", "/lib"};
Chandler Carruth866faab2012-01-25 07:21:38 +00001500 static const char *const X86_64Triples[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00001501 "x86_64-linux-gnu", "x86_64-unknown-linux-gnu",
1502 "x86_64-pc-linux-gnu", "x86_64-redhat-linux6E",
1503 "x86_64-redhat-linux", "x86_64-suse-linux",
1504 "x86_64-manbo-linux-gnu", "x86_64-linux-gnu",
1505 "x86_64-slackware-linux", "x86_64-linux-android",
1506 "x86_64-unknown-linux"};
1507 static const char *const X32LibDirs[] = {"/libx32"};
1508 static const char *const X86LibDirs[] = {"/lib32", "/lib"};
Chandler Carruth866faab2012-01-25 07:21:38 +00001509 static const char *const X86Triples[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00001510 "i686-linux-gnu", "i686-pc-linux-gnu", "i486-linux-gnu",
1511 "i386-linux-gnu", "i386-redhat-linux6E", "i686-redhat-linux",
1512 "i586-redhat-linux", "i386-redhat-linux", "i586-suse-linux",
1513 "i486-slackware-linux", "i686-montavista-linux", "i686-linux-android",
1514 "i586-linux-gnu"};
Chandler Carruth866faab2012-01-25 07:21:38 +00001515
Douglas Katzmana67e50c2015-06-26 15:47:46 +00001516 static const char *const MIPSLibDirs[] = {"/lib"};
Vasileios Kalintirisc744e122015-11-12 15:26:54 +00001517 static const char *const MIPSTriples[] = {"mips-linux-gnu", "mips-mti-linux",
1518 "mips-mti-linux-gnu",
1519 "mips-img-linux-gnu"};
Douglas Katzmana67e50c2015-06-26 15:47:46 +00001520 static const char *const MIPSELLibDirs[] = {"/lib"};
Simon Atanasyan603018a2016-07-19 07:09:48 +00001521 static const char *const MIPSELTriples[] = {"mipsel-linux-gnu",
1522 "mips-img-linux-gnu"};
Chandler Carruth866faab2012-01-25 07:21:38 +00001523
Douglas Katzmana67e50c2015-06-26 15:47:46 +00001524 static const char *const MIPS64LibDirs[] = {"/lib64", "/lib"};
1525 static const char *const MIPS64Triples[] = {
1526 "mips64-linux-gnu", "mips-mti-linux-gnu", "mips-img-linux-gnu",
1527 "mips64-linux-gnuabi64"};
1528 static const char *const MIPS64ELLibDirs[] = {"/lib64", "/lib"};
1529 static const char *const MIPS64ELTriples[] = {
1530 "mips64el-linux-gnu", "mips-mti-linux-gnu", "mips-img-linux-gnu",
Simon Atanasyan603018a2016-07-19 07:09:48 +00001531 "mips64el-linux-gnuabi64"};
1532
1533 static const char *const MIPSELAndroidLibDirs[] = {"/lib", "/libr2",
1534 "/libr6"};
1535 static const char *const MIPSELAndroidTriples[] = {"mipsel-linux-android"};
1536 static const char *const MIPS64ELAndroidLibDirs[] = {"/lib64", "/lib",
1537 "/libr2", "/libr6"};
1538 static const char *const MIPS64ELAndroidTriples[] = {
1539 "mips64el-linux-android"};
Simon Atanasyan9bb634d2012-04-26 19:57:02 +00001540
Douglas Katzmana67e50c2015-06-26 15:47:46 +00001541 static const char *const PPCLibDirs[] = {"/lib32", "/lib"};
Chandler Carruth866faab2012-01-25 07:21:38 +00001542 static const char *const PPCTriples[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00001543 "powerpc-linux-gnu", "powerpc-unknown-linux-gnu", "powerpc-linux-gnuspe",
1544 "powerpc-suse-linux", "powerpc-montavista-linuxspe"};
1545 static const char *const PPC64LibDirs[] = {"/lib64", "/lib"};
1546 static const char *const PPC64Triples[] = {
1547 "powerpc64-linux-gnu", "powerpc64-unknown-linux-gnu",
1548 "powerpc64-suse-linux", "ppc64-redhat-linux"};
1549 static const char *const PPC64LELibDirs[] = {"/lib64", "/lib"};
1550 static const char *const PPC64LETriples[] = {
1551 "powerpc64le-linux-gnu", "powerpc64le-unknown-linux-gnu",
1552 "powerpc64le-suse-linux", "ppc64le-redhat-linux"};
Chandler Carruth866faab2012-01-25 07:21:38 +00001553
Douglas Katzmana67e50c2015-06-26 15:47:46 +00001554 static const char *const SPARCv8LibDirs[] = {"/lib32", "/lib"};
1555 static const char *const SPARCv8Triples[] = {"sparc-linux-gnu",
1556 "sparcv8-linux-gnu"};
1557 static const char *const SPARCv9LibDirs[] = {"/lib64", "/lib"};
1558 static const char *const SPARCv9Triples[] = {"sparc64-linux-gnu",
1559 "sparcv9-linux-gnu"};
Jakob Stoklund Olesenb3f938e2014-01-10 06:53:02 +00001560
Douglas Katzmana67e50c2015-06-26 15:47:46 +00001561 static const char *const SystemZLibDirs[] = {"/lib64", "/lib"};
Ulrich Weigand47445072013-05-06 16:26:41 +00001562 static const char *const SystemZTriples[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00001563 "s390x-linux-gnu", "s390x-unknown-linux-gnu", "s390x-ibm-linux-gnu",
1564 "s390x-suse-linux", "s390x-redhat-linux"};
Ulrich Weigand47445072013-05-06 16:26:41 +00001565
Rafael Espindolac53c5b12015-08-31 19:17:51 +00001566 // Solaris.
1567 static const char *const SolarisSPARCLibDirs[] = {"/gcc"};
1568 static const char *const SolarisSPARCTriples[] = {"sparc-sun-solaris2.11",
1569 "i386-pc-solaris2.11"};
1570
Benjamin Kramer6ec434e2014-10-18 10:43:51 +00001571 using std::begin;
1572 using std::end;
1573
Rafael Espindolac53c5b12015-08-31 19:17:51 +00001574 if (TargetTriple.getOS() == llvm::Triple::Solaris) {
1575 LibDirs.append(begin(SolarisSPARCLibDirs), end(SolarisSPARCLibDirs));
1576 TripleAliases.append(begin(SolarisSPARCTriples), end(SolarisSPARCTriples));
Rafael Espindolac53c5b12015-08-31 19:17:51 +00001577 return;
1578 }
1579
Chandler Carruth866faab2012-01-25 07:21:38 +00001580 switch (TargetTriple.getArch()) {
Tim Northover9bb857a2013-01-31 12:13:10 +00001581 case llvm::Triple::aarch64:
Benjamin Kramer6ec434e2014-10-18 10:43:51 +00001582 LibDirs.append(begin(AArch64LibDirs), end(AArch64LibDirs));
1583 TripleAliases.append(begin(AArch64Triples), end(AArch64Triples));
1584 BiarchLibDirs.append(begin(AArch64LibDirs), end(AArch64LibDirs));
1585 BiarchTripleAliases.append(begin(AArch64Triples), end(AArch64Triples));
Tim Northover9bb857a2013-01-31 12:13:10 +00001586 break;
Christian Pirkera74c7912014-03-14 12:15:45 +00001587 case llvm::Triple::aarch64_be:
Benjamin Kramer6ec434e2014-10-18 10:43:51 +00001588 LibDirs.append(begin(AArch64beLibDirs), end(AArch64beLibDirs));
1589 TripleAliases.append(begin(AArch64beTriples), end(AArch64beTriples));
1590 BiarchLibDirs.append(begin(AArch64beLibDirs), end(AArch64beLibDirs));
1591 BiarchTripleAliases.append(begin(AArch64beTriples), end(AArch64beTriples));
Christian Pirkera74c7912014-03-14 12:15:45 +00001592 break;
Chandler Carruth866faab2012-01-25 07:21:38 +00001593 case llvm::Triple::arm:
1594 case llvm::Triple::thumb:
Benjamin Kramer6ec434e2014-10-18 10:43:51 +00001595 LibDirs.append(begin(ARMLibDirs), end(ARMLibDirs));
Jiangning Liu61b06cb2012-07-31 08:06:29 +00001596 if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF) {
Benjamin Kramer6ec434e2014-10-18 10:43:51 +00001597 TripleAliases.append(begin(ARMHFTriples), end(ARMHFTriples));
Jiangning Liu61b06cb2012-07-31 08:06:29 +00001598 } else {
Benjamin Kramer6ec434e2014-10-18 10:43:51 +00001599 TripleAliases.append(begin(ARMTriples), end(ARMTriples));
Jiangning Liu61b06cb2012-07-31 08:06:29 +00001600 }
Chandler Carruth866faab2012-01-25 07:21:38 +00001601 break;
Christian Pirkerf01cd6f2014-03-28 14:40:46 +00001602 case llvm::Triple::armeb:
1603 case llvm::Triple::thumbeb:
Benjamin Kramer6ec434e2014-10-18 10:43:51 +00001604 LibDirs.append(begin(ARMebLibDirs), end(ARMebLibDirs));
Christian Pirkerf01cd6f2014-03-28 14:40:46 +00001605 if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF) {
Benjamin Kramer6ec434e2014-10-18 10:43:51 +00001606 TripleAliases.append(begin(ARMebHFTriples), end(ARMebHFTriples));
Christian Pirkerf01cd6f2014-03-28 14:40:46 +00001607 } else {
Benjamin Kramer6ec434e2014-10-18 10:43:51 +00001608 TripleAliases.append(begin(ARMebTriples), end(ARMebTriples));
Christian Pirkerf01cd6f2014-03-28 14:40:46 +00001609 }
1610 break;
Chandler Carruth866faab2012-01-25 07:21:38 +00001611 case llvm::Triple::x86_64:
Benjamin Kramer6ec434e2014-10-18 10:43:51 +00001612 LibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs));
1613 TripleAliases.append(begin(X86_64Triples), end(X86_64Triples));
1614 // x32 is always available when x86_64 is available, so adding it as
1615 // secondary arch with x86_64 triples
Zinovy Nis1db95732014-07-10 15:27:19 +00001616 if (TargetTriple.getEnvironment() == llvm::Triple::GNUX32) {
Benjamin Kramer6ec434e2014-10-18 10:43:51 +00001617 BiarchLibDirs.append(begin(X32LibDirs), end(X32LibDirs));
1618 BiarchTripleAliases.append(begin(X86_64Triples), end(X86_64Triples));
Zinovy Nis1db95732014-07-10 15:27:19 +00001619 } else {
Benjamin Kramer6ec434e2014-10-18 10:43:51 +00001620 BiarchLibDirs.append(begin(X86LibDirs), end(X86LibDirs));
1621 BiarchTripleAliases.append(begin(X86Triples), end(X86Triples));
Zinovy Nis1db95732014-07-10 15:27:19 +00001622 }
Chandler Carruth866faab2012-01-25 07:21:38 +00001623 break;
1624 case llvm::Triple::x86:
Benjamin Kramer6ec434e2014-10-18 10:43:51 +00001625 LibDirs.append(begin(X86LibDirs), end(X86LibDirs));
Andrey Turetskiy4798eb62016-06-16 10:36:09 +00001626 // MCU toolchain is 32 bit only and its triple alias is TargetTriple
1627 // itself, which will be appended below.
1628 if (!TargetTriple.isOSIAMCU()) {
1629 TripleAliases.append(begin(X86Triples), end(X86Triples));
1630 BiarchLibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs));
1631 BiarchTripleAliases.append(begin(X86_64Triples), end(X86_64Triples));
1632 }
Chandler Carruth866faab2012-01-25 07:21:38 +00001633 break;
1634 case llvm::Triple::mips:
Benjamin Kramer6ec434e2014-10-18 10:43:51 +00001635 LibDirs.append(begin(MIPSLibDirs), end(MIPSLibDirs));
1636 TripleAliases.append(begin(MIPSTriples), end(MIPSTriples));
1637 BiarchLibDirs.append(begin(MIPS64LibDirs), end(MIPS64LibDirs));
1638 BiarchTripleAliases.append(begin(MIPS64Triples), end(MIPS64Triples));
Chandler Carruth866faab2012-01-25 07:21:38 +00001639 break;
1640 case llvm::Triple::mipsel:
Simon Atanasyan603018a2016-07-19 07:09:48 +00001641 if (TargetTriple.isAndroid()) {
1642 LibDirs.append(begin(MIPSELAndroidLibDirs), end(MIPSELAndroidLibDirs));
1643 TripleAliases.append(begin(MIPSELAndroidTriples),
1644 end(MIPSELAndroidTriples));
1645 BiarchLibDirs.append(begin(MIPS64ELAndroidLibDirs),
1646 end(MIPS64ELAndroidLibDirs));
1647 BiarchTripleAliases.append(begin(MIPS64ELAndroidTriples),
1648 end(MIPS64ELAndroidTriples));
1649
1650 } else {
1651 LibDirs.append(begin(MIPSELLibDirs), end(MIPSELLibDirs));
1652 TripleAliases.append(begin(MIPSELTriples), end(MIPSELTriples));
1653 TripleAliases.append(begin(MIPSTriples), end(MIPSTriples));
1654 BiarchLibDirs.append(begin(MIPS64ELLibDirs), end(MIPS64ELLibDirs));
1655 BiarchTripleAliases.append(begin(MIPS64ELTriples), end(MIPS64ELTriples));
1656 }
Simon Atanasyan9bb634d2012-04-26 19:57:02 +00001657 break;
1658 case llvm::Triple::mips64:
Benjamin Kramer6ec434e2014-10-18 10:43:51 +00001659 LibDirs.append(begin(MIPS64LibDirs), end(MIPS64LibDirs));
1660 TripleAliases.append(begin(MIPS64Triples), end(MIPS64Triples));
1661 BiarchLibDirs.append(begin(MIPSLibDirs), end(MIPSLibDirs));
1662 BiarchTripleAliases.append(begin(MIPSTriples), end(MIPSTriples));
Simon Atanasyan9bb634d2012-04-26 19:57:02 +00001663 break;
1664 case llvm::Triple::mips64el:
Simon Atanasyan603018a2016-07-19 07:09:48 +00001665 if (TargetTriple.isAndroid()) {
1666 LibDirs.append(begin(MIPS64ELAndroidLibDirs),
1667 end(MIPS64ELAndroidLibDirs));
1668 TripleAliases.append(begin(MIPS64ELAndroidTriples),
1669 end(MIPS64ELAndroidTriples));
1670 BiarchLibDirs.append(begin(MIPSELAndroidLibDirs),
1671 end(MIPSELAndroidLibDirs));
1672 BiarchTripleAliases.append(begin(MIPSELAndroidTriples),
1673 end(MIPSELAndroidTriples));
1674
1675 } else {
1676 LibDirs.append(begin(MIPS64ELLibDirs), end(MIPS64ELLibDirs));
1677 TripleAliases.append(begin(MIPS64ELTriples), end(MIPS64ELTriples));
1678 BiarchLibDirs.append(begin(MIPSELLibDirs), end(MIPSELLibDirs));
1679 BiarchTripleAliases.append(begin(MIPSELTriples), end(MIPSELTriples));
1680 BiarchTripleAliases.append(begin(MIPSTriples), end(MIPSTriples));
1681 }
Chandler Carruth866faab2012-01-25 07:21:38 +00001682 break;
1683 case llvm::Triple::ppc:
Benjamin Kramer6ec434e2014-10-18 10:43:51 +00001684 LibDirs.append(begin(PPCLibDirs), end(PPCLibDirs));
1685 TripleAliases.append(begin(PPCTriples), end(PPCTriples));
1686 BiarchLibDirs.append(begin(PPC64LibDirs), end(PPC64LibDirs));
1687 BiarchTripleAliases.append(begin(PPC64Triples), end(PPC64Triples));
Chandler Carruth866faab2012-01-25 07:21:38 +00001688 break;
1689 case llvm::Triple::ppc64:
Benjamin Kramer6ec434e2014-10-18 10:43:51 +00001690 LibDirs.append(begin(PPC64LibDirs), end(PPC64LibDirs));
1691 TripleAliases.append(begin(PPC64Triples), end(PPC64Triples));
1692 BiarchLibDirs.append(begin(PPCLibDirs), end(PPCLibDirs));
1693 BiarchTripleAliases.append(begin(PPCTriples), end(PPCTriples));
Chandler Carruth866faab2012-01-25 07:21:38 +00001694 break;
Bill Schmidt778d3872013-07-26 01:36:11 +00001695 case llvm::Triple::ppc64le:
Benjamin Kramer6ec434e2014-10-18 10:43:51 +00001696 LibDirs.append(begin(PPC64LELibDirs), end(PPC64LELibDirs));
1697 TripleAliases.append(begin(PPC64LETriples), end(PPC64LETriples));
Bill Schmidt778d3872013-07-26 01:36:11 +00001698 break;
Jakob Stoklund Olesenb3f938e2014-01-10 06:53:02 +00001699 case llvm::Triple::sparc:
Douglas Katzmanb76a3df2015-09-02 13:33:42 +00001700 case llvm::Triple::sparcel:
Benjamin Kramer6ec434e2014-10-18 10:43:51 +00001701 LibDirs.append(begin(SPARCv8LibDirs), end(SPARCv8LibDirs));
1702 TripleAliases.append(begin(SPARCv8Triples), end(SPARCv8Triples));
1703 BiarchLibDirs.append(begin(SPARCv9LibDirs), end(SPARCv9LibDirs));
1704 BiarchTripleAliases.append(begin(SPARCv9Triples), end(SPARCv9Triples));
Jakob Stoklund Olesenb3f938e2014-01-10 06:53:02 +00001705 break;
1706 case llvm::Triple::sparcv9:
Benjamin Kramer6ec434e2014-10-18 10:43:51 +00001707 LibDirs.append(begin(SPARCv9LibDirs), end(SPARCv9LibDirs));
1708 TripleAliases.append(begin(SPARCv9Triples), end(SPARCv9Triples));
1709 BiarchLibDirs.append(begin(SPARCv8LibDirs), end(SPARCv8LibDirs));
1710 BiarchTripleAliases.append(begin(SPARCv8Triples), end(SPARCv8Triples));
Jakob Stoklund Olesenb3f938e2014-01-10 06:53:02 +00001711 break;
Ulrich Weigand47445072013-05-06 16:26:41 +00001712 case llvm::Triple::systemz:
Benjamin Kramer6ec434e2014-10-18 10:43:51 +00001713 LibDirs.append(begin(SystemZLibDirs), end(SystemZLibDirs));
1714 TripleAliases.append(begin(SystemZTriples), end(SystemZTriples));
Ulrich Weigand47445072013-05-06 16:26:41 +00001715 break;
Chandler Carruth866faab2012-01-25 07:21:38 +00001716 default:
1717 // By default, just rely on the standard lib directories and the original
1718 // triple.
1719 break;
Chandler Carruth4c90fba2011-11-06 23:39:34 +00001720 }
Chandler Carruth866faab2012-01-25 07:21:38 +00001721
1722 // Always append the drivers target triple to the end, in case it doesn't
1723 // match any of our aliases.
1724 TripleAliases.push_back(TargetTriple.str());
1725
1726 // Also include the multiarch variant if it's different.
Chandler Carruthb427c562013-06-22 11:35:51 +00001727 if (TargetTriple.str() != BiarchTriple.str())
1728 BiarchTripleAliases.push_back(BiarchTriple.str());
Chandler Carruth4c90fba2011-11-06 23:39:34 +00001729}
1730
Justin Lebarc43ad9e2016-07-07 18:17:52 +00001731// Parses the contents of version.txt in an CUDA installation. It should
1732// contain one line of the from e.g. "CUDA Version 7.5.2".
1733static CudaVersion ParseCudaVersionFile(llvm::StringRef V) {
1734 if (!V.startswith("CUDA Version "))
1735 return CudaVersion::UNKNOWN;
1736 V = V.substr(strlen("CUDA Version "));
1737 int Major = -1, Minor = -1;
1738 auto First = V.split('.');
1739 auto Second = First.second.split('.');
1740 if (!First.first.getAsInteger(10, Major) ||
1741 !Second.first.getAsInteger(10, Minor))
1742 return CudaVersion::UNKNOWN;
1743
1744 if (Major == 7 && Minor == 0) {
1745 // This doesn't appear to ever happen -- version.txt doesn't exist in the
1746 // CUDA 7 installs I've seen. But no harm in checking.
1747 return CudaVersion::CUDA_70;
1748 }
1749 if (Major == 7 && Minor == 5)
1750 return CudaVersion::CUDA_75;
1751 if (Major == 8 && Minor == 0)
1752 return CudaVersion::CUDA_80;
1753 return CudaVersion::UNKNOWN;
1754}
1755
Artem Belevich98607b62015-09-23 21:49:39 +00001756// \brief -- try common CUDA installation paths looking for files we need for
1757// CUDA compilation.
Benjamin Kramerd45b2052015-10-07 15:48:01 +00001758void Generic_GCC::CudaInstallationDetector::init(
1759 const llvm::Triple &TargetTriple, const llvm::opt::ArgList &Args) {
NAKAMURA Takumi0c8decd2015-09-24 03:15:44 +00001760 SmallVector<std::string, 4> CudaPathCandidates;
Artem Belevich98607b62015-09-23 21:49:39 +00001761
1762 if (Args.hasArg(options::OPT_cuda_path_EQ))
1763 CudaPathCandidates.push_back(
1764 Args.getLastArgValue(options::OPT_cuda_path_EQ));
1765 else {
1766 CudaPathCandidates.push_back(D.SysRoot + "/usr/local/cuda");
Justin Lebaref1aaac2016-07-06 21:21:14 +00001767 // FIXME: Uncomment this once we can compile the cuda 8 headers.
1768 // CudaPathCandidates.push_back(D.SysRoot + "/usr/local/cuda-8.0");
Artem Belevich86017332015-11-17 22:28:55 +00001769 CudaPathCandidates.push_back(D.SysRoot + "/usr/local/cuda-7.5");
Artem Belevich98607b62015-09-23 21:49:39 +00001770 CudaPathCandidates.push_back(D.SysRoot + "/usr/local/cuda-7.0");
1771 }
1772
Benjamin Kramere8b76412015-09-24 14:48:37 +00001773 for (const auto &CudaPath : CudaPathCandidates) {
Benjamin Kramerd45b2052015-10-07 15:48:01 +00001774 if (CudaPath.empty() || !D.getVFS().exists(CudaPath))
Artem Belevich98607b62015-09-23 21:49:39 +00001775 continue;
1776
Justin Lebar710c1312016-07-06 21:21:43 +00001777 InstallPath = CudaPath;
1778 BinPath = CudaPath + "/bin";
1779 IncludePath = InstallPath + "/include";
1780 LibDevicePath = InstallPath + "/nvvm/libdevice";
1781 LibPath = InstallPath + (TargetTriple.isArch64Bit() ? "/lib64" : "/lib");
Artem Belevich98607b62015-09-23 21:49:39 +00001782
Justin Lebar710c1312016-07-06 21:21:43 +00001783 auto &FS = D.getVFS();
1784 if (!(FS.exists(IncludePath) && FS.exists(BinPath) && FS.exists(LibPath) &&
1785 FS.exists(LibDevicePath)))
Artem Belevich98607b62015-09-23 21:49:39 +00001786 continue;
1787
Artem Belevich34f481a2015-11-17 22:28:50 +00001788 std::error_code EC;
Justin Lebar710c1312016-07-06 21:21:43 +00001789 for (llvm::sys::fs::directory_iterator LI(LibDevicePath, EC), LE;
Artem Belevich34f481a2015-11-17 22:28:50 +00001790 !EC && LI != LE; LI = LI.increment(EC)) {
1791 StringRef FilePath = LI->path();
1792 StringRef FileName = llvm::sys::path::filename(FilePath);
1793 // Process all bitcode filenames that look like libdevice.compute_XX.YY.bc
1794 const StringRef LibDeviceName = "libdevice.";
1795 if (!(FileName.startswith(LibDeviceName) && FileName.endswith(".bc")))
1796 continue;
1797 StringRef GpuArch = FileName.slice(
1798 LibDeviceName.size(), FileName.find('.', LibDeviceName.size()));
Justin Lebar710c1312016-07-06 21:21:43 +00001799 LibDeviceMap[GpuArch] = FilePath.str();
Artem Belevich34f481a2015-11-17 22:28:50 +00001800 // Insert map entries for specifc devices with this compute capability.
1801 if (GpuArch == "compute_20") {
Justin Lebar710c1312016-07-06 21:21:43 +00001802 LibDeviceMap["sm_20"] = FilePath;
1803 LibDeviceMap["sm_21"] = FilePath;
Artem Belevich34f481a2015-11-17 22:28:50 +00001804 } else if (GpuArch == "compute_30") {
Justin Lebar710c1312016-07-06 21:21:43 +00001805 LibDeviceMap["sm_30"] = FilePath;
1806 LibDeviceMap["sm_32"] = FilePath;
Artem Belevich34f481a2015-11-17 22:28:50 +00001807 } else if (GpuArch == "compute_35") {
Justin Lebar710c1312016-07-06 21:21:43 +00001808 LibDeviceMap["sm_35"] = FilePath;
1809 LibDeviceMap["sm_37"] = FilePath;
Artem Belevichffa5fc52016-05-19 17:47:47 +00001810 } else if (GpuArch == "compute_50") {
Justin Lebar710c1312016-07-06 21:21:43 +00001811 LibDeviceMap["sm_50"] = FilePath;
1812 LibDeviceMap["sm_52"] = FilePath;
1813 LibDeviceMap["sm_53"] = FilePath;
1814 LibDeviceMap["sm_60"] = FilePath;
1815 LibDeviceMap["sm_61"] = FilePath;
1816 LibDeviceMap["sm_62"] = FilePath;
Artem Belevich34f481a2015-11-17 22:28:50 +00001817 }
1818 }
1819
Justin Lebarc43ad9e2016-07-07 18:17:52 +00001820 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> VersionFile =
1821 FS.getBufferForFile(InstallPath + "/version.txt");
1822 if (!VersionFile) {
1823 // CUDA 7.0 doesn't have a version.txt, so guess that's our version if
1824 // version.txt isn't present.
1825 Version = CudaVersion::CUDA_70;
1826 } else {
1827 Version = ParseCudaVersionFile((*VersionFile)->getBuffer());
1828 }
1829
Artem Belevich98607b62015-09-23 21:49:39 +00001830 IsValid = true;
1831 break;
1832 }
1833}
1834
Justin Lebarc43ad9e2016-07-07 18:17:52 +00001835void Generic_GCC::CudaInstallationDetector::CheckCudaVersionSupportsArch(
1836 CudaArch Arch) const {
1837 if (Arch == CudaArch::UNKNOWN || Version == CudaVersion::UNKNOWN ||
1838 ArchsWithVersionTooLowErrors.count(Arch) > 0)
1839 return;
1840
1841 auto RequiredVersion = MinVersionForCudaArch(Arch);
1842 if (Version < RequiredVersion) {
1843 ArchsWithVersionTooLowErrors.insert(Arch);
1844 D.Diag(diag::err_drv_cuda_version_too_low)
1845 << InstallPath << CudaArchToString(Arch) << CudaVersionToString(Version)
1846 << CudaVersionToString(RequiredVersion);
1847 }
1848}
1849
Artem Belevich98607b62015-09-23 21:49:39 +00001850void Generic_GCC::CudaInstallationDetector::print(raw_ostream &OS) const {
1851 if (isValid())
Justin Lebarc43ad9e2016-07-07 18:17:52 +00001852 OS << "Found CUDA installation: " << InstallPath << ", version "
1853 << CudaVersionToString(Version) << "\n";
Artem Belevich98607b62015-09-23 21:49:39 +00001854}
1855
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00001856namespace {
1857// Filter to remove Multilibs that don't exist as a suffix to Path
Benjamin Kramerac75baa2015-03-22 15:56:12 +00001858class FilterNonExistent {
Andrey Turetskiy4798eb62016-06-16 10:36:09 +00001859 StringRef Base, File;
Benjamin Kramerc5862f02015-10-09 13:03:18 +00001860 vfs::FileSystem &VFS;
Benjamin Kramerac75baa2015-03-22 15:56:12 +00001861
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00001862public:
Andrey Turetskiy4798eb62016-06-16 10:36:09 +00001863 FilterNonExistent(StringRef Base, StringRef File, vfs::FileSystem &VFS)
1864 : Base(Base), File(File), VFS(VFS) {}
Benjamin Kramerac75baa2015-03-22 15:56:12 +00001865 bool operator()(const Multilib &M) {
Andrey Turetskiy4798eb62016-06-16 10:36:09 +00001866 return !VFS.exists(Base + M.gccSuffix() + File);
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00001867 }
1868};
1869} // end anonymous namespace
1870
1871static void addMultilibFlag(bool Enabled, const char *const Flag,
1872 std::vector<std::string> &Flags) {
1873 if (Enabled)
1874 Flags.push_back(std::string("+") + Flag);
1875 else
1876 Flags.push_back(std::string("-") + Flag);
1877}
1878
Chih-Hung Hsiehb4d3bf72016-06-01 20:48:46 +00001879static bool isArmOrThumbArch(llvm::Triple::ArchType Arch) {
1880 return Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb;
1881}
1882
Simon Atanasyan08450bd2013-04-20 08:15:03 +00001883static bool isMipsArch(llvm::Triple::ArchType Arch) {
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00001884 return Arch == llvm::Triple::mips || Arch == llvm::Triple::mipsel ||
1885 Arch == llvm::Triple::mips64 || Arch == llvm::Triple::mips64el;
1886}
1887
1888static bool isMips32(llvm::Triple::ArchType Arch) {
1889 return Arch == llvm::Triple::mips || Arch == llvm::Triple::mipsel;
1890}
1891
1892static bool isMips64(llvm::Triple::ArchType Arch) {
1893 return Arch == llvm::Triple::mips64 || Arch == llvm::Triple::mips64el;
1894}
1895
1896static bool isMipsEL(llvm::Triple::ArchType Arch) {
1897 return Arch == llvm::Triple::mipsel || Arch == llvm::Triple::mips64el;
1898}
1899
Simon Atanasyan08450bd2013-04-20 08:15:03 +00001900static bool isMips16(const ArgList &Args) {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00001901 Arg *A = Args.getLastArg(options::OPT_mips16, options::OPT_mno_mips16);
Simon Atanasyan08450bd2013-04-20 08:15:03 +00001902 return A && A->getOption().matches(options::OPT_mips16);
1903}
1904
1905static bool isMicroMips(const ArgList &Args) {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00001906 Arg *A = Args.getLastArg(options::OPT_mmicromips, options::OPT_mno_micromips);
Simon Atanasyan08450bd2013-04-20 08:15:03 +00001907 return A && A->getOption().matches(options::OPT_mmicromips);
1908}
1909
Benjamin Kramere003ca22015-10-28 13:54:16 +00001910namespace {
Simon Atanasyan60280b42014-05-12 07:37:51 +00001911struct DetectedMultilibs {
1912 /// The set of multilibs that the detected installation supports.
1913 MultilibSet Multilibs;
1914
1915 /// The primary multilib appropriate for the given flags.
1916 Multilib SelectedMultilib;
1917
1918 /// On Biarch systems, this corresponds to the default multilib when
1919 /// targeting the non-default multilib. Otherwise, it is empty.
1920 llvm::Optional<Multilib> BiarchSibling;
1921};
Benjamin Kramere003ca22015-10-28 13:54:16 +00001922} // end anonymous namespace
Simon Atanasyan60280b42014-05-12 07:37:51 +00001923
Simon Atanasyan1b0542e2014-07-30 09:15:10 +00001924static Multilib makeMultilib(StringRef commonSuffix) {
1925 return Multilib(commonSuffix, commonSuffix, commonSuffix);
1926}
1927
Simon Atanasyanb4abcc52016-06-22 20:00:50 +00001928static bool findMipsCsMultilibs(const Multilib::flags_list &Flags,
1929 FilterNonExistent &NonExistent,
1930 DetectedMultilibs &Result) {
1931 // Check for Code Sourcery toolchain multilibs
1932 MultilibSet CSMipsMultilibs;
1933 {
1934 auto MArchMips16 = makeMultilib("/mips16").flag("+m32").flag("+mips16");
Simon Atanasyanee1accf2013-09-28 13:45:11 +00001935
Simon Atanasyanb4abcc52016-06-22 20:00:50 +00001936 auto MArchMicroMips =
1937 makeMultilib("/micromips").flag("+m32").flag("+mmicromips");
Jonathan Roelofs3fa96d82014-02-12 01:36:51 +00001938
Simon Atanasyanb4abcc52016-06-22 20:00:50 +00001939 auto MArchDefault = makeMultilib("").flag("-mips16").flag("-mmicromips");
1940
1941 auto UCLibc = makeMultilib("/uclibc").flag("+muclibc");
1942
1943 auto SoftFloat = makeMultilib("/soft-float").flag("+msoft-float");
1944
1945 auto Nan2008 = makeMultilib("/nan2008").flag("+mnan=2008");
1946
1947 auto DefaultFloat =
1948 makeMultilib("").flag("-msoft-float").flag("-mnan=2008");
1949
1950 auto BigEndian = makeMultilib("").flag("+EB").flag("-EL");
1951
1952 auto LittleEndian = makeMultilib("/el").flag("+EL").flag("-EB");
1953
1954 // Note that this one's osSuffix is ""
1955 auto MAbi64 = makeMultilib("")
1956 .gccSuffix("/64")
1957 .includeSuffix("/64")
1958 .flag("+mabi=n64")
1959 .flag("-mabi=n32")
1960 .flag("-m32");
1961
1962 CSMipsMultilibs =
1963 MultilibSet()
1964 .Either(MArchMips16, MArchMicroMips, MArchDefault)
1965 .Maybe(UCLibc)
1966 .Either(SoftFloat, Nan2008, DefaultFloat)
1967 .FilterOut("/micromips/nan2008")
1968 .FilterOut("/mips16/nan2008")
1969 .Either(BigEndian, LittleEndian)
1970 .Maybe(MAbi64)
1971 .FilterOut("/mips16.*/64")
1972 .FilterOut("/micromips.*/64")
1973 .FilterOut(NonExistent)
1974 .setIncludeDirsCallback([](const Multilib &M) {
1975 std::vector<std::string> Dirs({"/include"});
1976 if (StringRef(M.includeSuffix()).startswith("/uclibc"))
1977 Dirs.push_back(
1978 "/../../../../mips-linux-gnu/libc/uclibc/usr/include");
1979 else
1980 Dirs.push_back("/../../../../mips-linux-gnu/libc/usr/include");
1981 return Dirs;
1982 });
1983 }
1984
1985 MultilibSet DebianMipsMultilibs;
1986 {
1987 Multilib MAbiN32 =
1988 Multilib().gccSuffix("/n32").includeSuffix("/n32").flag("+mabi=n32");
1989
1990 Multilib M64 = Multilib()
1991 .gccSuffix("/64")
1992 .includeSuffix("/64")
1993 .flag("+m64")
1994 .flag("-m32")
1995 .flag("-mabi=n32");
1996
1997 Multilib M32 = Multilib().flag("-m64").flag("+m32").flag("-mabi=n32");
1998
1999 DebianMipsMultilibs =
2000 MultilibSet().Either(M32, M64, MAbiN32).FilterOut(NonExistent);
2001 }
2002
2003 // Sort candidates. Toolchain that best meets the directories tree goes first.
2004 // Then select the first toolchains matches command line flags.
2005 MultilibSet *Candidates[] = {&CSMipsMultilibs, &DebianMipsMultilibs};
2006 if (CSMipsMultilibs.size() < DebianMipsMultilibs.size())
2007 std::iter_swap(Candidates, Candidates + 1);
2008 for (const MultilibSet *Candidate : Candidates) {
2009 if (Candidate->select(Flags, Result.SelectedMultilib)) {
2010 if (Candidate == &DebianMipsMultilibs)
2011 Result.BiarchSibling = Multilib();
2012 Result.Multilibs = *Candidate;
2013 return true;
2014 }
2015 }
2016 return false;
2017}
2018
Simon Atanasyan603018a2016-07-19 07:09:48 +00002019static bool findMipsAndroidMultilibs(vfs::FileSystem &VFS, StringRef Path,
2020 const Multilib::flags_list &Flags,
Simon Atanasyanb4abcc52016-06-22 20:00:50 +00002021 FilterNonExistent &NonExistent,
2022 DetectedMultilibs &Result) {
2023
2024 MultilibSet AndroidMipsMultilibs =
2025 MultilibSet()
2026 .Maybe(Multilib("/mips-r2").flag("+march=mips32r2"))
2027 .Maybe(Multilib("/mips-r6").flag("+march=mips32r6"))
2028 .FilterOut(NonExistent);
2029
Simon Atanasyan603018a2016-07-19 07:09:48 +00002030 MultilibSet AndroidMipselMultilibs =
2031 MultilibSet()
2032 .Either(Multilib().flag("+march=mips32"),
2033 Multilib("/mips-r2", "", "/mips-r2").flag("+march=mips32r2"),
2034 Multilib("/mips-r6", "", "/mips-r6").flag("+march=mips32r6"))
2035 .FilterOut(NonExistent);
2036
2037 MultilibSet AndroidMips64elMultilibs =
2038 MultilibSet()
2039 .Either(
2040 Multilib().flag("+march=mips64r6"),
2041 Multilib("/32/mips-r1", "", "/mips-r1").flag("+march=mips32"),
2042 Multilib("/32/mips-r2", "", "/mips-r2").flag("+march=mips32r2"),
2043 Multilib("/32/mips-r6", "", "/mips-r6").flag("+march=mips32r6"))
2044 .FilterOut(NonExistent);
2045
2046 MultilibSet *MS = &AndroidMipsMultilibs;
2047 if (VFS.exists(Path + "/mips-r6"))
2048 MS = &AndroidMipselMultilibs;
2049 else if (VFS.exists(Path + "/32"))
2050 MS = &AndroidMips64elMultilibs;
2051 if (MS->select(Flags, Result.SelectedMultilib)) {
2052 Result.Multilibs = *MS;
Simon Atanasyanb4abcc52016-06-22 20:00:50 +00002053 return true;
2054 }
2055 return false;
2056}
2057
2058static bool findMipsMuslMultilibs(const Multilib::flags_list &Flags,
2059 FilterNonExistent &NonExistent,
2060 DetectedMultilibs &Result) {
2061 // Musl toolchain multilibs
2062 MultilibSet MuslMipsMultilibs;
2063 {
2064 auto MArchMipsR2 = makeMultilib("")
2065 .osSuffix("/mips-r2-hard-musl")
2066 .flag("+EB")
2067 .flag("-EL")
2068 .flag("+march=mips32r2");
2069
2070 auto MArchMipselR2 = makeMultilib("/mipsel-r2-hard-musl")
2071 .flag("-EB")
2072 .flag("+EL")
2073 .flag("+march=mips32r2");
2074
2075 MuslMipsMultilibs = MultilibSet().Either(MArchMipsR2, MArchMipselR2);
2076
2077 // Specify the callback that computes the include directories.
2078 MuslMipsMultilibs.setIncludeDirsCallback([](const Multilib &M) {
2079 return std::vector<std::string>(
2080 {"/../sysroot" + M.osSuffix() + "/usr/include"});
2081 });
2082 }
2083 if (MuslMipsMultilibs.select(Flags, Result.SelectedMultilib)) {
2084 Result.Multilibs = MuslMipsMultilibs;
2085 return true;
2086 }
2087 return false;
2088}
2089
2090static bool findMipsMtiMultilibs(const Multilib::flags_list &Flags,
2091 FilterNonExistent &NonExistent,
2092 DetectedMultilibs &Result) {
2093 // CodeScape MTI toolchain v1.2 and early.
Simon Atanasyancf7ac672016-05-22 15:27:58 +00002094 MultilibSet MtiMipsMultilibsV1;
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002095 {
Simon Atanasyan1b0542e2014-07-30 09:15:10 +00002096 auto MArchMips32 = makeMultilib("/mips32")
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002097 .flag("+m32")
2098 .flag("-m64")
2099 .flag("-mmicromips")
2100 .flag("+march=mips32");
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002101
Simon Atanasyan1b0542e2014-07-30 09:15:10 +00002102 auto MArchMicroMips = makeMultilib("/micromips")
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002103 .flag("+m32")
2104 .flag("-m64")
2105 .flag("+mmicromips");
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002106
Simon Atanasyan1b0542e2014-07-30 09:15:10 +00002107 auto MArchMips64r2 = makeMultilib("/mips64r2")
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002108 .flag("-m32")
2109 .flag("+m64")
2110 .flag("+march=mips64r2");
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002111
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002112 auto MArchMips64 = makeMultilib("/mips64").flag("-m32").flag("+m64").flag(
2113 "-march=mips64r2");
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002114
Simon Atanasyan1b0542e2014-07-30 09:15:10 +00002115 auto MArchDefault = makeMultilib("")
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002116 .flag("+m32")
2117 .flag("-m64")
2118 .flag("-mmicromips")
2119 .flag("+march=mips32r2");
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002120
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002121 auto Mips16 = makeMultilib("/mips16").flag("+mips16");
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002122
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002123 auto UCLibc = makeMultilib("/uclibc").flag("+muclibc");
Simon Atanasyand95c67d2014-08-13 14:34:14 +00002124
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002125 auto MAbi64 =
2126 makeMultilib("/64").flag("+mabi=n64").flag("-mabi=n32").flag("-m32");
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002127
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002128 auto BigEndian = makeMultilib("").flag("+EB").flag("-EL");
Simon Atanasyan738f85a2014-03-04 18:37:28 +00002129
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002130 auto LittleEndian = makeMultilib("/el").flag("+EL").flag("-EB");
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002131
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002132 auto SoftFloat = makeMultilib("/sof").flag("+msoft-float");
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002133
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002134 auto Nan2008 = makeMultilib("/nan2008").flag("+mnan=2008");
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002135
Simon Atanasyancf7ac672016-05-22 15:27:58 +00002136 MtiMipsMultilibsV1 =
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002137 MultilibSet()
2138 .Either(MArchMips32, MArchMicroMips, MArchMips64r2, MArchMips64,
2139 MArchDefault)
2140 .Maybe(UCLibc)
2141 .Maybe(Mips16)
2142 .FilterOut("/mips64/mips16")
2143 .FilterOut("/mips64r2/mips16")
2144 .FilterOut("/micromips/mips16")
2145 .Maybe(MAbi64)
2146 .FilterOut("/micromips/64")
2147 .FilterOut("/mips32/64")
2148 .FilterOut("^/64")
2149 .FilterOut("/mips16/64")
2150 .Either(BigEndian, LittleEndian)
2151 .Maybe(SoftFloat)
2152 .Maybe(Nan2008)
2153 .FilterOut(".*sof/nan2008")
2154 .FilterOut(NonExistent)
Simon Atanasyana45502d2016-05-19 15:07:21 +00002155 .setIncludeDirsCallback([](const Multilib &M) {
2156 std::vector<std::string> Dirs({"/include"});
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002157 if (StringRef(M.includeSuffix()).startswith("/uclibc"))
Simon Atanasyana45502d2016-05-19 15:07:21 +00002158 Dirs.push_back("/../../../../sysroot/uclibc/usr/include");
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002159 else
Simon Atanasyana45502d2016-05-19 15:07:21 +00002160 Dirs.push_back("/../../../../sysroot/usr/include");
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002161 return Dirs;
2162 });
Simon Atanasyan13e965a2013-11-26 11:57:14 +00002163 }
2164
Simon Atanasyanb4abcc52016-06-22 20:00:50 +00002165 // CodeScape IMG toolchain starting from v1.3.
Simon Atanasyan2834a222016-05-22 18:18:07 +00002166 MultilibSet MtiMipsMultilibsV2;
2167 {
2168 auto BeHard = makeMultilib("/mips-r2-hard")
2169 .flag("+EB")
2170 .flag("-msoft-float")
2171 .flag("-mnan=2008")
2172 .flag("-muclibc");
2173 auto BeSoft = makeMultilib("/mips-r2-soft")
2174 .flag("+EB")
2175 .flag("+msoft-float")
2176 .flag("-mnan=2008");
2177 auto ElHard = makeMultilib("/mipsel-r2-hard")
2178 .flag("+EL")
2179 .flag("-msoft-float")
2180 .flag("-mnan=2008")
2181 .flag("-muclibc");
2182 auto ElSoft = makeMultilib("/mipsel-r2-soft")
2183 .flag("+EL")
2184 .flag("+msoft-float")
2185 .flag("-mnan=2008")
2186 .flag("-mmicromips");
2187 auto BeHardNan = makeMultilib("/mips-r2-hard-nan2008")
2188 .flag("+EB")
2189 .flag("-msoft-float")
2190 .flag("+mnan=2008")
2191 .flag("-muclibc");
2192 auto ElHardNan = makeMultilib("/mipsel-r2-hard-nan2008")
2193 .flag("+EL")
2194 .flag("-msoft-float")
2195 .flag("+mnan=2008")
2196 .flag("-muclibc")
2197 .flag("-mmicromips");
2198 auto BeHardNanUclibc = makeMultilib("/mips-r2-hard-nan2008-uclibc")
2199 .flag("+EB")
2200 .flag("-msoft-float")
2201 .flag("+mnan=2008")
2202 .flag("+muclibc");
2203 auto ElHardNanUclibc = makeMultilib("/mipsel-r2-hard-nan2008-uclibc")
2204 .flag("+EL")
2205 .flag("-msoft-float")
2206 .flag("+mnan=2008")
2207 .flag("+muclibc");
2208 auto BeHardUclibc = makeMultilib("/mips-r2-hard-uclibc")
2209 .flag("+EB")
2210 .flag("-msoft-float")
2211 .flag("-mnan=2008")
2212 .flag("+muclibc");
2213 auto ElHardUclibc = makeMultilib("/mipsel-r2-hard-uclibc")
2214 .flag("+EL")
2215 .flag("-msoft-float")
2216 .flag("-mnan=2008")
2217 .flag("+muclibc");
2218 auto ElMicroHardNan = makeMultilib("/micromipsel-r2-hard-nan2008")
2219 .flag("+EL")
2220 .flag("-msoft-float")
2221 .flag("+mnan=2008")
2222 .flag("+mmicromips");
2223 auto ElMicroSoft = makeMultilib("/micromipsel-r2-soft")
2224 .flag("+EL")
2225 .flag("+msoft-float")
2226 .flag("-mnan=2008")
2227 .flag("+mmicromips");
2228
2229 auto O32 =
2230 makeMultilib("/lib").osSuffix("").flag("-mabi=n32").flag("-mabi=n64");
2231 auto N32 =
2232 makeMultilib("/lib32").osSuffix("").flag("+mabi=n32").flag("-mabi=n64");
2233 auto N64 =
2234 makeMultilib("/lib64").osSuffix("").flag("-mabi=n32").flag("+mabi=n64");
2235
2236 MtiMipsMultilibsV2 =
2237 MultilibSet()
2238 .Either({BeHard, BeSoft, ElHard, ElSoft, BeHardNan, ElHardNan,
2239 BeHardNanUclibc, ElHardNanUclibc, BeHardUclibc,
2240 ElHardUclibc, ElMicroHardNan, ElMicroSoft})
2241 .Either(O32, N32, N64)
2242 .FilterOut(NonExistent)
2243 .setIncludeDirsCallback([](const Multilib &M) {
2244 return std::vector<std::string>({"/../../../../sysroot" +
2245 M.includeSuffix() +
2246 "/../usr/include"});
2247 })
2248 .setFilePathsCallback([](const Multilib &M) {
2249 return std::vector<std::string>(
2250 {"/../../../../mips-mti-linux-gnu/lib" + M.gccSuffix()});
2251 });
2252 }
Simon Atanasyanb4abcc52016-06-22 20:00:50 +00002253 for (auto Candidate : {&MtiMipsMultilibsV1, &MtiMipsMultilibsV2}) {
2254 if (Candidate->select(Flags, Result.SelectedMultilib)) {
2255 Result.Multilibs = *Candidate;
2256 return true;
2257 }
Vasileios Kalintirisc744e122015-11-12 15:26:54 +00002258 }
Simon Atanasyanb4abcc52016-06-22 20:00:50 +00002259 return false;
2260}
Vasileios Kalintirisc744e122015-11-12 15:26:54 +00002261
Simon Atanasyanb4abcc52016-06-22 20:00:50 +00002262static bool findMipsImgMultilibs(const Multilib::flags_list &Flags,
2263 FilterNonExistent &NonExistent,
2264 DetectedMultilibs &Result) {
2265 // CodeScape IMG toolchain v1.2 and early.
Simon Atanasyancf7ac672016-05-22 15:27:58 +00002266 MultilibSet ImgMultilibsV1;
Daniel Sanders2bf13662014-07-10 14:40:57 +00002267 {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002268 auto Mips64r6 = makeMultilib("/mips64r6").flag("+m64").flag("-m32");
Daniel Sanders2bf13662014-07-10 14:40:57 +00002269
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002270 auto LittleEndian = makeMultilib("/el").flag("+EL").flag("-EB");
Daniel Sanders2bf13662014-07-10 14:40:57 +00002271
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002272 auto MAbi64 =
2273 makeMultilib("/64").flag("+mabi=n64").flag("-mabi=n32").flag("-m32");
Daniel Sanders2bf13662014-07-10 14:40:57 +00002274
Simon Atanasyancf7ac672016-05-22 15:27:58 +00002275 ImgMultilibsV1 =
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002276 MultilibSet()
2277 .Maybe(Mips64r6)
2278 .Maybe(MAbi64)
2279 .Maybe(LittleEndian)
2280 .FilterOut(NonExistent)
Simon Atanasyana45502d2016-05-19 15:07:21 +00002281 .setIncludeDirsCallback([](const Multilib &M) {
2282 return std::vector<std::string>(
2283 {"/include", "/../../../../sysroot/usr/include"});
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002284 });
Daniel Sanders2bf13662014-07-10 14:40:57 +00002285 }
2286
Simon Atanasyanb4abcc52016-06-22 20:00:50 +00002287 // CodeScape IMG toolchain starting from v1.3.
Simon Atanasyan2834a222016-05-22 18:18:07 +00002288 MultilibSet ImgMultilibsV2;
2289 {
2290 auto BeHard = makeMultilib("/mips-r6-hard")
2291 .flag("+EB")
2292 .flag("-msoft-float")
2293 .flag("-mmicromips");
2294 auto BeSoft = makeMultilib("/mips-r6-soft")
2295 .flag("+EB")
2296 .flag("+msoft-float")
2297 .flag("-mmicromips");
2298 auto ElHard = makeMultilib("/mipsel-r6-hard")
2299 .flag("+EL")
2300 .flag("-msoft-float")
2301 .flag("-mmicromips");
2302 auto ElSoft = makeMultilib("/mipsel-r6-soft")
2303 .flag("+EL")
2304 .flag("+msoft-float")
2305 .flag("-mmicromips");
2306 auto BeMicroHard = makeMultilib("/micromips-r6-hard")
Simon Atanasyan6c51f5a2016-05-22 18:18:41 +00002307 .flag("+EB")
2308 .flag("-msoft-float")
2309 .flag("+mmicromips");
Simon Atanasyan2834a222016-05-22 18:18:07 +00002310 auto BeMicroSoft = makeMultilib("/micromips-r6-soft")
Simon Atanasyan6c51f5a2016-05-22 18:18:41 +00002311 .flag("+EB")
2312 .flag("+msoft-float")
2313 .flag("+mmicromips");
Simon Atanasyan2834a222016-05-22 18:18:07 +00002314 auto ElMicroHard = makeMultilib("/micromipsel-r6-hard")
Simon Atanasyan6c51f5a2016-05-22 18:18:41 +00002315 .flag("+EL")
2316 .flag("-msoft-float")
2317 .flag("+mmicromips");
Simon Atanasyan2834a222016-05-22 18:18:07 +00002318 auto ElMicroSoft = makeMultilib("/micromipsel-r6-soft")
Simon Atanasyan6c51f5a2016-05-22 18:18:41 +00002319 .flag("+EL")
2320 .flag("+msoft-float")
2321 .flag("+mmicromips");
Simon Atanasyan2834a222016-05-22 18:18:07 +00002322
2323 auto O32 =
2324 makeMultilib("/lib").osSuffix("").flag("-mabi=n32").flag("-mabi=n64");
2325 auto N32 =
2326 makeMultilib("/lib32").osSuffix("").flag("+mabi=n32").flag("-mabi=n64");
2327 auto N64 =
2328 makeMultilib("/lib64").osSuffix("").flag("-mabi=n32").flag("+mabi=n64");
2329
Simon Atanasyan6c51f5a2016-05-22 18:18:41 +00002330 ImgMultilibsV2 =
2331 MultilibSet()
2332 .Either({BeHard, BeSoft, ElHard, ElSoft, BeMicroHard, BeMicroSoft,
2333 ElMicroHard, ElMicroSoft})
2334 .Either(O32, N32, N64)
2335 .FilterOut(NonExistent)
2336 .setIncludeDirsCallback([](const Multilib &M) {
2337 return std::vector<std::string>({"/../../../../sysroot" +
2338 M.includeSuffix() +
2339 "/../usr/include"});
2340 })
2341 .setFilePathsCallback([](const Multilib &M) {
2342 return std::vector<std::string>(
2343 {"/../../../../mips-img-linux-gnu/lib" + M.gccSuffix()});
2344 });
Simon Atanasyan2834a222016-05-22 18:18:07 +00002345 }
Simon Atanasyanb4abcc52016-06-22 20:00:50 +00002346 for (auto Candidate : {&ImgMultilibsV1, &ImgMultilibsV2}) {
2347 if (Candidate->select(Flags, Result.SelectedMultilib)) {
2348 Result.Multilibs = *Candidate;
2349 return true;
2350 }
2351 }
2352 return false;
2353}
2354
2355static bool findMIPSMultilibs(const Driver &D, const llvm::Triple &TargetTriple,
2356 StringRef Path, const ArgList &Args,
2357 DetectedMultilibs &Result) {
2358 FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());
Simon Atanasyan2834a222016-05-22 18:18:07 +00002359
Simon Atanasyan7018e1d2014-07-16 12:29:22 +00002360 StringRef CPUName;
2361 StringRef ABIName;
2362 tools::mips::getMipsCPUAndABI(Args, TargetTriple, CPUName, ABIName);
2363
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002364 llvm::Triple::ArchType TargetArch = TargetTriple.getArch();
2365
2366 Multilib::flags_list Flags;
2367 addMultilibFlag(isMips32(TargetArch), "m32", Flags);
2368 addMultilibFlag(isMips64(TargetArch), "m64", Flags);
2369 addMultilibFlag(isMips16(Args), "mips16", Flags);
Simon Atanasyan9988e3a2014-07-16 17:34:54 +00002370 addMultilibFlag(CPUName == "mips32", "march=mips32", Flags);
Simon Atanasyan59b25cb2015-02-26 04:45:57 +00002371 addMultilibFlag(CPUName == "mips32r2" || CPUName == "mips32r3" ||
Daniel Sandersff952582015-10-05 12:24:30 +00002372 CPUName == "mips32r5" || CPUName == "p5600",
Simon Atanasyan59b25cb2015-02-26 04:45:57 +00002373 "march=mips32r2", Flags);
Simon Atanasyan3f024032015-02-25 07:31:12 +00002374 addMultilibFlag(CPUName == "mips32r6", "march=mips32r6", Flags);
Simon Atanasyan9988e3a2014-07-16 17:34:54 +00002375 addMultilibFlag(CPUName == "mips64", "march=mips64", Flags);
Simon Atanasyan59b25cb2015-02-26 04:45:57 +00002376 addMultilibFlag(CPUName == "mips64r2" || CPUName == "mips64r3" ||
2377 CPUName == "mips64r5" || CPUName == "octeon",
Simon Atanasyan9988e3a2014-07-16 17:34:54 +00002378 "march=mips64r2", Flags);
Simon Atanasyan603018a2016-07-19 07:09:48 +00002379 addMultilibFlag(CPUName == "mips64r6", "march=mips64r6", Flags);
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002380 addMultilibFlag(isMicroMips(Args), "mmicromips", Flags);
Simon Atanasyand95c67d2014-08-13 14:34:14 +00002381 addMultilibFlag(tools::mips::isUCLibc(Args), "muclibc", Flags);
Simon Atanasyanab6db9f2014-07-16 12:24:48 +00002382 addMultilibFlag(tools::mips::isNaN2008(Args, TargetTriple), "mnan=2008",
2383 Flags);
Simon Atanasyan7018e1d2014-07-16 12:29:22 +00002384 addMultilibFlag(ABIName == "n32", "mabi=n32", Flags);
2385 addMultilibFlag(ABIName == "n64", "mabi=n64", Flags);
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002386 addMultilibFlag(isSoftFloatABI(Args), "msoft-float", Flags);
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002387 addMultilibFlag(!isSoftFloatABI(Args), "mhard-float", Flags);
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002388 addMultilibFlag(isMipsEL(TargetArch), "EL", Flags);
Simon Atanasyan7018e1d2014-07-16 12:29:22 +00002389 addMultilibFlag(!isMipsEL(TargetArch), "EB", Flags);
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002390
Simon Atanasyanb4abcc52016-06-22 20:00:50 +00002391 if (TargetTriple.isAndroid())
Simon Atanasyan603018a2016-07-19 07:09:48 +00002392 return findMipsAndroidMultilibs(D.getVFS(), Path, Flags, NonExistent,
2393 Result);
Simon Atanasyan738f85a2014-03-04 18:37:28 +00002394
Vasileios Kalintirisc744e122015-11-12 15:26:54 +00002395 if (TargetTriple.getVendor() == llvm::Triple::MipsTechnologies &&
2396 TargetTriple.getOS() == llvm::Triple::Linux &&
Simon Atanasyanb4abcc52016-06-22 20:00:50 +00002397 TargetTriple.getEnvironment() == llvm::Triple::UnknownEnvironment)
2398 return findMipsMuslMultilibs(Flags, NonExistent, Result);
Vasileios Kalintirisc744e122015-11-12 15:26:54 +00002399
Simon Atanasyan4f3fe5b2016-05-22 15:28:34 +00002400 if (TargetTriple.getVendor() == llvm::Triple::MipsTechnologies &&
2401 TargetTriple.getOS() == llvm::Triple::Linux &&
Simon Atanasyanb4abcc52016-06-22 20:00:50 +00002402 TargetTriple.getEnvironment() == llvm::Triple::GNU)
2403 return findMipsMtiMultilibs(Flags, NonExistent, Result);
Simon Atanasyan4f3fe5b2016-05-22 15:28:34 +00002404
Daniel Sanders2bf13662014-07-10 14:40:57 +00002405 if (TargetTriple.getVendor() == llvm::Triple::ImaginationTechnologies &&
2406 TargetTriple.getOS() == llvm::Triple::Linux &&
Simon Atanasyanb4abcc52016-06-22 20:00:50 +00002407 TargetTriple.getEnvironment() == llvm::Triple::GNU)
2408 return findMipsImgMultilibs(Flags, NonExistent, Result);
Daniel Sanders2bf13662014-07-10 14:40:57 +00002409
Simon Atanasyanb4abcc52016-06-22 20:00:50 +00002410 if (findMipsCsMultilibs(Flags, NonExistent, Result))
2411 return true;
Simon Atanasyan738f85a2014-03-04 18:37:28 +00002412
Simon Atanasyanb4abcc52016-06-22 20:00:50 +00002413 // Fallback to the regular toolchain-tree structure.
2414 Multilib Default;
2415 Result.Multilibs.push_back(Default);
2416 Result.Multilibs.FilterOut(NonExistent);
Simon Atanasyan3a46afa2014-06-24 19:00:12 +00002417
Simon Atanasyanb4abcc52016-06-22 20:00:50 +00002418 if (Result.Multilibs.select(Flags, Result.SelectedMultilib)) {
2419 Result.BiarchSibling = Multilib();
2420 return true;
Simon Atanasyan3a46afa2014-06-24 19:00:12 +00002421 }
2422
Simon Atanasyan738f85a2014-03-04 18:37:28 +00002423 return false;
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002424}
2425
Chih-Hung Hsiehb4d3bf72016-06-01 20:48:46 +00002426static void findAndroidArmMultilibs(const Driver &D,
2427 const llvm::Triple &TargetTriple,
2428 StringRef Path, const ArgList &Args,
2429 DetectedMultilibs &Result) {
2430 // Find multilibs with subdirectories like armv7-a, thumb, armv7-a/thumb.
Andrey Turetskiy4798eb62016-06-16 10:36:09 +00002431 FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());
Chih-Hung Hsiehb4d3bf72016-06-01 20:48:46 +00002432 Multilib ArmV7Multilib = makeMultilib("/armv7-a")
2433 .flag("+armv7")
2434 .flag("-thumb");
2435 Multilib ThumbMultilib = makeMultilib("/thumb")
2436 .flag("-armv7")
2437 .flag("+thumb");
2438 Multilib ArmV7ThumbMultilib = makeMultilib("/armv7-a/thumb")
2439 .flag("+armv7")
2440 .flag("+thumb");
2441 Multilib DefaultMultilib = makeMultilib("")
2442 .flag("-armv7")
2443 .flag("-thumb");
2444 MultilibSet AndroidArmMultilibs =
2445 MultilibSet()
2446 .Either(ThumbMultilib, ArmV7Multilib,
2447 ArmV7ThumbMultilib, DefaultMultilib)
2448 .FilterOut(NonExistent);
2449
2450 Multilib::flags_list Flags;
2451 llvm::StringRef Arch = Args.getLastArgValue(options::OPT_march_EQ);
2452 bool IsArmArch = TargetTriple.getArch() == llvm::Triple::arm;
2453 bool IsThumbArch = TargetTriple.getArch() == llvm::Triple::thumb;
2454 bool IsV7SubArch = TargetTriple.getSubArch() == llvm::Triple::ARMSubArch_v7;
2455 bool IsThumbMode = IsThumbArch ||
2456 Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, false) ||
2457 (IsArmArch && llvm::ARM::parseArchISA(Arch) == llvm::ARM::IK_THUMB);
2458 bool IsArmV7Mode = (IsArmArch || IsThumbArch) &&
2459 (llvm::ARM::parseArchVersion(Arch) == 7 ||
2460 (IsArmArch && Arch == "" && IsV7SubArch));
2461 addMultilibFlag(IsArmV7Mode, "armv7", Flags);
2462 addMultilibFlag(IsThumbMode, "thumb", Flags);
2463
2464 if (AndroidArmMultilibs.select(Flags, Result.SelectedMultilib))
2465 Result.Multilibs = AndroidArmMultilibs;
2466}
2467
Benjamin Kramerc5862f02015-10-09 13:03:18 +00002468static bool findBiarchMultilibs(const Driver &D,
2469 const llvm::Triple &TargetTriple,
Simon Atanasyan60280b42014-05-12 07:37:51 +00002470 StringRef Path, const ArgList &Args,
2471 bool NeedsBiarchSuffix,
2472 DetectedMultilibs &Result) {
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002473 // Some versions of SUSE and Fedora on ppc64 put 32-bit libs
2474 // in what would normally be GCCInstallPath and put the 64-bit
2475 // libs in a subdirectory named 64. The simple logic we follow is that
2476 // *if* there is a subdirectory of the right name with crtbegin.o in it,
2477 // we use that. If not, and if not a biarch triple alias, we look for
2478 // crtbegin.o without the subdirectory.
2479
2480 Multilib Default;
2481 Multilib Alt64 = Multilib()
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002482 .gccSuffix("/64")
2483 .includeSuffix("/64")
2484 .flag("-m32")
2485 .flag("+m64")
2486 .flag("-mx32");
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002487 Multilib Alt32 = Multilib()
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002488 .gccSuffix("/32")
2489 .includeSuffix("/32")
2490 .flag("+m32")
2491 .flag("-m64")
2492 .flag("-mx32");
Zinovy Nis1db95732014-07-10 15:27:19 +00002493 Multilib Altx32 = Multilib()
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002494 .gccSuffix("/x32")
2495 .includeSuffix("/x32")
2496 .flag("-m32")
2497 .flag("-m64")
2498 .flag("+mx32");
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002499
Andrey Turetskiy4798eb62016-06-16 10:36:09 +00002500 // GCC toolchain for IAMCU doesn't have crtbegin.o, so look for libgcc.a.
2501 FilterNonExistent NonExistent(
2502 Path, TargetTriple.isOSIAMCU() ? "/libgcc.a" : "/crtbegin.o", D.getVFS());
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002503
Zinovy Nis1db95732014-07-10 15:27:19 +00002504 // Determine default multilib from: 32, 64, x32
2505 // Also handle cases such as 64 on 32, 32 on 64, etc.
2506 enum { UNKNOWN, WANT32, WANT64, WANTX32 } Want = UNKNOWN;
David Blaikie40f842d2014-07-10 18:46:15 +00002507 const bool IsX32 = TargetTriple.getEnvironment() == llvm::Triple::GNUX32;
Alp Tokerf45fa3d2014-02-25 04:21:44 +00002508 if (TargetTriple.isArch32Bit() && !NonExistent(Alt32))
Zinovy Nis1db95732014-07-10 15:27:19 +00002509 Want = WANT64;
Zinovy Nis6e3c6302014-07-10 15:42:35 +00002510 else if (TargetTriple.isArch64Bit() && IsX32 && !NonExistent(Altx32))
Zinovy Nis1db95732014-07-10 15:27:19 +00002511 Want = WANT64;
Zinovy Nis6e3c6302014-07-10 15:42:35 +00002512 else if (TargetTriple.isArch64Bit() && !IsX32 && !NonExistent(Alt64))
Zinovy Nis1db95732014-07-10 15:27:19 +00002513 Want = WANT32;
Jonathan Roelofs3fa96d82014-02-12 01:36:51 +00002514 else {
Zinovy Nis1db95732014-07-10 15:27:19 +00002515 if (TargetTriple.isArch32Bit())
2516 Want = NeedsBiarchSuffix ? WANT64 : WANT32;
Zinovy Nis6e3c6302014-07-10 15:42:35 +00002517 else if (IsX32)
Zinovy Nis1db95732014-07-10 15:27:19 +00002518 Want = NeedsBiarchSuffix ? WANT64 : WANTX32;
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002519 else
Zinovy Nis1db95732014-07-10 15:27:19 +00002520 Want = NeedsBiarchSuffix ? WANT32 : WANT64;
Jonathan Roelofs0e7ec602014-02-12 01:29:25 +00002521 }
2522
Zinovy Nis1db95732014-07-10 15:27:19 +00002523 if (Want == WANT32)
2524 Default.flag("+m32").flag("-m64").flag("-mx32");
2525 else if (Want == WANT64)
2526 Default.flag("-m32").flag("+m64").flag("-mx32");
2527 else if (Want == WANTX32)
2528 Default.flag("-m32").flag("-m64").flag("+mx32");
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002529 else
Zinovy Nis1db95732014-07-10 15:27:19 +00002530 return false;
Jonathan Roelofs3fa96d82014-02-12 01:36:51 +00002531
Simon Atanasyan60280b42014-05-12 07:37:51 +00002532 Result.Multilibs.push_back(Default);
2533 Result.Multilibs.push_back(Alt64);
2534 Result.Multilibs.push_back(Alt32);
Zinovy Nis1db95732014-07-10 15:27:19 +00002535 Result.Multilibs.push_back(Altx32);
Jonathan Roelofs3fa96d82014-02-12 01:36:51 +00002536
Simon Atanasyan60280b42014-05-12 07:37:51 +00002537 Result.Multilibs.FilterOut(NonExistent);
Jonathan Roelofs3fa96d82014-02-12 01:36:51 +00002538
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002539 Multilib::flags_list Flags;
Zinovy Nis6e3c6302014-07-10 15:42:35 +00002540 addMultilibFlag(TargetTriple.isArch64Bit() && !IsX32, "m64", Flags);
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002541 addMultilibFlag(TargetTriple.isArch32Bit(), "m32", Flags);
Zinovy Nis6e3c6302014-07-10 15:42:35 +00002542 addMultilibFlag(TargetTriple.isArch64Bit() && IsX32, "mx32", Flags);
Jonathan Roelofs3fa96d82014-02-12 01:36:51 +00002543
Simon Atanasyan60280b42014-05-12 07:37:51 +00002544 if (!Result.Multilibs.select(Flags, Result.SelectedMultilib))
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002545 return false;
Jonathan Roelofs3fa96d82014-02-12 01:36:51 +00002546
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002547 if (Result.SelectedMultilib == Alt64 || Result.SelectedMultilib == Alt32 ||
Zinovy Nis1db95732014-07-10 15:27:19 +00002548 Result.SelectedMultilib == Altx32)
Simon Atanasyan60280b42014-05-12 07:37:51 +00002549 Result.BiarchSibling = Default;
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002550
2551 return true;
Simon Atanasyan08450bd2013-04-20 08:15:03 +00002552}
2553
Rafael Espindolac53c5b12015-08-31 19:17:51 +00002554void Generic_GCC::GCCInstallationDetector::scanLibDirForGCCTripleSolaris(
2555 const llvm::Triple &TargetArch, const llvm::opt::ArgList &Args,
2556 const std::string &LibDir, StringRef CandidateTriple,
2557 bool NeedsBiarchSuffix) {
2558 // Solaris is a special case. The GCC installation is under
2559 // /usr/gcc/<major>.<minor>/lib/gcc/<triple>/<major>.<minor>.<patch>/, so we
2560 // need to iterate twice.
2561 std::error_code EC;
Benjamin Kramerd45b2052015-10-07 15:48:01 +00002562 for (vfs::directory_iterator LI = D.getVFS().dir_begin(LibDir, EC), LE;
2563 !EC && LI != LE; LI = LI.increment(EC)) {
2564 StringRef VersionText = llvm::sys::path::filename(LI->getName());
Rafael Espindolac53c5b12015-08-31 19:17:51 +00002565 GCCVersion CandidateVersion = GCCVersion::Parse(VersionText);
2566
2567 if (CandidateVersion.Major != -1) // Filter obviously bad entries.
Benjamin Kramerd45b2052015-10-07 15:48:01 +00002568 if (!CandidateGCCInstallPaths.insert(LI->getName()).second)
Rafael Espindolac53c5b12015-08-31 19:17:51 +00002569 continue; // Saw this path before; no need to look at it again.
2570 if (CandidateVersion.isOlderThan(4, 1, 1))
2571 continue;
2572 if (CandidateVersion <= Version)
2573 continue;
2574
2575 GCCInstallPath =
2576 LibDir + "/" + VersionText.str() + "/lib/gcc/" + CandidateTriple.str();
Benjamin Kramerd45b2052015-10-07 15:48:01 +00002577 if (!D.getVFS().exists(GCCInstallPath))
Rafael Espindolac53c5b12015-08-31 19:17:51 +00002578 continue;
2579
2580 // If we make it here there has to be at least one GCC version, let's just
2581 // use the latest one.
2582 std::error_code EEC;
Benjamin Kramerd45b2052015-10-07 15:48:01 +00002583 for (vfs::directory_iterator
2584 LLI = D.getVFS().dir_begin(GCCInstallPath, EEC),
2585 LLE;
Rafael Espindolac53c5b12015-08-31 19:17:51 +00002586 !EEC && LLI != LLE; LLI = LLI.increment(EEC)) {
2587
Benjamin Kramerd45b2052015-10-07 15:48:01 +00002588 StringRef SubVersionText = llvm::sys::path::filename(LLI->getName());
Rafael Espindolac53c5b12015-08-31 19:17:51 +00002589 GCCVersion CandidateSubVersion = GCCVersion::Parse(SubVersionText);
2590
2591 if (CandidateSubVersion > Version)
2592 Version = CandidateSubVersion;
2593 }
2594
2595 GCCTriple.setTriple(CandidateTriple);
2596
2597 GCCInstallPath += "/" + Version.Text;
2598 GCCParentLibPath = GCCInstallPath + "/../../../../";
2599
2600 IsValid = true;
2601 }
2602}
2603
Chandler Carruth4c90fba2011-11-06 23:39:34 +00002604void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple(
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002605 const llvm::Triple &TargetTriple, const ArgList &Args,
Chandler Carruthb427c562013-06-22 11:35:51 +00002606 const std::string &LibDir, StringRef CandidateTriple,
2607 bool NeedsBiarchSuffix) {
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002608 llvm::Triple::ArchType TargetArch = TargetTriple.getArch();
Chandler Carruth4c90fba2011-11-06 23:39:34 +00002609 // There are various different suffixes involving the triple we
2610 // check for. We also record what is necessary to walk from each back
Douglas Katzmancb07d152015-08-14 15:52:12 +00002611 // up to the lib directory. Specifically, the number of "up" steps
2612 // in the second half of each row is 1 + the number of path separators
2613 // in the first half.
2614 const std::string LibAndInstallSuffixes[][2] = {
2615 {"/gcc/" + CandidateTriple.str(), "/../../.."},
2616
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002617 // Debian puts cross-compilers in gcc-cross
Douglas Katzmancb07d152015-08-14 15:52:12 +00002618 {"/gcc-cross/" + CandidateTriple.str(), "/../../.."},
2619
2620 {"/" + CandidateTriple.str() + "/gcc/" + CandidateTriple.str(),
2621 "/../../../.."},
Chandler Carruth4c90fba2011-11-06 23:39:34 +00002622
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002623 // The Freescale PPC SDK has the gcc libraries in
2624 // <sysroot>/usr/lib/<triple>/x.y.z so have a look there as well.
Douglas Katzmancb07d152015-08-14 15:52:12 +00002625 {"/" + CandidateTriple.str(), "/../.."},
Hal Finkelf3587912012-09-18 22:25:07 +00002626
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002627 // Ubuntu has a strange mis-matched pair of triples that this happens to
2628 // match.
2629 // FIXME: It may be worthwhile to generalize this and look for a second
2630 // triple.
Douglas Katzmancb07d152015-08-14 15:52:12 +00002631 {"/i386-linux-gnu/gcc/" + CandidateTriple.str(), "/../../../.."}};
2632
Rafael Espindolac53c5b12015-08-31 19:17:51 +00002633 if (TargetTriple.getOS() == llvm::Triple::Solaris) {
2634 scanLibDirForGCCTripleSolaris(TargetTriple, Args, LibDir, CandidateTriple,
2635 NeedsBiarchSuffix);
2636 return;
2637 }
2638
Chandler Carruth4c90fba2011-11-06 23:39:34 +00002639 // Only look at the final, weird Ubuntu suffix for i386-linux-gnu.
Douglas Katzmancb07d152015-08-14 15:52:12 +00002640 const unsigned NumLibSuffixes = (llvm::array_lengthof(LibAndInstallSuffixes) -
2641 (TargetArch != llvm::Triple::x86));
Chandler Carruth866faab2012-01-25 07:21:38 +00002642 for (unsigned i = 0; i < NumLibSuffixes; ++i) {
Douglas Katzmancb07d152015-08-14 15:52:12 +00002643 StringRef LibSuffix = LibAndInstallSuffixes[i][0];
Rafael Espindolac0809172014-06-12 14:02:15 +00002644 std::error_code EC;
Benjamin Kramerd45b2052015-10-07 15:48:01 +00002645 for (vfs::directory_iterator
2646 LI = D.getVFS().dir_begin(LibDir + LibSuffix, EC),
2647 LE;
Chandler Carruth4c90fba2011-11-06 23:39:34 +00002648 !EC && LI != LE; LI = LI.increment(EC)) {
Benjamin Kramerd45b2052015-10-07 15:48:01 +00002649 StringRef VersionText = llvm::sys::path::filename(LI->getName());
Chandler Carruth4c90fba2011-11-06 23:39:34 +00002650 GCCVersion CandidateVersion = GCCVersion::Parse(VersionText);
Benjamin Kramera97e4d12013-08-14 18:38:51 +00002651 if (CandidateVersion.Major != -1) // Filter obviously bad entries.
Benjamin Kramerd45b2052015-10-07 15:48:01 +00002652 if (!CandidateGCCInstallPaths.insert(LI->getName()).second)
Benjamin Kramera97e4d12013-08-14 18:38:51 +00002653 continue; // Saw this path before; no need to look at it again.
Benjamin Kramer604e8482013-08-09 17:17:48 +00002654 if (CandidateVersion.isOlderThan(4, 1, 1))
Chandler Carruth4c90fba2011-11-06 23:39:34 +00002655 continue;
2656 if (CandidateVersion <= Version)
2657 continue;
Hal Finkel221e11e2011-12-08 05:50:03 +00002658
Simon Atanasyan60280b42014-05-12 07:37:51 +00002659 DetectedMultilibs Detected;
Simon Atanasyanee1accf2013-09-28 13:45:11 +00002660
Chih-Hung Hsiehb4d3bf72016-06-01 20:48:46 +00002661 // Android standalone toolchain could have multilibs for ARM and Thumb.
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002662 // Debian mips multilibs behave more like the rest of the biarch ones,
2663 // so handle them there
Chih-Hung Hsiehb4d3bf72016-06-01 20:48:46 +00002664 if (isArmOrThumbArch(TargetArch) && TargetTriple.isAndroid()) {
2665 // It should also work without multilibs in a simplified toolchain.
2666 findAndroidArmMultilibs(D, TargetTriple, LI->getName(), Args, Detected);
2667 } else if (isMipsArch(TargetArch)) {
Benjamin Kramerc5862f02015-10-09 13:03:18 +00002668 if (!findMIPSMultilibs(D, TargetTriple, LI->getName(), Args, Detected))
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002669 continue;
Benjamin Kramerc5862f02015-10-09 13:03:18 +00002670 } else if (!findBiarchMultilibs(D, TargetTriple, LI->getName(), Args,
Simon Atanasyan60280b42014-05-12 07:37:51 +00002671 NeedsBiarchSuffix, Detected)) {
Simon Atanasyanee1accf2013-09-28 13:45:11 +00002672 continue;
Simon Atanasyan60280b42014-05-12 07:37:51 +00002673 }
Chandler Carruth4c90fba2011-11-06 23:39:34 +00002674
Simon Atanasyan60280b42014-05-12 07:37:51 +00002675 Multilibs = Detected.Multilibs;
2676 SelectedMultilib = Detected.SelectedMultilib;
2677 BiarchSibling = Detected.BiarchSibling;
Chandler Carruth4c90fba2011-11-06 23:39:34 +00002678 Version = CandidateVersion;
Chandler Carruth4d9d7682012-01-24 19:28:29 +00002679 GCCTriple.setTriple(CandidateTriple);
Chandler Carruth4c90fba2011-11-06 23:39:34 +00002680 // FIXME: We hack together the directory name here instead of
2681 // using LI to ensure stable path separators across Windows and
2682 // Linux.
Douglas Katzmancb07d152015-08-14 15:52:12 +00002683 GCCInstallPath =
2684 LibDir + LibAndInstallSuffixes[i][0] + "/" + VersionText.str();
2685 GCCParentLibPath = GCCInstallPath + LibAndInstallSuffixes[i][1];
Chandler Carruth4c90fba2011-11-06 23:39:34 +00002686 IsValid = true;
2687 }
2688 }
2689}
2690
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002691Generic_GCC::Generic_GCC(const Driver &D, const llvm::Triple &Triple,
Rafael Espindola1af7c212012-02-19 01:38:32 +00002692 const ArgList &Args)
Benjamin Kramerd45b2052015-10-07 15:48:01 +00002693 : ToolChain(D, Triple, Args), GCCInstallation(D), CudaInstallation(D) {
Daniel Dunbar88979912010-08-01 22:29:51 +00002694 getProgramPaths().push_back(getDriver().getInstalledDir());
Benjamin Kramer51477bd2011-03-01 22:50:47 +00002695 if (getDriver().getInstalledDir() != getDriver().Dir)
Daniel Dunbar88979912010-08-01 22:29:51 +00002696 getProgramPaths().push_back(getDriver().Dir);
Daniel Dunbar76ce7412009-03-23 16:15:50 +00002697}
2698
Angel Garcia Gomez637d1e62015-10-20 13:23:58 +00002699Generic_GCC::~Generic_GCC() {}
Daniel Dunbar59e5e882009-03-20 00:20:03 +00002700
Rafael Espindola7cf32212013-03-20 03:05:54 +00002701Tool *Generic_GCC::getTool(Action::ActionClass AC) const {
Rafael Espindola260e28d2013-03-18 20:48:54 +00002702 switch (AC) {
Rafael Espindolac8e3a012013-03-18 18:50:01 +00002703 case Action::PreprocessJobClass:
Rafael Espindola7cf32212013-03-20 03:05:54 +00002704 if (!Preprocess)
Douglas Katzman95354292015-06-23 20:42:09 +00002705 Preprocess.reset(new tools::gcc::Preprocessor(*this));
Rafael Espindola7cf32212013-03-20 03:05:54 +00002706 return Preprocess.get();
Rafael Espindolac8e3a012013-03-18 18:50:01 +00002707 case Action::CompileJobClass:
Rafael Espindola7cf32212013-03-20 03:05:54 +00002708 if (!Compile)
Douglas Katzman95354292015-06-23 20:42:09 +00002709 Compile.reset(new tools::gcc::Compiler(*this));
Rafael Espindola7cf32212013-03-20 03:05:54 +00002710 return Compile.get();
Rafael Espindolad15a8912013-03-19 00:36:57 +00002711 default:
Rafael Espindola7cf32212013-03-20 03:05:54 +00002712 return ToolChain::getTool(AC);
Daniel Dunbar59e5e882009-03-20 00:20:03 +00002713 }
Daniel Dunbar59e5e882009-03-20 00:20:03 +00002714}
2715
Rafael Espindola7cf32212013-03-20 03:05:54 +00002716Tool *Generic_GCC::buildAssembler() const {
Douglas Katzman95354292015-06-23 20:42:09 +00002717 return new tools::gnutools::Assembler(*this);
Rafael Espindola7cf32212013-03-20 03:05:54 +00002718}
2719
Douglas Katzman95354292015-06-23 20:42:09 +00002720Tool *Generic_GCC::buildLinker() const { return new tools::gcc::Linker(*this); }
Rafael Espindola7cf32212013-03-20 03:05:54 +00002721
Chandler Carruth0ae39aa2013-07-30 17:57:09 +00002722void Generic_GCC::printVerboseInfo(raw_ostream &OS) const {
2723 // Print the information about how we detected the GCC installation.
2724 GCCInstallation.print(OS);
Artem Belevich98607b62015-09-23 21:49:39 +00002725 CudaInstallation.print(OS);
Chandler Carruth0ae39aa2013-07-30 17:57:09 +00002726}
2727
Daniel Dunbar59e5e882009-03-20 00:20:03 +00002728bool Generic_GCC::IsUnwindTablesDefault() const {
Rafael Espindola08f1ebb2012-09-22 15:04:11 +00002729 return getArch() == llvm::Triple::x86_64;
Daniel Dunbar59e5e882009-03-20 00:20:03 +00002730}
2731
David Majnemer17f448b2015-06-28 04:23:33 +00002732bool Generic_GCC::isPICDefault() const {
2733 return getArch() == llvm::Triple::x86_64 && getTriple().isOSWindows();
2734}
Daniel Dunbar59e5e882009-03-20 00:20:03 +00002735
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002736bool Generic_GCC::isPIEDefault() const { return false; }
Peter Collingbourne54d770c2013-04-09 04:35:11 +00002737
David Majnemer17f448b2015-06-28 04:23:33 +00002738bool Generic_GCC::isPICDefaultForced() const {
2739 return getArch() == llvm::Triple::x86_64 && getTriple().isOSWindows();
2740}
Chandler Carruth76a943b2012-11-19 03:52:03 +00002741
Rafael Espindolaa8b3b682013-11-25 18:50:53 +00002742bool Generic_GCC::IsIntegratedAssemblerDefault() const {
Douglas Katzman7ae27b82015-06-03 19:40:30 +00002743 switch (getTriple().getArch()) {
2744 case llvm::Triple::x86:
2745 case llvm::Triple::x86_64:
2746 case llvm::Triple::aarch64:
2747 case llvm::Triple::aarch64_be:
2748 case llvm::Triple::arm:
2749 case llvm::Triple::armeb:
Alexei Starovoitovf657ca82015-06-10 22:59:13 +00002750 case llvm::Triple::bpfel:
2751 case llvm::Triple::bpfeb:
Douglas Katzman7ae27b82015-06-03 19:40:30 +00002752 case llvm::Triple::thumb:
2753 case llvm::Triple::thumbeb:
2754 case llvm::Triple::ppc:
2755 case llvm::Triple::ppc64:
2756 case llvm::Triple::ppc64le:
Douglas Katzman7ae27b82015-06-03 19:40:30 +00002757 case llvm::Triple::systemz:
Daniel Sanderse160f832016-05-14 12:43:08 +00002758 case llvm::Triple::mips:
2759 case llvm::Triple::mipsel:
Douglas Katzman7ae27b82015-06-03 19:40:30 +00002760 return true;
2761 default:
2762 return false;
2763 }
Rafael Espindolaa8b3b682013-11-25 18:50:53 +00002764}
2765
James Y Knighta6c9ee72015-10-16 18:46:26 +00002766/// \brief Helper to add the variant paths of a libstdc++ installation.
2767bool Generic_GCC::addLibStdCXXIncludePaths(
2768 Twine Base, Twine Suffix, StringRef GCCTriple, StringRef GCCMultiarchTriple,
2769 StringRef TargetMultiarchTriple, Twine IncludeSuffix,
2770 const ArgList &DriverArgs, ArgStringList &CC1Args) const {
2771 if (!getVFS().exists(Base + Suffix))
2772 return false;
2773
2774 addSystemInclude(DriverArgs, CC1Args, Base + Suffix);
2775
2776 // The vanilla GCC layout of libstdc++ headers uses a triple subdirectory. If
2777 // that path exists or we have neither a GCC nor target multiarch triple, use
2778 // this vanilla search path.
2779 if ((GCCMultiarchTriple.empty() && TargetMultiarchTriple.empty()) ||
2780 getVFS().exists(Base + Suffix + "/" + GCCTriple + IncludeSuffix)) {
2781 addSystemInclude(DriverArgs, CC1Args,
2782 Base + Suffix + "/" + GCCTriple + IncludeSuffix);
2783 } else {
2784 // Otherwise try to use multiarch naming schemes which have normalized the
2785 // triples and put the triple before the suffix.
2786 //
2787 // GCC surprisingly uses *both* the GCC triple with a multilib suffix and
2788 // the target triple, so we support that here.
2789 addSystemInclude(DriverArgs, CC1Args,
2790 Base + "/" + GCCMultiarchTriple + Suffix + IncludeSuffix);
2791 addSystemInclude(DriverArgs, CC1Args,
2792 Base + "/" + TargetMultiarchTriple + Suffix);
2793 }
2794
2795 addSystemInclude(DriverArgs, CC1Args, Base + Suffix + "/backward");
2796 return true;
2797}
2798
Kristof Beylsfb387292014-01-10 13:44:34 +00002799void Generic_ELF::addClangTargetOptions(const ArgList &DriverArgs,
2800 ArgStringList &CC1Args) const {
2801 const Generic_GCC::GCCVersion &V = GCCInstallation.getVersion();
Tim Northovera2ee4332014-03-29 15:09:45 +00002802 bool UseInitArrayDefault =
Kristof Beylsfb387292014-01-10 13:44:34 +00002803 getTriple().getArch() == llvm::Triple::aarch64 ||
Christian Pirker9b019ae2014-02-25 13:51:00 +00002804 getTriple().getArch() == llvm::Triple::aarch64_be ||
Tim Northovera2ee4332014-03-29 15:09:45 +00002805 (getTriple().getOS() == llvm::Triple::Linux &&
Evgeniy Stepanov14deb7b2015-10-08 21:21:44 +00002806 (!V.isOlderThan(4, 7, 0) || getTriple().isAndroid())) ||
Vasileios Kalintirisc744e122015-11-12 15:26:54 +00002807 getTriple().getOS() == llvm::Triple::NaCl ||
2808 (getTriple().getVendor() == llvm::Triple::MipsTechnologies &&
2809 !getTriple().hasEnvironment());
Kristof Beylsfb387292014-01-10 13:44:34 +00002810
2811 if (DriverArgs.hasFlag(options::OPT_fuse_init_array,
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002812 options::OPT_fno_use_init_array, UseInitArrayDefault))
Kristof Beylsfb387292014-01-10 13:44:34 +00002813 CC1Args.push_back("-fuse-init-array");
2814}
2815
Vasileios Kalintirisc744e122015-11-12 15:26:54 +00002816/// Mips Toolchain
2817MipsLLVMToolChain::MipsLLVMToolChain(const Driver &D,
2818 const llvm::Triple &Triple,
2819 const ArgList &Args)
2820 : Linux(D, Triple, Args) {
2821 // Select the correct multilib according to the given arguments.
2822 DetectedMultilibs Result;
2823 findMIPSMultilibs(D, Triple, "", Args, Result);
2824 Multilibs = Result.Multilibs;
2825 SelectedMultilib = Result.SelectedMultilib;
2826
2827 // Find out the library suffix based on the ABI.
2828 LibSuffix = tools::mips::getMipsABILibSuffix(Args, Triple);
2829 getFilePaths().clear();
2830 getFilePaths().push_back(computeSysRoot() + "/usr/lib" + LibSuffix);
2831
2832 // Use LLD by default.
Peter Collingbourne39719a72015-11-20 20:49:39 +00002833 DefaultLinker = "lld";
Vasileios Kalintirisc744e122015-11-12 15:26:54 +00002834}
2835
2836void MipsLLVMToolChain::AddClangSystemIncludeArgs(
2837 const ArgList &DriverArgs, ArgStringList &CC1Args) const {
2838 if (DriverArgs.hasArg(options::OPT_nostdinc))
2839 return;
2840
2841 const Driver &D = getDriver();
2842
2843 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
2844 SmallString<128> P(D.ResourceDir);
2845 llvm::sys::path::append(P, "include");
2846 addSystemInclude(DriverArgs, CC1Args, P);
2847 }
2848
2849 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
2850 return;
2851
2852 const auto &Callback = Multilibs.includeDirsCallback();
2853 if (Callback) {
Simon Atanasyana45502d2016-05-19 15:07:21 +00002854 for (const auto &Path : Callback(SelectedMultilib))
2855 addExternCSystemIncludeIfExists(DriverArgs, CC1Args,
2856 D.getInstalledDir() + Path);
Vasileios Kalintirisc744e122015-11-12 15:26:54 +00002857 }
2858}
2859
2860Tool *MipsLLVMToolChain::buildLinker() const {
2861 return new tools::gnutools::Linker(*this);
2862}
2863
2864std::string MipsLLVMToolChain::computeSysRoot() const {
2865 if (!getDriver().SysRoot.empty())
2866 return getDriver().SysRoot + SelectedMultilib.osSuffix();
2867
2868 const std::string InstalledDir(getDriver().getInstalledDir());
2869 std::string SysRootPath =
2870 InstalledDir + "/../sysroot" + SelectedMultilib.osSuffix();
2871 if (llvm::sys::fs::exists(SysRootPath))
2872 return SysRootPath;
2873
2874 return std::string();
2875}
2876
2877ToolChain::CXXStdlibType
2878MipsLLVMToolChain::GetCXXStdlibType(const ArgList &Args) const {
2879 Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
2880 if (A) {
2881 StringRef Value = A->getValue();
2882 if (Value != "libc++")
2883 getDriver().Diag(diag::err_drv_invalid_stdlib_name)
2884 << A->getAsString(Args);
2885 }
2886
2887 return ToolChain::CST_Libcxx;
2888}
2889
2890void MipsLLVMToolChain::AddClangCXXStdlibIncludeArgs(
2891 const ArgList &DriverArgs, ArgStringList &CC1Args) const {
2892 if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
2893 DriverArgs.hasArg(options::OPT_nostdincxx))
2894 return;
2895
2896 assert((GetCXXStdlibType(DriverArgs) == ToolChain::CST_Libcxx) &&
2897 "Only -lc++ (aka libcxx) is suported in this toolchain.");
2898
2899 const auto &Callback = Multilibs.includeDirsCallback();
2900 if (Callback) {
Simon Atanasyana45502d2016-05-19 15:07:21 +00002901 for (std::string Path : Callback(SelectedMultilib)) {
2902 Path = getDriver().getInstalledDir() + Path + "/c++/v1";
2903 if (llvm::sys::fs::exists(Path)) {
2904 addSystemInclude(DriverArgs, CC1Args, Path);
Vasileios Kalintirisc744e122015-11-12 15:26:54 +00002905 break;
2906 }
2907 }
2908 }
2909}
2910
2911void MipsLLVMToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
2912 ArgStringList &CmdArgs) const {
2913 assert((GetCXXStdlibType(Args) == ToolChain::CST_Libcxx) &&
2914 "Only -lc++ (aka libxx) is suported in this toolchain.");
2915
2916 CmdArgs.push_back("-lc++");
2917 CmdArgs.push_back("-lc++abi");
2918 CmdArgs.push_back("-lunwind");
2919}
2920
Vedant Kumarbf51e702016-07-18 19:56:38 +00002921std::string
2922MipsLLVMToolChain::getCompilerRT(const llvm::Triple &EffectiveTriple,
2923 const ArgList &Args, StringRef Component,
2924 bool Shared) const {
Vasileios Kalintirisc744e122015-11-12 15:26:54 +00002925 SmallString<128> Path(getDriver().ResourceDir);
2926 llvm::sys::path::append(Path, SelectedMultilib.osSuffix(), "lib" + LibSuffix,
2927 getOS());
2928 llvm::sys::path::append(Path, Twine("libclang_rt." + Component + "-" +
Vasileios Kalintirisbbc99302015-11-16 15:41:30 +00002929 "mips" + (Shared ? ".so" : ".a")));
Vasileios Kalintirisc744e122015-11-12 15:26:54 +00002930 return Path.str();
2931}
2932
Tony Linthicum76329bf2011-12-12 21:14:55 +00002933/// Hexagon Toolchain
2934
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00002935std::string HexagonToolChain::getHexagonTargetDir(
2936 const std::string &InstalledDir,
2937 const SmallVectorImpl<std::string> &PrefixDirs) const {
2938 std::string InstallRelDir;
2939 const Driver &D = getDriver();
2940
Matthew Curtis22dd8da2012-12-06 12:43:18 +00002941 // Locate the rest of the toolchain ...
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00002942 for (auto &I : PrefixDirs)
2943 if (D.getVFS().exists(I))
2944 return I;
Samuel Antaoc909c992014-11-07 17:48:03 +00002945
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00002946 if (getVFS().exists(InstallRelDir = InstalledDir + "/../target"))
Matthew Curtis22dd8da2012-12-06 12:43:18 +00002947 return InstallRelDir;
2948
Matthew Curtis22dd8da2012-12-06 12:43:18 +00002949 return InstallRelDir;
2950}
2951
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00002952Optional<unsigned> HexagonToolChain::getSmallDataThreshold(
2953 const ArgList &Args) {
2954 StringRef Gn = "";
2955 if (Arg *A = Args.getLastArg(options::OPT_G, options::OPT_G_EQ,
2956 options::OPT_msmall_data_threshold_EQ)) {
2957 Gn = A->getValue();
2958 } else if (Args.getLastArg(options::OPT_shared, options::OPT_fpic,
2959 options::OPT_fPIC)) {
2960 Gn = "0";
2961 }
Ikhlas Ajbar522e6192015-05-14 13:52:08 +00002962
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00002963 unsigned G;
2964 if (!Gn.getAsInteger(10, G))
2965 return G;
Ikhlas Ajbar522e6192015-05-14 13:52:08 +00002966
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00002967 return None;
Ikhlas Ajbar522e6192015-05-14 13:52:08 +00002968}
2969
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00002970void HexagonToolChain::getHexagonLibraryPaths(const ArgList &Args,
2971 ToolChain::path_list &LibPaths) const {
2972 const Driver &D = getDriver();
Matthew Curtise689b052012-12-06 15:46:07 +00002973
2974 //----------------------------------------------------------------------------
2975 // -L Args
2976 //----------------------------------------------------------------------------
Douglas Katzman6bbffc42015-06-25 18:51:37 +00002977 for (Arg *A : Args.filtered(options::OPT_L))
2978 for (const char *Value : A->getValues())
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00002979 LibPaths.push_back(Value);
Matthew Curtise689b052012-12-06 15:46:07 +00002980
2981 //----------------------------------------------------------------------------
2982 // Other standard paths
2983 //----------------------------------------------------------------------------
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00002984 std::vector<std::string> RootDirs;
Krzysztof Parzyszekf4467cd2016-01-06 14:13:11 +00002985 std::copy(D.PrefixDirs.begin(), D.PrefixDirs.end(),
2986 std::back_inserter(RootDirs));
Matthew Curtise689b052012-12-06 15:46:07 +00002987
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00002988 std::string TargetDir = getHexagonTargetDir(D.getInstalledDir(),
2989 D.PrefixDirs);
2990 if (std::find(RootDirs.begin(), RootDirs.end(), TargetDir) == RootDirs.end())
2991 RootDirs.push_back(TargetDir);
2992
2993 bool HasPIC = Args.hasArg(options::OPT_fpic, options::OPT_fPIC);
2994 // Assume G0 with -shared.
2995 bool HasG0 = Args.hasArg(options::OPT_shared);
2996 if (auto G = getSmallDataThreshold(Args))
2997 HasG0 = G.getValue() == 0;
2998
2999 const std::string CpuVer = GetTargetCPUVersion(Args).str();
3000 for (auto &Dir : RootDirs) {
3001 std::string LibDir = Dir + "/hexagon/lib";
3002 std::string LibDirCpu = LibDir + '/' + CpuVer;
3003 if (HasG0) {
3004 if (HasPIC)
3005 LibPaths.push_back(LibDirCpu + "/G0/pic");
3006 LibPaths.push_back(LibDirCpu + "/G0");
3007 }
3008 LibPaths.push_back(LibDirCpu);
3009 LibPaths.push_back(LibDir);
Matthew Curtise689b052012-12-06 15:46:07 +00003010 }
Matthew Curtise689b052012-12-06 15:46:07 +00003011}
3012
Douglas Katzman54366072015-07-27 16:53:08 +00003013HexagonToolChain::HexagonToolChain(const Driver &D, const llvm::Triple &Triple,
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00003014 const llvm::opt::ArgList &Args)
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003015 : Linux(D, Triple, Args) {
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00003016 const std::string TargetDir = getHexagonTargetDir(D.getInstalledDir(),
3017 D.PrefixDirs);
Matthew Curtis22dd8da2012-12-06 12:43:18 +00003018
3019 // Note: Generic_GCC::Generic_GCC adds InstalledDir and getDriver().Dir to
3020 // program paths
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00003021 const std::string BinDir(TargetDir + "/bin");
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003022 if (D.getVFS().exists(BinDir))
Matthew Curtis22dd8da2012-12-06 12:43:18 +00003023 getProgramPaths().push_back(BinDir);
3024
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00003025 ToolChain::path_list &LibPaths = getFilePaths();
Matthew Curtise689b052012-12-06 15:46:07 +00003026
3027 // Remove paths added by Linux toolchain. Currently Hexagon_TC really targets
3028 // 'elf' OS type, so the Linux paths are not appropriate. When we actually
3029 // support 'linux' we'll need to fix this up
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00003030 LibPaths.clear();
3031 getHexagonLibraryPaths(Args, LibPaths);
Tony Linthicum76329bf2011-12-12 21:14:55 +00003032}
3033
Angel Garcia Gomez637d1e62015-10-20 13:23:58 +00003034HexagonToolChain::~HexagonToolChain() {}
Tony Linthicum76329bf2011-12-12 21:14:55 +00003035
Douglas Katzman54366072015-07-27 16:53:08 +00003036Tool *HexagonToolChain::buildAssembler() const {
Douglas Katzman95354292015-06-23 20:42:09 +00003037 return new tools::hexagon::Assembler(*this);
Rafael Espindola7cf32212013-03-20 03:05:54 +00003038}
3039
Douglas Katzman54366072015-07-27 16:53:08 +00003040Tool *HexagonToolChain::buildLinker() const {
Douglas Katzman95354292015-06-23 20:42:09 +00003041 return new tools::hexagon::Linker(*this);
Tony Linthicum76329bf2011-12-12 21:14:55 +00003042}
3043
Douglas Katzman54366072015-07-27 16:53:08 +00003044void HexagonToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
3045 ArgStringList &CC1Args) const {
Matthew Curtis22dd8da2012-12-06 12:43:18 +00003046 if (DriverArgs.hasArg(options::OPT_nostdinc) ||
3047 DriverArgs.hasArg(options::OPT_nostdlibinc))
3048 return;
3049
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00003050 const Driver &D = getDriver();
3051 std::string TargetDir = getHexagonTargetDir(D.getInstalledDir(),
3052 D.PrefixDirs);
3053 addExternCSystemInclude(DriverArgs, CC1Args, TargetDir + "/hexagon/include");
Tony Linthicum76329bf2011-12-12 21:14:55 +00003054}
3055
Douglas Katzman54366072015-07-27 16:53:08 +00003056void HexagonToolChain::AddClangCXXStdlibIncludeArgs(
3057 const ArgList &DriverArgs, ArgStringList &CC1Args) const {
Matthew Curtis22dd8da2012-12-06 12:43:18 +00003058 if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
3059 DriverArgs.hasArg(options::OPT_nostdincxx))
3060 return;
3061
3062 const Driver &D = getDriver();
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00003063 std::string TargetDir = getHexagonTargetDir(D.InstalledDir, D.PrefixDirs);
3064 addSystemInclude(DriverArgs, CC1Args, TargetDir + "/hexagon/include/c++");
Chandler Carruth76a943b2012-11-19 03:52:03 +00003065}
Matthew Curtisf10a5952012-12-06 14:16:43 +00003066
Matthew Curtise689b052012-12-06 15:46:07 +00003067ToolChain::CXXStdlibType
Douglas Katzman54366072015-07-27 16:53:08 +00003068HexagonToolChain::GetCXXStdlibType(const ArgList &Args) const {
Matthew Curtise689b052012-12-06 15:46:07 +00003069 Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
3070 if (!A)
3071 return ToolChain::CST_Libstdcxx;
3072
3073 StringRef Value = A->getValue();
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00003074 if (Value != "libstdc++")
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003075 getDriver().Diag(diag::err_drv_invalid_stdlib_name) << A->getAsString(Args);
Matthew Curtise689b052012-12-06 15:46:07 +00003076
3077 return ToolChain::CST_Libstdcxx;
3078}
3079
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00003080//
3081// Returns the default CPU for Hexagon. This is the default compilation target
3082// if no Hexagon processor is selected at the command-line.
3083//
3084const StringRef HexagonToolChain::GetDefaultCPU() {
3085 return "hexagonv60";
Matthew Curtisf10a5952012-12-06 14:16:43 +00003086}
3087
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00003088const StringRef HexagonToolChain::GetTargetCPUVersion(const ArgList &Args) {
3089 Arg *CpuArg = nullptr;
Krzysztof Parzyszek972f72c2016-01-06 21:12:03 +00003090 if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ, options::OPT_march_EQ))
3091 CpuArg = A;
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00003092
3093 StringRef CPU = CpuArg ? CpuArg->getValue() : GetDefaultCPU();
3094 if (CPU.startswith("hexagon"))
3095 return CPU.substr(sizeof("hexagon") - 1);
3096 return CPU;
Matthew Curtisf10a5952012-12-06 14:16:43 +00003097}
Matthew Curtis22dd8da2012-12-06 12:43:18 +00003098// End Hexagon
Daniel Dunbardac54a82009-03-25 04:13:45 +00003099
Tom Stellard8fa33092015-07-18 01:49:05 +00003100/// AMDGPU Toolchain
3101AMDGPUToolChain::AMDGPUToolChain(const Driver &D, const llvm::Triple &Triple,
3102 const ArgList &Args)
3103 : Generic_ELF(D, Triple, Args) { }
3104
3105Tool *AMDGPUToolChain::buildLinker() const {
3106 return new tools::amdgpu::Linker(*this);
3107}
3108// End AMDGPU
3109
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003110/// NaCl Toolchain
Douglas Katzman54366072015-07-27 16:53:08 +00003111NaClToolChain::NaClToolChain(const Driver &D, const llvm::Triple &Triple,
3112 const ArgList &Args)
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003113 : Generic_ELF(D, Triple, Args) {
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003114
3115 // Remove paths added by Generic_GCC. NaCl Toolchain cannot use the
3116 // default paths, and must instead only use the paths provided
3117 // with this toolchain based on architecture.
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003118 path_list &file_paths = getFilePaths();
3119 path_list &prog_paths = getProgramPaths();
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003120
3121 file_paths.clear();
3122 prog_paths.clear();
3123
3124 // Path for library files (libc.a, ...)
3125 std::string FilePath(getDriver().Dir + "/../");
3126
3127 // Path for tools (clang, ld, etc..)
3128 std::string ProgPath(getDriver().Dir + "/../");
3129
3130 // Path for toolchain libraries (libgcc.a, ...)
3131 std::string ToolPath(getDriver().ResourceDir + "/lib/");
3132
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003133 switch (Triple.getArch()) {
Hans Wennborgdcfba332015-10-06 23:40:43 +00003134 case llvm::Triple::x86:
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003135 file_paths.push_back(FilePath + "x86_64-nacl/lib32");
Derek Schuff9afb0502015-08-26 17:14:08 +00003136 file_paths.push_back(FilePath + "i686-nacl/usr/lib");
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003137 prog_paths.push_back(ProgPath + "x86_64-nacl/bin");
3138 file_paths.push_back(ToolPath + "i686-nacl");
3139 break;
Hans Wennborgdcfba332015-10-06 23:40:43 +00003140 case llvm::Triple::x86_64:
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003141 file_paths.push_back(FilePath + "x86_64-nacl/lib");
3142 file_paths.push_back(FilePath + "x86_64-nacl/usr/lib");
3143 prog_paths.push_back(ProgPath + "x86_64-nacl/bin");
3144 file_paths.push_back(ToolPath + "x86_64-nacl");
3145 break;
Hans Wennborgdcfba332015-10-06 23:40:43 +00003146 case llvm::Triple::arm:
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003147 file_paths.push_back(FilePath + "arm-nacl/lib");
3148 file_paths.push_back(FilePath + "arm-nacl/usr/lib");
3149 prog_paths.push_back(ProgPath + "arm-nacl/bin");
3150 file_paths.push_back(ToolPath + "arm-nacl");
3151 break;
Hans Wennborgdcfba332015-10-06 23:40:43 +00003152 case llvm::Triple::mipsel:
Petar Jovanovic26a4a402015-07-08 13:07:31 +00003153 file_paths.push_back(FilePath + "mipsel-nacl/lib");
3154 file_paths.push_back(FilePath + "mipsel-nacl/usr/lib");
3155 prog_paths.push_back(ProgPath + "bin");
3156 file_paths.push_back(ToolPath + "mipsel-nacl");
3157 break;
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003158 default:
3159 break;
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003160 }
3161
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003162 NaClArmMacrosPath = GetFilePath("nacl-arm-macros.s");
3163}
3164
Douglas Katzman54366072015-07-27 16:53:08 +00003165void NaClToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
3166 ArgStringList &CC1Args) const {
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003167 const Driver &D = getDriver();
3168 if (DriverArgs.hasArg(options::OPT_nostdinc))
3169 return;
3170
3171 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
3172 SmallString<128> P(D.ResourceDir);
3173 llvm::sys::path::append(P, "include");
3174 addSystemInclude(DriverArgs, CC1Args, P.str());
3175 }
3176
3177 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
3178 return;
3179
3180 SmallString<128> P(D.Dir + "/../");
Douglas Katzman7e37afb2015-06-23 03:02:39 +00003181 switch (getTriple().getArch()) {
Derek Schuff9afb0502015-08-26 17:14:08 +00003182 case llvm::Triple::x86:
3183 // x86 is special because multilib style uses x86_64-nacl/include for libc
3184 // headers but the SDK wants i686-nacl/usr/include. The other architectures
3185 // have the same substring.
3186 llvm::sys::path::append(P, "i686-nacl/usr/include");
3187 addSystemInclude(DriverArgs, CC1Args, P.str());
3188 llvm::sys::path::remove_filename(P);
3189 llvm::sys::path::remove_filename(P);
3190 llvm::sys::path::remove_filename(P);
3191 llvm::sys::path::append(P, "x86_64-nacl/include");
3192 addSystemInclude(DriverArgs, CC1Args, P.str());
3193 return;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00003194 case llvm::Triple::arm:
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003195 llvm::sys::path::append(P, "arm-nacl/usr/include");
Douglas Katzman7e37afb2015-06-23 03:02:39 +00003196 break;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00003197 case llvm::Triple::x86_64:
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003198 llvm::sys::path::append(P, "x86_64-nacl/usr/include");
Douglas Katzman7e37afb2015-06-23 03:02:39 +00003199 break;
Petar Jovanovic26a4a402015-07-08 13:07:31 +00003200 case llvm::Triple::mipsel:
3201 llvm::sys::path::append(P, "mipsel-nacl/usr/include");
3202 break;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00003203 default:
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003204 return;
3205 }
3206
3207 addSystemInclude(DriverArgs, CC1Args, P.str());
3208 llvm::sys::path::remove_filename(P);
3209 llvm::sys::path::remove_filename(P);
3210 llvm::sys::path::append(P, "include");
3211 addSystemInclude(DriverArgs, CC1Args, P.str());
3212}
3213
Douglas Katzman54366072015-07-27 16:53:08 +00003214void NaClToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
3215 ArgStringList &CmdArgs) const {
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003216 // Check for -stdlib= flags. We only support libc++ but this consumes the arg
3217 // if the value is libc++, and emits an error for other values.
3218 GetCXXStdlibType(Args);
3219 CmdArgs.push_back("-lc++");
3220}
3221
Douglas Katzman54366072015-07-27 16:53:08 +00003222void NaClToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
3223 ArgStringList &CC1Args) const {
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003224 const Driver &D = getDriver();
3225 if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
3226 DriverArgs.hasArg(options::OPT_nostdincxx))
3227 return;
3228
3229 // Check for -stdlib= flags. We only support libc++ but this consumes the arg
3230 // if the value is libc++, and emits an error for other values.
3231 GetCXXStdlibType(DriverArgs);
3232
Douglas Katzman7e37afb2015-06-23 03:02:39 +00003233 SmallString<128> P(D.Dir + "/../");
3234 switch (getTriple().getArch()) {
3235 case llvm::Triple::arm:
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003236 llvm::sys::path::append(P, "arm-nacl/include/c++/v1");
3237 addSystemInclude(DriverArgs, CC1Args, P.str());
Douglas Katzman7e37afb2015-06-23 03:02:39 +00003238 break;
3239 case llvm::Triple::x86:
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003240 llvm::sys::path::append(P, "x86_64-nacl/include/c++/v1");
3241 addSystemInclude(DriverArgs, CC1Args, P.str());
Douglas Katzman7e37afb2015-06-23 03:02:39 +00003242 break;
3243 case llvm::Triple::x86_64:
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003244 llvm::sys::path::append(P, "x86_64-nacl/include/c++/v1");
3245 addSystemInclude(DriverArgs, CC1Args, P.str());
Douglas Katzman7e37afb2015-06-23 03:02:39 +00003246 break;
Petar Jovanovic26a4a402015-07-08 13:07:31 +00003247 case llvm::Triple::mipsel:
3248 llvm::sys::path::append(P, "mipsel-nacl/include/c++/v1");
3249 addSystemInclude(DriverArgs, CC1Args, P.str());
3250 break;
Douglas Katzman9ad0ec22015-06-23 04:20:44 +00003251 default:
3252 break;
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003253 }
3254}
3255
Douglas Katzman54366072015-07-27 16:53:08 +00003256ToolChain::CXXStdlibType
3257NaClToolChain::GetCXXStdlibType(const ArgList &Args) const {
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003258 if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) {
3259 StringRef Value = A->getValue();
3260 if (Value == "libc++")
3261 return ToolChain::CST_Libcxx;
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003262 getDriver().Diag(diag::err_drv_invalid_stdlib_name) << A->getAsString(Args);
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003263 }
3264
3265 return ToolChain::CST_Libcxx;
3266}
3267
Douglas Katzman54366072015-07-27 16:53:08 +00003268std::string
3269NaClToolChain::ComputeEffectiveClangTriple(const ArgList &Args,
3270 types::ID InputType) const {
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003271 llvm::Triple TheTriple(ComputeLLVMTriple(Args, InputType));
3272 if (TheTriple.getArch() == llvm::Triple::arm &&
3273 TheTriple.getEnvironment() == llvm::Triple::UnknownEnvironment)
3274 TheTriple.setEnvironment(llvm::Triple::GNUEABIHF);
3275 return TheTriple.getTriple();
3276}
3277
Douglas Katzman54366072015-07-27 16:53:08 +00003278Tool *NaClToolChain::buildLinker() const {
Douglas Katzman95354292015-06-23 20:42:09 +00003279 return new tools::nacltools::Linker(*this);
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003280}
3281
Douglas Katzman54366072015-07-27 16:53:08 +00003282Tool *NaClToolChain::buildAssembler() const {
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003283 if (getTriple().getArch() == llvm::Triple::arm)
Douglas Katzman95354292015-06-23 20:42:09 +00003284 return new tools::nacltools::AssemblerARM(*this);
3285 return new tools::gnutools::Assembler(*this);
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003286}
3287// End NaCl
3288
Chris Lattner09797542010-03-04 21:07:38 +00003289/// TCEToolChain - A tool chain using the llvm bitcode tools to perform
3290/// all subcommands. See http://tce.cs.tut.fi for our peculiar target.
3291/// Currently does not support anything else but compilation.
3292
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003293TCEToolChain::TCEToolChain(const Driver &D, const llvm::Triple &Triple,
Rafael Espindola84b588b2013-03-18 18:10:27 +00003294 const ArgList &Args)
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003295 : ToolChain(D, Triple, Args) {
Chris Lattner09797542010-03-04 21:07:38 +00003296 // Path mangling to find libexec
3297 std::string Path(getDriver().Dir);
3298
3299 Path += "/../libexec";
3300 getProgramPaths().push_back(Path);
3301}
3302
Angel Garcia Gomez637d1e62015-10-20 13:23:58 +00003303TCEToolChain::~TCEToolChain() {}
Chris Lattner09797542010-03-04 21:07:38 +00003304
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003305bool TCEToolChain::IsMathErrnoDefault() const { return true; }
Chris Lattner09797542010-03-04 21:07:38 +00003306
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003307bool TCEToolChain::isPICDefault() const { return false; }
Chris Lattner09797542010-03-04 21:07:38 +00003308
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003309bool TCEToolChain::isPIEDefault() const { return false; }
Peter Collingbourne54d770c2013-04-09 04:35:11 +00003310
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003311bool TCEToolChain::isPICDefaultForced() const { return false; }
Chris Lattner09797542010-03-04 21:07:38 +00003312
Ed Schouten3c3e58c2015-03-26 11:13:44 +00003313// CloudABI - CloudABI tool chain which can call ld(1) directly.
3314
3315CloudABI::CloudABI(const Driver &D, const llvm::Triple &Triple,
3316 const ArgList &Args)
3317 : Generic_ELF(D, Triple, Args) {
3318 SmallString<128> P(getDriver().Dir);
3319 llvm::sys::path::append(P, "..", getTriple().str(), "lib");
3320 getFilePaths().push_back(P.str());
3321}
3322
3323void CloudABI::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
3324 ArgStringList &CC1Args) const {
3325 if (DriverArgs.hasArg(options::OPT_nostdlibinc) &&
3326 DriverArgs.hasArg(options::OPT_nostdincxx))
3327 return;
3328
3329 SmallString<128> P(getDriver().Dir);
3330 llvm::sys::path::append(P, "..", getTriple().str(), "include/c++/v1");
3331 addSystemInclude(DriverArgs, CC1Args, P.str());
3332}
3333
3334void CloudABI::AddCXXStdlibLibArgs(const ArgList &Args,
3335 ArgStringList &CmdArgs) const {
3336 CmdArgs.push_back("-lc++");
3337 CmdArgs.push_back("-lc++abi");
3338 CmdArgs.push_back("-lunwind");
3339}
3340
Douglas Katzman95354292015-06-23 20:42:09 +00003341Tool *CloudABI::buildLinker() const {
3342 return new tools::cloudabi::Linker(*this);
3343}
Ed Schouten3c3e58c2015-03-26 11:13:44 +00003344
Ed Schouten51bfbe72016-02-17 18:56:20 +00003345SanitizerMask CloudABI::getSupportedSanitizers() const {
3346 SanitizerMask Res = ToolChain::getSupportedSanitizers();
3347 Res |= SanitizerKind::SafeStack;
3348 return Res;
3349}
3350
Ed Schoutenfc79d2c2016-03-29 21:13:53 +00003351SanitizerMask CloudABI::getDefaultSanitizers() const {
3352 return SanitizerKind::SafeStack;
3353}
3354
Reid Kleckner330fb172016-05-11 16:19:05 +00003355/// Haiku - Haiku tool chain which can call as(1) and ld(1) directly.
3356
3357Haiku::Haiku(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
3358 : Generic_ELF(D, Triple, Args) {
3359
3360}
3361
3362void Haiku::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
3363 ArgStringList &CC1Args) const {
3364 if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
3365 DriverArgs.hasArg(options::OPT_nostdincxx))
3366 return;
3367
3368 switch (GetCXXStdlibType(DriverArgs)) {
3369 case ToolChain::CST_Libcxx:
3370 addSystemInclude(DriverArgs, CC1Args,
3371 getDriver().SysRoot + "/system/develop/headers/c++/v1");
3372 break;
3373 case ToolChain::CST_Libstdcxx:
3374 addSystemInclude(DriverArgs, CC1Args,
3375 getDriver().SysRoot + "/system/develop/headers/c++");
3376 addSystemInclude(DriverArgs, CC1Args,
3377 getDriver().SysRoot + "/system/develop/headers/c++/backward");
3378
3379 StringRef Triple = getTriple().str();
3380 addSystemInclude(DriverArgs, CC1Args,
3381 getDriver().SysRoot + "/system/develop/headers/c++/" +
3382 Triple);
3383 break;
3384 }
3385}
3386
Daniel Dunbar10de9e62009-06-29 20:52:51 +00003387/// OpenBSD - OpenBSD tool chain which can call as(1) and ld(1) directly.
3388
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003389OpenBSD::OpenBSD(const Driver &D, const llvm::Triple &Triple,
3390 const ArgList &Args)
3391 : Generic_ELF(D, Triple, Args) {
Daniel Dunbar083edf72009-12-21 18:54:17 +00003392 getFilePaths().push_back(getDriver().Dir + "/../lib");
Daniel Dunbar10de9e62009-06-29 20:52:51 +00003393 getFilePaths().push_back("/usr/lib");
3394}
3395
Rafael Espindola7cf32212013-03-20 03:05:54 +00003396Tool *OpenBSD::buildAssembler() const {
Douglas Katzman95354292015-06-23 20:42:09 +00003397 return new tools::openbsd::Assembler(*this);
Rafael Espindola7cf32212013-03-20 03:05:54 +00003398}
3399
Douglas Katzman95354292015-06-23 20:42:09 +00003400Tool *OpenBSD::buildLinker() const { return new tools::openbsd::Linker(*this); }
Daniel Dunbar10de9e62009-06-29 20:52:51 +00003401
Eli Friedman9fa28852012-08-08 23:57:20 +00003402/// Bitrig - Bitrig tool chain which can call as(1) and ld(1) directly.
3403
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003404Bitrig::Bitrig(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
3405 : Generic_ELF(D, Triple, Args) {
Eli Friedman9fa28852012-08-08 23:57:20 +00003406 getFilePaths().push_back(getDriver().Dir + "/../lib");
3407 getFilePaths().push_back("/usr/lib");
3408}
3409
Rafael Espindola7cf32212013-03-20 03:05:54 +00003410Tool *Bitrig::buildAssembler() const {
Douglas Katzman95354292015-06-23 20:42:09 +00003411 return new tools::bitrig::Assembler(*this);
Rafael Espindola7cf32212013-03-20 03:05:54 +00003412}
3413
Douglas Katzman95354292015-06-23 20:42:09 +00003414Tool *Bitrig::buildLinker() const { return new tools::bitrig::Linker(*this); }
Eli Friedman9fa28852012-08-08 23:57:20 +00003415
Jonas Hahnfeldaae83742016-02-12 07:48:37 +00003416ToolChain::CXXStdlibType Bitrig::GetDefaultCXXStdlibType() const {
Richard Smith51af5192014-05-01 23:24:24 +00003417 return ToolChain::CST_Libcxx;
3418}
3419
Eli Friedman9fa28852012-08-08 23:57:20 +00003420void Bitrig::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
3421 ArgStringList &CC1Args) const {
3422 if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
3423 DriverArgs.hasArg(options::OPT_nostdincxx))
3424 return;
3425
Chandler Carruthc0f5cd12012-10-08 21:31:38 +00003426 switch (GetCXXStdlibType(DriverArgs)) {
3427 case ToolChain::CST_Libcxx:
3428 addSystemInclude(DriverArgs, CC1Args,
Richard Smith51af5192014-05-01 23:24:24 +00003429 getDriver().SysRoot + "/usr/include/c++/v1");
Chandler Carruthc0f5cd12012-10-08 21:31:38 +00003430 break;
3431 case ToolChain::CST_Libstdcxx:
3432 addSystemInclude(DriverArgs, CC1Args,
3433 getDriver().SysRoot + "/usr/include/c++/stdc++");
3434 addSystemInclude(DriverArgs, CC1Args,
3435 getDriver().SysRoot + "/usr/include/c++/stdc++/backward");
Eli Friedman9fa28852012-08-08 23:57:20 +00003436
Chandler Carruthc0f5cd12012-10-08 21:31:38 +00003437 StringRef Triple = getTriple().str();
3438 if (Triple.startswith("amd64"))
3439 addSystemInclude(DriverArgs, CC1Args,
3440 getDriver().SysRoot + "/usr/include/c++/stdc++/x86_64" +
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003441 Triple.substr(5));
Chandler Carruthc0f5cd12012-10-08 21:31:38 +00003442 else
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003443 addSystemInclude(DriverArgs, CC1Args, getDriver().SysRoot +
3444 "/usr/include/c++/stdc++/" +
3445 Triple);
Chandler Carruthc0f5cd12012-10-08 21:31:38 +00003446 break;
3447 }
Eli Friedman9fa28852012-08-08 23:57:20 +00003448}
3449
3450void Bitrig::AddCXXStdlibLibArgs(const ArgList &Args,
3451 ArgStringList &CmdArgs) const {
Chandler Carruthc0f5cd12012-10-08 21:31:38 +00003452 switch (GetCXXStdlibType(Args)) {
3453 case ToolChain::CST_Libcxx:
3454 CmdArgs.push_back("-lc++");
Richard Smith51af5192014-05-01 23:24:24 +00003455 CmdArgs.push_back("-lc++abi");
3456 CmdArgs.push_back("-lpthread");
Chandler Carruthc0f5cd12012-10-08 21:31:38 +00003457 break;
3458 case ToolChain::CST_Libstdcxx:
3459 CmdArgs.push_back("-lstdc++");
3460 break;
3461 }
Eli Friedman9fa28852012-08-08 23:57:20 +00003462}
3463
Daniel Dunbare24297c2009-03-30 21:06:03 +00003464/// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly.
3465
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003466FreeBSD::FreeBSD(const Driver &D, const llvm::Triple &Triple,
3467 const ArgList &Args)
3468 : Generic_ELF(D, Triple, Args) {
Daniel Dunbara18a4872010-08-02 05:43:59 +00003469
Chandler Carruth0b1756b2012-01-26 01:35:15 +00003470 // When targeting 32-bit platforms, look for '/usr/lib32/crt1.o' and fall
3471 // back to '/usr/lib' if it doesn't exist.
Chandler Carruthf7bf3db2012-01-25 11:24:24 +00003472 if ((Triple.getArch() == llvm::Triple::x86 ||
3473 Triple.getArch() == llvm::Triple::ppc) &&
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003474 D.getVFS().exists(getDriver().SysRoot + "/usr/lib32/crt1.o"))
Chandler Carruthf7bf3db2012-01-25 11:24:24 +00003475 getFilePaths().push_back(getDriver().SysRoot + "/usr/lib32");
3476 else
3477 getFilePaths().push_back(getDriver().SysRoot + "/usr/lib");
Daniel Dunbare24297c2009-03-30 21:06:03 +00003478}
3479
Jonas Hahnfeld09954192016-03-14 14:34:04 +00003480ToolChain::CXXStdlibType FreeBSD::GetDefaultCXXStdlibType() const {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003481 if (getTriple().getOSMajorVersion() >= 10)
David Chisnall867ccd82013-11-09 15:10:56 +00003482 return ToolChain::CST_Libcxx;
3483 return ToolChain::CST_Libstdcxx;
3484}
3485
3486void FreeBSD::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
3487 ArgStringList &CC1Args) const {
3488 if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
3489 DriverArgs.hasArg(options::OPT_nostdincxx))
3490 return;
3491
3492 switch (GetCXXStdlibType(DriverArgs)) {
3493 case ToolChain::CST_Libcxx:
3494 addSystemInclude(DriverArgs, CC1Args,
3495 getDriver().SysRoot + "/usr/include/c++/v1");
3496 break;
3497 case ToolChain::CST_Libstdcxx:
3498 addSystemInclude(DriverArgs, CC1Args,
3499 getDriver().SysRoot + "/usr/include/c++/4.2");
3500 addSystemInclude(DriverArgs, CC1Args,
3501 getDriver().SysRoot + "/usr/include/c++/4.2/backward");
3502 break;
3503 }
3504}
3505
Dimitry Andric60907392016-02-14 16:08:20 +00003506void FreeBSD::AddCXXStdlibLibArgs(const ArgList &Args,
3507 ArgStringList &CmdArgs) const {
3508 CXXStdlibType Type = GetCXXStdlibType(Args);
3509 bool Profiling = Args.hasArg(options::OPT_pg);
3510
3511 switch (Type) {
3512 case ToolChain::CST_Libcxx:
3513 CmdArgs.push_back(Profiling ? "-lc++_p" : "-lc++");
3514 break;
3515
3516 case ToolChain::CST_Libstdcxx:
3517 CmdArgs.push_back(Profiling ? "-lstdc++_p" : "-lstdc++");
3518 break;
3519 }
3520}
3521
Rafael Espindola7cf32212013-03-20 03:05:54 +00003522Tool *FreeBSD::buildAssembler() const {
Douglas Katzman95354292015-06-23 20:42:09 +00003523 return new tools::freebsd::Assembler(*this);
Rafael Espindola7cf32212013-03-20 03:05:54 +00003524}
3525
Douglas Katzman95354292015-06-23 20:42:09 +00003526Tool *FreeBSD::buildLinker() const { return new tools::freebsd::Linker(*this); }
Daniel Dunbarcc912342009-05-02 18:28:39 +00003527
Tim Northovere931f9f2015-10-30 16:30:41 +00003528bool FreeBSD::UseSjLjExceptions(const ArgList &Args) const {
Rafael Espindola0f207ed2012-12-13 04:17:14 +00003529 // FreeBSD uses SjLj exceptions on ARM oabi.
3530 switch (getTriple().getEnvironment()) {
Renato Golinf4421f72014-02-19 10:44:07 +00003531 case llvm::Triple::GNUEABIHF:
Rafael Espindola0f207ed2012-12-13 04:17:14 +00003532 case llvm::Triple::GNUEABI:
3533 case llvm::Triple::EABI:
3534 return false;
3535
3536 default:
3537 return (getTriple().getArch() == llvm::Triple::arm ||
3538 getTriple().getArch() == llvm::Triple::thumb);
3539 }
3540}
3541
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003542bool FreeBSD::HasNativeLLVMSupport() const { return true; }
Alexey Samsonove65ceb92014-02-25 13:26:03 +00003543
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003544bool FreeBSD::isPIEDefault() const { return getSanitizerArgs().requiresPIE(); }
Alexey Samsonove65ceb92014-02-25 13:26:03 +00003545
Alexey Samsonov7f2a0d22015-06-19 21:36:47 +00003546SanitizerMask FreeBSD::getSupportedSanitizers() const {
3547 const bool IsX86 = getTriple().getArch() == llvm::Triple::x86;
3548 const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64;
3549 const bool IsMIPS64 = getTriple().getArch() == llvm::Triple::mips64 ||
3550 getTriple().getArch() == llvm::Triple::mips64el;
3551 SanitizerMask Res = ToolChain::getSupportedSanitizers();
3552 Res |= SanitizerKind::Address;
3553 Res |= SanitizerKind::Vptr;
3554 if (IsX86_64 || IsMIPS64) {
3555 Res |= SanitizerKind::Leak;
3556 Res |= SanitizerKind::Thread;
3557 }
3558 if (IsX86 || IsX86_64) {
3559 Res |= SanitizerKind::SafeStack;
3560 }
3561 return Res;
3562}
3563
Benjamin Kramer24f1d3e2011-02-02 18:59:27 +00003564/// NetBSD - NetBSD tool chain which can call as(1) and ld(1) directly.
3565
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003566NetBSD::NetBSD(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
3567 : Generic_ELF(D, Triple, Args) {
Joerg Sonnenbergerbc923f32011-03-21 13:59:26 +00003568 if (getDriver().UseStdLib) {
Chandler Carruth1ccbed82012-01-25 11:18:20 +00003569 // When targeting a 32-bit platform, try the special directory used on
3570 // 64-bit hosts, and only fall back to the main library directory if that
3571 // doesn't work.
3572 // FIXME: It'd be nicer to test if this directory exists, but I'm not sure
3573 // what all logic is needed to emulate the '=' prefix here.
Joerg Sonnenberger25de31d2014-02-02 22:47:37 +00003574 switch (Triple.getArch()) {
3575 case llvm::Triple::x86:
Joerg Sonnenbergerbc923f32011-03-21 13:59:26 +00003576 getFilePaths().push_back("=/usr/lib/i386");
Joerg Sonnenberger25de31d2014-02-02 22:47:37 +00003577 break;
3578 case llvm::Triple::arm:
Joerg Sonnenberger3a6c28a2014-05-07 08:24:23 +00003579 case llvm::Triple::armeb:
Joerg Sonnenberger25de31d2014-02-02 22:47:37 +00003580 case llvm::Triple::thumb:
Joerg Sonnenberger3a6c28a2014-05-07 08:24:23 +00003581 case llvm::Triple::thumbeb:
Joerg Sonnenberger25de31d2014-02-02 22:47:37 +00003582 switch (Triple.getEnvironment()) {
3583 case llvm::Triple::EABI:
Joerg Sonnenberger25de31d2014-02-02 22:47:37 +00003584 case llvm::Triple::GNUEABI:
Joerg Sonnenberger25de31d2014-02-02 22:47:37 +00003585 getFilePaths().push_back("=/usr/lib/eabi");
3586 break;
Joerg Sonnenberger17a80e42014-08-09 19:01:52 +00003587 case llvm::Triple::EABIHF:
3588 case llvm::Triple::GNUEABIHF:
3589 getFilePaths().push_back("=/usr/lib/eabihf");
3590 break;
Joerg Sonnenberger25de31d2014-02-02 22:47:37 +00003591 default:
3592 getFilePaths().push_back("=/usr/lib/oabi");
3593 break;
3594 }
3595 break;
Joerg Sonnenbergere7f97592014-02-02 22:59:16 +00003596 case llvm::Triple::mips64:
3597 case llvm::Triple::mips64el:
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00003598 if (tools::mips::hasMipsAbiArg(Args, "o32"))
Joerg Sonnenbergere7f97592014-02-02 22:59:16 +00003599 getFilePaths().push_back("=/usr/lib/o32");
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00003600 else if (tools::mips::hasMipsAbiArg(Args, "64"))
Joerg Sonnenbergere7f97592014-02-02 22:59:16 +00003601 getFilePaths().push_back("=/usr/lib/64");
3602 break;
Joerg Sonnenbergerdd13b302014-08-13 14:17:32 +00003603 case llvm::Triple::ppc:
3604 getFilePaths().push_back("=/usr/lib/powerpc");
3605 break;
Joerg Sonnenberger8280abe2014-04-16 20:44:17 +00003606 case llvm::Triple::sparc:
3607 getFilePaths().push_back("=/usr/lib/sparc");
3608 break;
Joerg Sonnenberger25de31d2014-02-02 22:47:37 +00003609 default:
3610 break;
3611 }
Chandler Carruth1ccbed82012-01-25 11:18:20 +00003612
3613 getFilePaths().push_back("=/usr/lib");
Benjamin Kramer24f1d3e2011-02-02 18:59:27 +00003614 }
3615}
3616
Rafael Espindola7cf32212013-03-20 03:05:54 +00003617Tool *NetBSD::buildAssembler() const {
Douglas Katzman95354292015-06-23 20:42:09 +00003618 return new tools::netbsd::Assembler(*this);
Rafael Espindola7cf32212013-03-20 03:05:54 +00003619}
3620
Douglas Katzman95354292015-06-23 20:42:09 +00003621Tool *NetBSD::buildLinker() const { return new tools::netbsd::Linker(*this); }
Benjamin Kramer24f1d3e2011-02-02 18:59:27 +00003622
Jonas Hahnfeld09954192016-03-14 14:34:04 +00003623ToolChain::CXXStdlibType NetBSD::GetDefaultCXXStdlibType() const {
Joerg Sonnenbergera4435632013-10-14 20:13:05 +00003624 unsigned Major, Minor, Micro;
3625 getTriple().getOSVersion(Major, Minor, Micro);
Joerg Sonnenberger21156e82016-02-11 23:35:03 +00003626 if (Major >= 7 || Major == 0) {
Joerg Sonnenbergerd769a1e2014-01-18 00:50:49 +00003627 switch (getArch()) {
Joerg Sonnenberger323cea92014-08-09 18:28:36 +00003628 case llvm::Triple::aarch64:
Joerg Sonnenberger1ea66472014-05-07 08:45:26 +00003629 case llvm::Triple::arm:
3630 case llvm::Triple::armeb:
3631 case llvm::Triple::thumb:
3632 case llvm::Triple::thumbeb:
Joerg Sonnenbergerc8887572014-07-25 20:57:24 +00003633 case llvm::Triple::ppc:
Joerg Sonnenbergerdd13b302014-08-13 14:17:32 +00003634 case llvm::Triple::ppc64:
3635 case llvm::Triple::ppc64le:
Joerg Sonnenberger059613c2016-02-11 23:18:36 +00003636 case llvm::Triple::sparc:
3637 case llvm::Triple::sparcv9:
Joerg Sonnenbergerd769a1e2014-01-18 00:50:49 +00003638 case llvm::Triple::x86:
3639 case llvm::Triple::x86_64:
Joerg Sonnenbergera4435632013-10-14 20:13:05 +00003640 return ToolChain::CST_Libcxx;
Joerg Sonnenbergerd769a1e2014-01-18 00:50:49 +00003641 default:
3642 break;
3643 }
Joerg Sonnenbergera4435632013-10-14 20:13:05 +00003644 }
Joerg Sonnenberger428ef1e2013-04-30 01:21:43 +00003645 return ToolChain::CST_Libstdcxx;
3646}
3647
3648void NetBSD::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
3649 ArgStringList &CC1Args) const {
3650 if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
3651 DriverArgs.hasArg(options::OPT_nostdincxx))
3652 return;
3653
3654 switch (GetCXXStdlibType(DriverArgs)) {
3655 case ToolChain::CST_Libcxx:
3656 addSystemInclude(DriverArgs, CC1Args,
3657 getDriver().SysRoot + "/usr/include/c++/");
3658 break;
3659 case ToolChain::CST_Libstdcxx:
3660 addSystemInclude(DriverArgs, CC1Args,
3661 getDriver().SysRoot + "/usr/include/g++");
3662 addSystemInclude(DriverArgs, CC1Args,
3663 getDriver().SysRoot + "/usr/include/g++/backward");
3664 break;
3665 }
3666}
3667
Chris Lattner3e2ee142010-07-07 16:01:42 +00003668/// Minix - Minix tool chain which can call as(1) and ld(1) directly.
3669
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003670Minix::Minix(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
3671 : Generic_ELF(D, Triple, Args) {
Chris Lattner3e2ee142010-07-07 16:01:42 +00003672 getFilePaths().push_back(getDriver().Dir + "/../lib");
3673 getFilePaths().push_back("/usr/lib");
Chris Lattner3e2ee142010-07-07 16:01:42 +00003674}
3675
Rafael Espindola7cf32212013-03-20 03:05:54 +00003676Tool *Minix::buildAssembler() const {
Douglas Katzman95354292015-06-23 20:42:09 +00003677 return new tools::minix::Assembler(*this);
Rafael Espindola7cf32212013-03-20 03:05:54 +00003678}
3679
Douglas Katzman95354292015-06-23 20:42:09 +00003680Tool *Minix::buildLinker() const { return new tools::minix::Linker(*this); }
Chris Lattner3e2ee142010-07-07 16:01:42 +00003681
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003682static void addPathIfExists(const Driver &D, const Twine &Path,
3683 ToolChain::path_list &Paths) {
3684 if (D.getVFS().exists(Path))
Rafael Espindolac53c5b12015-08-31 19:17:51 +00003685 Paths.push_back(Path.str());
3686}
3687
David Chisnallf571cde2012-02-15 13:39:01 +00003688/// Solaris - Solaris tool chain which can call as(1) and ld(1) directly.
3689
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003690Solaris::Solaris(const Driver &D, const llvm::Triple &Triple,
Rafael Espindola1af7c212012-02-19 01:38:32 +00003691 const ArgList &Args)
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003692 : Generic_GCC(D, Triple, Args) {
David Chisnallf571cde2012-02-15 13:39:01 +00003693
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003694 GCCInstallation.init(Triple, Args);
David Chisnallf571cde2012-02-15 13:39:01 +00003695
Rafael Espindolac53c5b12015-08-31 19:17:51 +00003696 path_list &Paths = getFilePaths();
3697 if (GCCInstallation.isValid())
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003698 addPathIfExists(D, GCCInstallation.getInstallPath(), Paths);
Rafael Espindolac53c5b12015-08-31 19:17:51 +00003699
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003700 addPathIfExists(D, getDriver().getInstalledDir(), Paths);
Rafael Espindolac53c5b12015-08-31 19:17:51 +00003701 if (getDriver().getInstalledDir() != getDriver().Dir)
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003702 addPathIfExists(D, getDriver().Dir, Paths);
Rafael Espindolac53c5b12015-08-31 19:17:51 +00003703
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003704 addPathIfExists(D, getDriver().SysRoot + getDriver().Dir + "/../lib", Paths);
Rafael Espindolac53c5b12015-08-31 19:17:51 +00003705
3706 std::string LibPath = "/usr/lib/";
3707 switch (Triple.getArch()) {
3708 case llvm::Triple::x86:
3709 case llvm::Triple::sparc:
3710 break;
3711 case llvm::Triple::x86_64:
3712 LibPath += "amd64/";
3713 break;
3714 case llvm::Triple::sparcv9:
3715 LibPath += "sparcv9/";
3716 break;
3717 default:
3718 llvm_unreachable("Unsupported architecture");
3719 }
3720
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003721 addPathIfExists(D, getDriver().SysRoot + LibPath, Paths);
David Chisnallf571cde2012-02-15 13:39:01 +00003722}
3723
Rafael Espindola7cf32212013-03-20 03:05:54 +00003724Tool *Solaris::buildAssembler() const {
Douglas Katzman95354292015-06-23 20:42:09 +00003725 return new tools::solaris::Assembler(*this);
Rafael Espindola7cf32212013-03-20 03:05:54 +00003726}
3727
Douglas Katzman95354292015-06-23 20:42:09 +00003728Tool *Solaris::buildLinker() const { return new tools::solaris::Linker(*this); }
Edward O'Callaghan856e4ff2009-08-22 01:06:46 +00003729
Rafael Espindolad5117262015-09-09 13:36:00 +00003730void Solaris::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
3731 ArgStringList &CC1Args) const {
3732 if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
3733 DriverArgs.hasArg(options::OPT_nostdincxx))
3734 return;
3735
3736 // Include the support directory for things like xlocale and fudged system
3737 // headers.
3738 addSystemInclude(DriverArgs, CC1Args, "/usr/include/c++/v1/support/solaris");
3739
3740 if (GCCInstallation.isValid()) {
3741 GCCVersion Version = GCCInstallation.getVersion();
3742 addSystemInclude(DriverArgs, CC1Args,
3743 getDriver().SysRoot + "/usr/gcc/" +
3744 Version.MajorStr + "." +
3745 Version.MinorStr +
3746 "/include/c++/" + Version.Text);
3747 addSystemInclude(DriverArgs, CC1Args,
3748 getDriver().SysRoot + "/usr/gcc/" + Version.MajorStr +
3749 "." + Version.MinorStr + "/include/c++/" +
3750 Version.Text + "/" +
3751 GCCInstallation.getTriple().str());
3752 }
3753}
3754
Thomas Schwinge6d94da02013-03-28 19:02:48 +00003755/// Distribution (very bare-bones at the moment).
Eli Friedman5cd659f2009-05-26 07:52:18 +00003756
Thomas Schwinge6d94da02013-03-28 19:02:48 +00003757enum Distro {
Douglas Katzmana5df0c82015-06-22 20:55:31 +00003758 // NB: Releases of a particular Linux distro should be kept together
3759 // in this enum, because some tests are done by integer comparison against
3760 // the first and last known member in the family, e.g. IsRedHat().
Chandler Carruth6a4e8e32011-02-25 06:39:53 +00003761 ArchLinux,
Rafael Espindolac8f008f2010-11-07 20:14:31 +00003762 DebianLenny,
3763 DebianSqueeze,
Eli Friedmanf7600942011-06-02 21:36:53 +00003764 DebianWheezy,
Sylvestre Ledrubdef2892013-01-06 08:09:29 +00003765 DebianJessie,
Benjamin Kramer1a8fa8b2015-04-06 12:30:43 +00003766 DebianStretch,
Rafael Espindola12479842010-11-11 02:07:13 +00003767 Exherbo,
Chris Lattner84e38552011-05-22 05:36:06 +00003768 RHEL5,
3769 RHEL6,
Benjamin Kramer1a8fa8b2015-04-06 12:30:43 +00003770 RHEL7,
Rafael Espindola0d2cbc02013-10-25 18:09:41 +00003771 Fedora,
Rafael Espindola10a63c22013-07-03 14:14:00 +00003772 OpenSUSE,
Douglas Gregor0a36f4d2011-03-14 15:39:50 +00003773 UbuntuHardy,
3774 UbuntuIntrepid,
Rafael Espindola66b291a2010-11-10 05:00:22 +00003775 UbuntuJaunty,
Zhongxing Xu14776cf2010-11-15 09:01:52 +00003776 UbuntuKarmic,
Rafael Espindolac8f008f2010-11-07 20:14:31 +00003777 UbuntuLucid,
3778 UbuntuMaverick,
Ted Kremenek43d47cc2011-04-05 22:04:27 +00003779 UbuntuNatty,
Benjamin Kramerf90b5de2011-06-05 16:08:59 +00003780 UbuntuOneiric,
Benjamin Kramer7c3f09d2012-02-06 14:36:09 +00003781 UbuntuPrecise,
Rafael Espindola62e87702012-12-13 20:26:05 +00003782 UbuntuQuantal,
3783 UbuntuRaring,
Sylvestre Ledru93c47b72013-06-13 11:52:27 +00003784 UbuntuSaucy,
Sylvestre Ledruaaf01a72013-11-07 09:31:30 +00003785 UbuntuTrusty,
Benjamin Kramer1a8fa8b2015-04-06 12:30:43 +00003786 UbuntuUtopic,
3787 UbuntuVivid,
Benjamin Kramer2d469802015-07-09 15:31:17 +00003788 UbuntuWily,
Sylvestre Ledru43b95712015-10-29 17:27:55 +00003789 UbuntuXenial,
Sylvestre Ledrud3078e72016-07-19 14:00:57 +00003790 UbuntuYakkety,
Rafael Espindolac8f008f2010-11-07 20:14:31 +00003791 UnknownDistro
3792};
3793
Thomas Schwinge6d94da02013-03-28 19:02:48 +00003794static bool IsRedhat(enum Distro Distro) {
Rafael Espindola52fe8962016-05-09 13:13:50 +00003795 return Distro == Fedora || (Distro >= RHEL5 && Distro <= RHEL7);
Rafael Espindolac8f008f2010-11-07 20:14:31 +00003796}
3797
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003798static bool IsOpenSUSE(enum Distro Distro) { return Distro == OpenSUSE; }
Rafael Espindolac8f008f2010-11-07 20:14:31 +00003799
Thomas Schwinge6d94da02013-03-28 19:02:48 +00003800static bool IsDebian(enum Distro Distro) {
Benjamin Kramer1a8fa8b2015-04-06 12:30:43 +00003801 return Distro >= DebianLenny && Distro <= DebianStretch;
Rafael Espindolac8f008f2010-11-07 20:14:31 +00003802}
3803
Thomas Schwinge6d94da02013-03-28 19:02:48 +00003804static bool IsUbuntu(enum Distro Distro) {
Sylvestre Ledrud3078e72016-07-19 14:00:57 +00003805 return Distro >= UbuntuHardy && Distro <= UbuntuYakkety;
Rafael Espindolac8f008f2010-11-07 20:14:31 +00003806}
3807
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003808static Distro DetectDistro(const Driver &D, llvm::Triple::ArchType Arch) {
Rafael Espindola2d2b4202014-07-06 17:43:24 +00003809 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> File =
3810 llvm::MemoryBuffer::getFile("/etc/lsb-release");
3811 if (File) {
Chris Lattner0e62c1c2011-07-23 10:55:15 +00003812 StringRef Data = File.get()->getBuffer();
Hans Wennborg3b7dd8d2014-08-11 18:09:32 +00003813 SmallVector<StringRef, 16> Lines;
Rafael Espindolac8f008f2010-11-07 20:14:31 +00003814 Data.split(Lines, "\n");
Thomas Schwinge6d94da02013-03-28 19:02:48 +00003815 Distro Version = UnknownDistro;
Benjamin Kramer72e64312015-09-24 14:48:49 +00003816 for (StringRef Line : Lines)
Douglas Katzman6bbffc42015-06-25 18:51:37 +00003817 if (Version == UnknownDistro && Line.startswith("DISTRIB_CODENAME="))
3818 Version = llvm::StringSwitch<Distro>(Line.substr(17))
3819 .Case("hardy", UbuntuHardy)
3820 .Case("intrepid", UbuntuIntrepid)
3821 .Case("jaunty", UbuntuJaunty)
3822 .Case("karmic", UbuntuKarmic)
3823 .Case("lucid", UbuntuLucid)
3824 .Case("maverick", UbuntuMaverick)
3825 .Case("natty", UbuntuNatty)
3826 .Case("oneiric", UbuntuOneiric)
3827 .Case("precise", UbuntuPrecise)
3828 .Case("quantal", UbuntuQuantal)
3829 .Case("raring", UbuntuRaring)
3830 .Case("saucy", UbuntuSaucy)
3831 .Case("trusty", UbuntuTrusty)
3832 .Case("utopic", UbuntuUtopic)
3833 .Case("vivid", UbuntuVivid)
Benjamin Kramer2d469802015-07-09 15:31:17 +00003834 .Case("wily", UbuntuWily)
Sylvestre Ledru43b95712015-10-29 17:27:55 +00003835 .Case("xenial", UbuntuXenial)
Sylvestre Ledrud3078e72016-07-19 14:00:57 +00003836 .Case("yakkety", UbuntuYakkety)
Douglas Katzman6bbffc42015-06-25 18:51:37 +00003837 .Default(UnknownDistro);
Rafael Espindola52fe8962016-05-09 13:13:50 +00003838 if (Version != UnknownDistro)
3839 return Version;
Rafael Espindolac8f008f2010-11-07 20:14:31 +00003840 }
3841
Rafael Espindola2d2b4202014-07-06 17:43:24 +00003842 File = llvm::MemoryBuffer::getFile("/etc/redhat-release");
3843 if (File) {
Chris Lattner0e62c1c2011-07-23 10:55:15 +00003844 StringRef Data = File.get()->getBuffer();
Rafael Espindola0d2cbc02013-10-25 18:09:41 +00003845 if (Data.startswith("Fedora release"))
3846 return Fedora;
Benjamin Kramer6af073b2014-05-05 12:39:32 +00003847 if (Data.startswith("Red Hat Enterprise Linux") ||
Rafael Espindola52fe8962016-05-09 13:13:50 +00003848 Data.startswith("CentOS") ||
3849 Data.startswith("Scientific Linux")) {
Benjamin Kramer1a8fa8b2015-04-06 12:30:43 +00003850 if (Data.find("release 7") != StringRef::npos)
3851 return RHEL7;
3852 else if (Data.find("release 6") != StringRef::npos)
Benjamin Kramer6af073b2014-05-05 12:39:32 +00003853 return RHEL6;
3854 else if (Data.find("release 5") != StringRef::npos)
3855 return RHEL5;
Benjamin Kramer6af073b2014-05-05 12:39:32 +00003856 }
Rafael Espindolac8f008f2010-11-07 20:14:31 +00003857 return UnknownDistro;
3858 }
3859
Rafael Espindola2d2b4202014-07-06 17:43:24 +00003860 File = llvm::MemoryBuffer::getFile("/etc/debian_version");
3861 if (File) {
Chris Lattner0e62c1c2011-07-23 10:55:15 +00003862 StringRef Data = File.get()->getBuffer();
Rafael Espindolac8f008f2010-11-07 20:14:31 +00003863 if (Data[0] == '5')
3864 return DebianLenny;
Rafael Espindola1510c852011-12-28 18:17:14 +00003865 else if (Data.startswith("squeeze/sid") || Data[0] == '6')
Rafael Espindolac8f008f2010-11-07 20:14:31 +00003866 return DebianSqueeze;
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003867 else if (Data.startswith("wheezy/sid") || Data[0] == '7')
Eli Friedmanf7600942011-06-02 21:36:53 +00003868 return DebianWheezy;
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003869 else if (Data.startswith("jessie/sid") || Data[0] == '8')
Sylvestre Ledrubdef2892013-01-06 08:09:29 +00003870 return DebianJessie;
Benjamin Kramer1a8fa8b2015-04-06 12:30:43 +00003871 else if (Data.startswith("stretch/sid") || Data[0] == '9')
3872 return DebianStretch;
Rafael Espindolac8f008f2010-11-07 20:14:31 +00003873 return UnknownDistro;
3874 }
3875
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003876 if (D.getVFS().exists("/etc/SuSE-release"))
Rafael Espindola10a63c22013-07-03 14:14:00 +00003877 return OpenSUSE;
Rafael Espindolac8f008f2010-11-07 20:14:31 +00003878
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003879 if (D.getVFS().exists("/etc/exherbo-release"))
Rafael Espindola12479842010-11-11 02:07:13 +00003880 return Exherbo;
3881
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003882 if (D.getVFS().exists("/etc/arch-release"))
Chandler Carruth6a4e8e32011-02-25 06:39:53 +00003883 return ArchLinux;
3884
Rafael Espindolac8f008f2010-11-07 20:14:31 +00003885 return UnknownDistro;
3886}
3887
Chandler Carruthfb7fa242011-10-31 08:42:24 +00003888/// \brief Get our best guess at the multiarch triple for a target.
3889///
3890/// Debian-based systems are starting to use a multiarch setup where they use
3891/// a target-triple directory in the library and header search paths.
3892/// Unfortunately, this triple does not align with the vanilla target triple,
3893/// so we provide a rough mapping here.
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003894static std::string getMultiarchTriple(const Driver &D,
3895 const llvm::Triple &TargetTriple,
Chandler Carruthfb7fa242011-10-31 08:42:24 +00003896 StringRef SysRoot) {
Eric Christopherefef8ef2015-12-07 22:43:05 +00003897 llvm::Triple::EnvironmentType TargetEnvironment =
3898 TargetTriple.getEnvironment();
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003899
Chandler Carruthfb7fa242011-10-31 08:42:24 +00003900 // For most architectures, just use whatever we have rather than trying to be
3901 // clever.
3902 switch (TargetTriple.getArch()) {
3903 default:
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003904 break;
Chandler Carruthfb7fa242011-10-31 08:42:24 +00003905
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003906 // We use the existence of '/lib/<triple>' as a directory to detect some
3907 // common linux triples that don't quite match the Clang triple for both
3908 // 32-bit and 64-bit targets. Multiarch fixes its install triples to these
3909 // regardless of what the actual target triple is.
Chad Rosier4dce73a2012-07-11 19:08:21 +00003910 case llvm::Triple::arm:
3911 case llvm::Triple::thumb:
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003912 if (TargetEnvironment == llvm::Triple::GNUEABIHF) {
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003913 if (D.getVFS().exists(SysRoot + "/lib/arm-linux-gnueabihf"))
Jiangning Liu61b06cb2012-07-31 08:06:29 +00003914 return "arm-linux-gnueabihf";
3915 } else {
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003916 if (D.getVFS().exists(SysRoot + "/lib/arm-linux-gnueabi"))
Jiangning Liu61b06cb2012-07-31 08:06:29 +00003917 return "arm-linux-gnueabi";
3918 }
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003919 break;
Christian Pirkerf01cd6f2014-03-28 14:40:46 +00003920 case llvm::Triple::armeb:
3921 case llvm::Triple::thumbeb:
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003922 if (TargetEnvironment == llvm::Triple::GNUEABIHF) {
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003923 if (D.getVFS().exists(SysRoot + "/lib/armeb-linux-gnueabihf"))
Christian Pirkerf01cd6f2014-03-28 14:40:46 +00003924 return "armeb-linux-gnueabihf";
3925 } else {
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003926 if (D.getVFS().exists(SysRoot + "/lib/armeb-linux-gnueabi"))
Christian Pirkerf01cd6f2014-03-28 14:40:46 +00003927 return "armeb-linux-gnueabi";
3928 }
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003929 break;
Chandler Carruthfb7fa242011-10-31 08:42:24 +00003930 case llvm::Triple::x86:
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003931 if (D.getVFS().exists(SysRoot + "/lib/i386-linux-gnu"))
Chandler Carruthfb7fa242011-10-31 08:42:24 +00003932 return "i386-linux-gnu";
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003933 break;
Chandler Carruthfb7fa242011-10-31 08:42:24 +00003934 case llvm::Triple::x86_64:
Zinovy Nis1db95732014-07-10 15:27:19 +00003935 // We don't want this for x32, otherwise it will match x86_64 libs
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003936 if (TargetEnvironment != llvm::Triple::GNUX32 &&
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003937 D.getVFS().exists(SysRoot + "/lib/x86_64-linux-gnu"))
Chandler Carruthfb7fa242011-10-31 08:42:24 +00003938 return "x86_64-linux-gnu";
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003939 break;
Tim Northover9bb857a2013-01-31 12:13:10 +00003940 case llvm::Triple::aarch64:
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003941 if (D.getVFS().exists(SysRoot + "/lib/aarch64-linux-gnu"))
Tim Northover9bb857a2013-01-31 12:13:10 +00003942 return "aarch64-linux-gnu";
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003943 break;
Christian Pirkera74c7912014-03-14 12:15:45 +00003944 case llvm::Triple::aarch64_be:
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003945 if (D.getVFS().exists(SysRoot + "/lib/aarch64_be-linux-gnu"))
Christian Pirkera74c7912014-03-14 12:15:45 +00003946 return "aarch64_be-linux-gnu";
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003947 break;
Eli Friedman27b8c4f2011-11-08 19:43:37 +00003948 case llvm::Triple::mips:
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003949 if (D.getVFS().exists(SysRoot + "/lib/mips-linux-gnu"))
Eli Friedman27b8c4f2011-11-08 19:43:37 +00003950 return "mips-linux-gnu";
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003951 break;
Eli Friedman27b8c4f2011-11-08 19:43:37 +00003952 case llvm::Triple::mipsel:
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003953 if (D.getVFS().exists(SysRoot + "/lib/mipsel-linux-gnu"))
Eli Friedman27b8c4f2011-11-08 19:43:37 +00003954 return "mipsel-linux-gnu";
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003955 break;
Simon Atanasyan3a46afa2014-06-24 19:00:12 +00003956 case llvm::Triple::mips64:
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003957 if (D.getVFS().exists(SysRoot + "/lib/mips64-linux-gnu"))
Simon Atanasyan3a46afa2014-06-24 19:00:12 +00003958 return "mips64-linux-gnu";
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003959 if (D.getVFS().exists(SysRoot + "/lib/mips64-linux-gnuabi64"))
Simon Atanasyan3a46afa2014-06-24 19:00:12 +00003960 return "mips64-linux-gnuabi64";
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003961 break;
Simon Atanasyan3a46afa2014-06-24 19:00:12 +00003962 case llvm::Triple::mips64el:
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003963 if (D.getVFS().exists(SysRoot + "/lib/mips64el-linux-gnu"))
Simon Atanasyan3a46afa2014-06-24 19:00:12 +00003964 return "mips64el-linux-gnu";
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003965 if (D.getVFS().exists(SysRoot + "/lib/mips64el-linux-gnuabi64"))
Simon Atanasyan3a46afa2014-06-24 19:00:12 +00003966 return "mips64el-linux-gnuabi64";
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003967 break;
Chandler Carruthaf3c2092012-02-26 09:03:21 +00003968 case llvm::Triple::ppc:
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003969 if (D.getVFS().exists(SysRoot + "/lib/powerpc-linux-gnuspe"))
Sylvestre Ledrue0bf5812013-03-15 16:22:43 +00003970 return "powerpc-linux-gnuspe";
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003971 if (D.getVFS().exists(SysRoot + "/lib/powerpc-linux-gnu"))
Chandler Carruthaf3c2092012-02-26 09:03:21 +00003972 return "powerpc-linux-gnu";
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003973 break;
Chandler Carruthaf3c2092012-02-26 09:03:21 +00003974 case llvm::Triple::ppc64:
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003975 if (D.getVFS().exists(SysRoot + "/lib/powerpc64-linux-gnu"))
Chandler Carruthaf3c2092012-02-26 09:03:21 +00003976 return "powerpc64-linux-gnu";
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003977 break;
Bill Schmidt778d3872013-07-26 01:36:11 +00003978 case llvm::Triple::ppc64le:
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003979 if (D.getVFS().exists(SysRoot + "/lib/powerpc64le-linux-gnu"))
Bill Schmidt778d3872013-07-26 01:36:11 +00003980 return "powerpc64le-linux-gnu";
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003981 break;
James Y Knightc0aeadf2015-06-04 15:36:30 +00003982 case llvm::Triple::sparc:
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003983 if (D.getVFS().exists(SysRoot + "/lib/sparc-linux-gnu"))
James Y Knightc0aeadf2015-06-04 15:36:30 +00003984 return "sparc-linux-gnu";
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003985 break;
James Y Knightc0aeadf2015-06-04 15:36:30 +00003986 case llvm::Triple::sparcv9:
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003987 if (D.getVFS().exists(SysRoot + "/lib/sparc64-linux-gnu"))
James Y Knightc0aeadf2015-06-04 15:36:30 +00003988 return "sparc64-linux-gnu";
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003989 break;
Sylvestre Ledruc0babf22015-08-28 12:26:09 +00003990 case llvm::Triple::systemz:
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003991 if (D.getVFS().exists(SysRoot + "/lib/s390x-linux-gnu"))
Sylvestre Ledruc0babf22015-08-28 12:26:09 +00003992 return "s390x-linux-gnu";
3993 break;
Chandler Carruthfb7fa242011-10-31 08:42:24 +00003994 }
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003995 return TargetTriple.str();
Chandler Carruthfb7fa242011-10-31 08:42:24 +00003996}
3997
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00003998static StringRef getOSLibDir(const llvm::Triple &Triple, const ArgList &Args) {
Chandler Carruthda797042013-10-29 10:27:30 +00003999 if (isMipsArch(Triple.getArch())) {
Simon Atanasyan603018a2016-07-19 07:09:48 +00004000 if (Triple.isAndroid()) {
4001 StringRef CPUName;
4002 StringRef ABIName;
4003 tools::mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
4004 if (CPUName == "mips32r6")
4005 return "libr6";
4006 if (CPUName == "mips32r2")
4007 return "libr2";
4008 }
Chandler Carruthda797042013-10-29 10:27:30 +00004009 // lib32 directory has a special meaning on MIPS targets.
4010 // It contains N32 ABI binaries. Use this folder if produce
4011 // code for N32 ABI only.
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00004012 if (tools::mips::hasMipsAbiArg(Args, "n32"))
Chandler Carruthda797042013-10-29 10:27:30 +00004013 return "lib32";
4014 return Triple.isArch32Bit() ? "lib" : "lib64";
4015 }
Simon Atanasyand4413882012-09-14 11:27:24 +00004016
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00004017 // It happens that only x86 and PPC use the 'lib32' variant of oslibdir, and
Chandler Carruthda797042013-10-29 10:27:30 +00004018 // using that variant while targeting other architectures causes problems
4019 // because the libraries are laid out in shared system roots that can't cope
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00004020 // with a 'lib32' library search path being considered. So we only enable
Chandler Carruthda797042013-10-29 10:27:30 +00004021 // them when we know we may need it.
4022 //
4023 // FIXME: This is a bit of a hack. We should really unify this code for
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00004024 // reasoning about oslibdir spellings with the lib dir spellings in the
Chandler Carruthda797042013-10-29 10:27:30 +00004025 // GCCInstallationDetector, but that is a more significant refactoring.
4026 if (Triple.getArch() == llvm::Triple::x86 ||
4027 Triple.getArch() == llvm::Triple::ppc)
Simon Atanasyand4413882012-09-14 11:27:24 +00004028 return "lib32";
4029
Zinovy Nis1db95732014-07-10 15:27:19 +00004030 if (Triple.getArch() == llvm::Triple::x86_64 &&
4031 Triple.getEnvironment() == llvm::Triple::GNUX32)
4032 return "libx32";
4033
Simon Atanasyand4413882012-09-14 11:27:24 +00004034 return Triple.isArch32Bit() ? "lib" : "lib64";
4035}
4036
Simon Atanasyan2834a222016-05-22 18:18:07 +00004037static void addMultilibsFilePaths(const Driver &D, const MultilibSet &Multilibs,
4038 const Multilib &Multilib,
4039 StringRef InstallPath,
4040 ToolChain::path_list &Paths) {
4041 if (const auto &PathsCallback = Multilibs.filePathsCallback())
4042 for (const auto &Path : PathsCallback(Multilib))
4043 addPathIfExists(D, InstallPath + Path, Paths);
4044}
4045
Rafael Espindola1af7c212012-02-19 01:38:32 +00004046Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004047 : Generic_ELF(D, Triple, Args) {
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004048 GCCInstallation.init(Triple, Args);
4049 CudaInstallation.init(Triple, Args);
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00004050 Multilibs = GCCInstallation.getMultilibs();
Chandler Carruth96bae7b2012-01-24 20:08:17 +00004051 llvm::Triple::ArchType Arch = Triple.getArch();
Simon Atanasyana0d89572013-10-05 14:37:55 +00004052 std::string SysRoot = computeSysRoot();
Rafael Espindolac8f008f2010-11-07 20:14:31 +00004053
Rafael Espindola10a63c22013-07-03 14:14:00 +00004054 // Cross-compiling binutils and GCC installations (vanilla and openSUSE at
Chandler Carruthd6c62b62013-06-20 23:37:54 +00004055 // least) put various tools in a triple-prefixed directory off of the parent
4056 // of the GCC installation. We use the GCC triple here to ensure that we end
4057 // up with tools that support the same amount of cross compiling as the
4058 // detected GCC installation. For example, if we find a GCC installation
4059 // targeting x86_64, but it is a bi-arch GCC installation, it can also be
4060 // used to target i386.
4061 // FIXME: This seems unlikely to be Linux-specific.
Rafael Espindola5f344ff2011-09-01 16:25:49 +00004062 ToolChain::path_list &PPaths = getProgramPaths();
Chandler Carruth4be70dd2011-11-06 09:21:54 +00004063 PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + "/../" +
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004064 GCCInstallation.getTriple().str() + "/bin")
4065 .str());
Rafael Espindola5f344ff2011-09-01 16:25:49 +00004066
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004067 Distro Distro = DetectDistro(D, Arch);
Rafael Espindolac8f008f2010-11-07 20:14:31 +00004068
Rafael Espindola10a63c22013-07-03 14:14:00 +00004069 if (IsOpenSUSE(Distro) || IsUbuntu(Distro)) {
Rafael Espindolac5688622010-11-08 14:48:47 +00004070 ExtraOpts.push_back("-z");
4071 ExtraOpts.push_back("relro");
4072 }
Rafael Espindolac8f008f2010-11-07 20:14:31 +00004073
Douglas Gregord9bb1522011-03-06 19:11:49 +00004074 if (Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb)
Rafael Espindolac8f008f2010-11-07 20:14:31 +00004075 ExtraOpts.push_back("-X");
4076
Evgeniy Stepanov14deb7b2015-10-08 21:21:44 +00004077 const bool IsAndroid = Triple.isAndroid();
Simon Atanasyan08450bd2013-04-20 08:15:03 +00004078 const bool IsMips = isMipsArch(Arch);
4079
4080 if (IsMips && !SysRoot.empty())
4081 ExtraOpts.push_back("--sysroot=" + SysRoot);
Evgeniy Stepanov2ca1aa52012-01-13 09:30:38 +00004082
Chandler Carruth0b842912011-12-09 04:45:18 +00004083 // Do not use 'gnu' hash style for Mips targets because .gnu.hash
4084 // and the MIPS ABI require .dynsym to be sorted in different ways.
4085 // .gnu.hash needs symbols to be grouped by hash code whereas the MIPS
4086 // ABI requires a mapping between the GOT and the symbol table.
Evgeniy Stepanov2ca1aa52012-01-13 09:30:38 +00004087 // Android loader does not support .gnu.hash.
Simon Atanasyan08450bd2013-04-20 08:15:03 +00004088 if (!IsMips && !IsAndroid) {
Rafael Espindola10a63c22013-07-03 14:14:00 +00004089 if (IsRedhat(Distro) || IsOpenSUSE(Distro) ||
Benjamin Kramer7c3f09d2012-02-06 14:36:09 +00004090 (IsUbuntu(Distro) && Distro >= UbuntuMaverick))
Chandler Carruth0b842912011-12-09 04:45:18 +00004091 ExtraOpts.push_back("--hash-style=gnu");
4092
Rafael Espindola10a63c22013-07-03 14:14:00 +00004093 if (IsDebian(Distro) || IsOpenSUSE(Distro) || Distro == UbuntuLucid ||
Chandler Carruth0b842912011-12-09 04:45:18 +00004094 Distro == UbuntuJaunty || Distro == UbuntuKarmic)
4095 ExtraOpts.push_back("--hash-style=both");
4096 }
Rafael Espindolac8f008f2010-11-07 20:14:31 +00004097
Rafael Espindola52fe8962016-05-09 13:13:50 +00004098 if (IsRedhat(Distro) && Distro != RHEL5 && Distro != RHEL6)
Rafael Espindolac8f008f2010-11-07 20:14:31 +00004099 ExtraOpts.push_back("--no-add-needed");
4100
Rafael Espindola5ed89d42016-06-03 17:26:16 +00004101#ifdef ENABLE_LINKER_BUILD_ID
4102 ExtraOpts.push_back("--build-id");
4103#endif
Rafael Espindolac8f008f2010-11-07 20:14:31 +00004104
Rafael Espindola10a63c22013-07-03 14:14:00 +00004105 if (IsOpenSUSE(Distro))
Chandler Carruthe5d9d902011-05-24 07:51:17 +00004106 ExtraOpts.push_back("--enable-new-dtags");
Chris Lattnerd075c822011-05-22 16:45:07 +00004107
Chandler Carruth413e5ac2011-10-03 05:28:29 +00004108 // The selection of paths to try here is designed to match the patterns which
4109 // the GCC driver itself uses, as this is part of the GCC-compatible driver.
4110 // This was determined by running GCC in a fake filesystem, creating all
4111 // possible permutations of these directories, and seeing which ones it added
4112 // to the link paths.
4113 path_list &Paths = getFilePaths();
Chandler Carruth6a4e8e32011-02-25 06:39:53 +00004114
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00004115 const std::string OSLibDir = getOSLibDir(Triple, Args);
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004116 const std::string MultiarchTriple = getMultiarchTriple(D, Triple, SysRoot);
Chandler Carruth413e5ac2011-10-03 05:28:29 +00004117
Chandler Carruthd0b93d62011-11-06 23:09:05 +00004118 // Add the multilib suffixed paths where they are available.
4119 if (GCCInstallation.isValid()) {
Chandler Carruth4d9d7682012-01-24 19:28:29 +00004120 const llvm::Triple &GCCTriple = GCCInstallation.getTriple();
Chandler Carruth96bae7b2012-01-24 20:08:17 +00004121 const std::string &LibPath = GCCInstallation.getParentLibPath();
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00004122 const Multilib &Multilib = GCCInstallation.getMultilib();
Simon Atanasyan2834a222016-05-22 18:18:07 +00004123 const MultilibSet &Multilibs = GCCInstallation.getMultilibs();
4124
4125 // Add toolchain / multilib specific file paths.
4126 addMultilibsFilePaths(D, Multilibs, Multilib,
4127 GCCInstallation.getInstallPath(), Paths);
Simon Atanasyan53fefd12012-10-03 17:46:38 +00004128
Chandler Carruth7f8042c2013-07-31 00:37:07 +00004129 // Sourcery CodeBench MIPS toolchain holds some libraries under
Chandler Carruth9b6ce932013-10-29 02:27:56 +00004130 // a biarch-like suffix of the GCC installation.
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004131 addPathIfExists(D, GCCInstallation.getInstallPath() + Multilib.gccSuffix(),
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00004132 Paths);
Chandler Carruth7f8042c2013-07-31 00:37:07 +00004133
4134 // GCC cross compiling toolchains will install target libraries which ship
4135 // as part of the toolchain under <prefix>/<triple>/<libdir> rather than as
4136 // any part of the GCC installation in
4137 // <prefix>/<libdir>/gcc/<triple>/<version>. This decision is somewhat
4138 // debatable, but is the reality today. We need to search this tree even
4139 // when we have a sysroot somewhere else. It is the responsibility of
Alp Tokerf6a24ce2013-12-05 16:25:25 +00004140 // whomever is doing the cross build targeting a sysroot using a GCC
Chandler Carruth7f8042c2013-07-31 00:37:07 +00004141 // installation that is *not* within the system root to ensure two things:
4142 //
4143 // 1) Any DSOs that are linked in from this tree or from the install path
Alexander Potapenkoc8e749a2014-09-01 12:35:57 +00004144 // above must be present on the system root and found via an
Chandler Carruth7f8042c2013-07-31 00:37:07 +00004145 // appropriate rpath.
4146 // 2) There must not be libraries installed into
4147 // <prefix>/<triple>/<libdir> unless they should be preferred over
4148 // those within the system root.
4149 //
4150 // Note that this matches the GCC behavior. See the below comment for where
4151 // Clang diverges from GCC's behavior.
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004152 addPathIfExists(D, LibPath + "/../" + GCCTriple.str() + "/lib/../" +
4153 OSLibDir + Multilib.osSuffix(),
Chandler Carruth7f8042c2013-07-31 00:37:07 +00004154 Paths);
4155
Chandler Carruth69a125b2012-04-06 16:32:06 +00004156 // If the GCC installation we found is inside of the sysroot, we want to
4157 // prefer libraries installed in the parent prefix of the GCC installation.
4158 // It is important to *not* use these paths when the GCC installation is
Gabor Greif5d3231c2012-04-18 10:59:08 +00004159 // outside of the system root as that can pick up unintended libraries.
Chandler Carruth69a125b2012-04-06 16:32:06 +00004160 // This usually happens when there is an external cross compiler on the
4161 // host system, and a more minimal sysroot available that is the target of
Chandler Carruth7f8042c2013-07-31 00:37:07 +00004162 // the cross. Note that GCC does include some of these directories in some
4163 // configurations but this seems somewhere between questionable and simply
4164 // a bug.
Chandler Carruth69a125b2012-04-06 16:32:06 +00004165 if (StringRef(LibPath).startswith(SysRoot)) {
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004166 addPathIfExists(D, LibPath + "/" + MultiarchTriple, Paths);
4167 addPathIfExists(D, LibPath + "/../" + OSLibDir, Paths);
Chandler Carruth69a125b2012-04-06 16:32:06 +00004168 }
Rafael Espindolac8f008f2010-11-07 20:14:31 +00004169 }
Chandler Carruth902efc62014-01-21 22:49:05 +00004170
4171 // Similar to the logic for GCC above, if we currently running Clang inside
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00004172 // of the requested system root, add its parent library paths to
Chandler Carruth902efc62014-01-21 22:49:05 +00004173 // those searched.
4174 // FIXME: It's not clear whether we should use the driver's installed
4175 // directory ('Dir' below) or the ResourceDir.
4176 if (StringRef(D.Dir).startswith(SysRoot)) {
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004177 addPathIfExists(D, D.Dir + "/../lib/" + MultiarchTriple, Paths);
4178 addPathIfExists(D, D.Dir + "/../" + OSLibDir, Paths);
Chandler Carruth902efc62014-01-21 22:49:05 +00004179 }
4180
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004181 addPathIfExists(D, SysRoot + "/lib/" + MultiarchTriple, Paths);
4182 addPathIfExists(D, SysRoot + "/lib/../" + OSLibDir, Paths);
4183 addPathIfExists(D, SysRoot + "/usr/lib/" + MultiarchTriple, Paths);
4184 addPathIfExists(D, SysRoot + "/usr/lib/../" + OSLibDir, Paths);
Chandler Carruthd0b93d62011-11-06 23:09:05 +00004185
Chandler Carruthb427c562013-06-22 11:35:51 +00004186 // Try walking via the GCC triple path in case of biarch or multiarch GCC
Chandler Carruthd0b93d62011-11-06 23:09:05 +00004187 // installations with strange symlinks.
Rafael Espindolab6250162013-10-25 17:06:04 +00004188 if (GCCInstallation.isValid()) {
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004189 addPathIfExists(D,
4190 SysRoot + "/usr/lib/" + GCCInstallation.getTriple().str() +
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004191 "/../../" + OSLibDir,
4192 Paths);
Rafael Espindola30490212011-06-03 15:39:42 +00004193
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00004194 // Add the 'other' biarch variant path
4195 Multilib BiarchSibling;
4196 if (GCCInstallation.getBiarchSibling(BiarchSibling)) {
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004197 addPathIfExists(D, GCCInstallation.getInstallPath() +
4198 BiarchSibling.gccSuffix(),
4199 Paths);
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00004200 }
Chandler Carruth69a125b2012-04-06 16:32:06 +00004201
Chandler Carruth7f8042c2013-07-31 00:37:07 +00004202 // See comments above on the multilib variant for details of why this is
4203 // included even from outside the sysroot.
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00004204 const std::string &LibPath = GCCInstallation.getParentLibPath();
4205 const llvm::Triple &GCCTriple = GCCInstallation.getTriple();
4206 const Multilib &Multilib = GCCInstallation.getMultilib();
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004207 addPathIfExists(D, LibPath + "/../" + GCCTriple.str() + "/lib" +
4208 Multilib.osSuffix(),
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004209 Paths);
Chandler Carruth7f8042c2013-07-31 00:37:07 +00004210
4211 // See comments above on the multilib variant for details of why this is
4212 // only included from within the sysroot.
4213 if (StringRef(LibPath).startswith(SysRoot))
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004214 addPathIfExists(D, LibPath, Paths);
Chandler Carruth413e5ac2011-10-03 05:28:29 +00004215 }
Chandler Carruth902efc62014-01-21 22:49:05 +00004216
4217 // Similar to the logic for GCC above, if we are currently running Clang
4218 // inside of the requested system root, add its parent library path to those
4219 // searched.
4220 // FIXME: It's not clear whether we should use the driver's installed
4221 // directory ('Dir' below) or the ResourceDir.
4222 if (StringRef(D.Dir).startswith(SysRoot))
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004223 addPathIfExists(D, D.Dir + "/../lib", Paths);
Chandler Carruth902efc62014-01-21 22:49:05 +00004224
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004225 addPathIfExists(D, SysRoot + "/lib", Paths);
4226 addPathIfExists(D, SysRoot + "/usr/lib", Paths);
Rafael Espindolac8f008f2010-11-07 20:14:31 +00004227}
4228
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004229bool Linux::HasNativeLLVMSupport() const { return true; }
Eli Friedman5cd659f2009-05-26 07:52:18 +00004230
Douglas Katzman95354292015-06-23 20:42:09 +00004231Tool *Linux::buildLinker() const { return new tools::gnutools::Linker(*this); }
Rafael Espindola7cf32212013-03-20 03:05:54 +00004232
4233Tool *Linux::buildAssembler() const {
Douglas Katzman95354292015-06-23 20:42:09 +00004234 return new tools::gnutools::Assembler(*this);
Rafael Espindola92b00932010-08-10 00:25:48 +00004235}
4236
Simon Atanasyana0d89572013-10-05 14:37:55 +00004237std::string Linux::computeSysRoot() const {
Simon Atanasyan08450bd2013-04-20 08:15:03 +00004238 if (!getDriver().SysRoot.empty())
4239 return getDriver().SysRoot;
4240
4241 if (!GCCInstallation.isValid() || !isMipsArch(getTriple().getArch()))
4242 return std::string();
4243
Simon Atanasyana61b7ec2013-10-10 07:57:44 +00004244 // Standalone MIPS toolchains use different names for sysroot folder
4245 // and put it into different places. Here we try to check some known
4246 // variants.
Simon Atanasyan08450bd2013-04-20 08:15:03 +00004247
Simon Atanasyana61b7ec2013-10-10 07:57:44 +00004248 const StringRef InstallDir = GCCInstallation.getInstallPath();
4249 const StringRef TripleStr = GCCInstallation.getTriple().str();
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00004250 const Multilib &Multilib = GCCInstallation.getMultilib();
Simon Atanasyana61b7ec2013-10-10 07:57:44 +00004251
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004252 std::string Path =
4253 (InstallDir + "/../../../../" + TripleStr + "/libc" + Multilib.osSuffix())
4254 .str();
Simon Atanasyana61b7ec2013-10-10 07:57:44 +00004255
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004256 if (getVFS().exists(Path))
Simon Atanasyana61b7ec2013-10-10 07:57:44 +00004257 return Path;
4258
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00004259 Path = (InstallDir + "/../../../../sysroot" + Multilib.osSuffix()).str();
Simon Atanasyana61b7ec2013-10-10 07:57:44 +00004260
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004261 if (getVFS().exists(Path))
Simon Atanasyana61b7ec2013-10-10 07:57:44 +00004262 return Path;
4263
4264 return std::string();
Simon Atanasyan08450bd2013-04-20 08:15:03 +00004265}
4266
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004267std::string Linux::getDynamicLinker(const ArgList &Args) const {
4268 const llvm::Triple::ArchType Arch = getArch();
4269 const llvm::Triple &Triple = getTriple();
4270
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004271 const enum Distro Distro = DetectDistro(getDriver(), Arch);
4272
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004273 if (Triple.isAndroid())
4274 return Triple.isArch64Bit() ? "/system/bin/linker64" : "/system/bin/linker";
Rafael Espindola0fa66802016-06-24 21:35:06 +00004275 else if (Triple.isMusl()) {
4276 std::string ArchName;
4277 switch (Arch) {
4278 case llvm::Triple::thumb:
4279 ArchName = "arm";
4280 break;
4281 case llvm::Triple::thumbeb:
4282 ArchName = "armeb";
4283 break;
4284 default:
4285 ArchName = Triple.getArchName().str();
4286 }
4287 if (Triple.getEnvironment() == llvm::Triple::MuslEABIHF)
4288 ArchName += "hf";
4289
4290 return "/lib/ld-musl-" + ArchName + ".so.1";
4291 }
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004292
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004293 std::string LibDir;
4294 std::string Loader;
4295
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004296 switch (Arch) {
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004297 default:
4298 llvm_unreachable("unsupported architecture");
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004299
4300 case llvm::Triple::aarch64:
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004301 LibDir = "lib";
4302 Loader = "ld-linux-aarch64.so.1";
4303 break;
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004304 case llvm::Triple::aarch64_be:
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004305 LibDir = "lib";
4306 Loader = "ld-linux-aarch64_be.so.1";
4307 break;
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004308 case llvm::Triple::arm:
4309 case llvm::Triple::thumb:
4310 case llvm::Triple::armeb:
4311 case llvm::Triple::thumbeb: {
Vedant Kumarbf51e702016-07-18 19:56:38 +00004312 const bool HF = Triple.getEnvironment() == llvm::Triple::GNUEABIHF ||
4313 tools::arm::getARMFloatABI(*this, Triple, Args) ==
4314 tools::arm::FloatABI::Hard;
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004315
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004316 LibDir = "lib";
4317 Loader = HF ? "ld-linux-armhf.so.3" : "ld-linux.so.3";
4318 break;
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004319 }
4320 case llvm::Triple::mips:
4321 case llvm::Triple::mipsel:
4322 case llvm::Triple::mips64:
4323 case llvm::Triple::mips64el: {
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004324 bool LE = (Triple.getArch() == llvm::Triple::mipsel) ||
4325 (Triple.getArch() == llvm::Triple::mips64el);
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004326 bool IsNaN2008 = tools::mips::isNaN2008(Args, Triple);
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004327
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004328 LibDir = "lib" + tools::mips::getMipsABILibSuffix(Args, Triple);
4329
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004330 if (tools::mips::isUCLibc(Args))
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004331 Loader = IsNaN2008 ? "ld-uClibc-mipsn8.so.0" : "ld-uClibc.so.0";
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004332 else if (!Triple.hasEnvironment() &&
4333 Triple.getVendor() == llvm::Triple::VendorType::MipsTechnologies)
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004334 Loader = LE ? "ld-musl-mipsel.so.1" : "ld-musl-mips.so.1";
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004335 else
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004336 Loader = IsNaN2008 ? "ld-linux-mipsn8.so.1" : "ld.so.1";
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004337
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004338 break;
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004339 }
4340 case llvm::Triple::ppc:
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004341 LibDir = "lib";
4342 Loader = "ld.so.1";
4343 break;
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004344 case llvm::Triple::ppc64:
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004345 LibDir = "lib64";
4346 Loader =
4347 (tools::ppc::hasPPCAbiArg(Args, "elfv2")) ? "ld64.so.2" : "ld64.so.1";
4348 break;
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004349 case llvm::Triple::ppc64le:
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004350 LibDir = "lib64";
4351 Loader =
4352 (tools::ppc::hasPPCAbiArg(Args, "elfv1")) ? "ld64.so.1" : "ld64.so.2";
4353 break;
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004354 case llvm::Triple::sparc:
4355 case llvm::Triple::sparcel:
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004356 LibDir = "lib";
4357 Loader = "ld-linux.so.2";
4358 break;
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004359 case llvm::Triple::sparcv9:
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004360 LibDir = "lib64";
4361 Loader = "ld-linux.so.2";
4362 break;
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004363 case llvm::Triple::systemz:
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004364 LibDir = "lib";
4365 Loader = "ld64.so.1";
4366 break;
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004367 case llvm::Triple::x86:
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004368 LibDir = "lib";
4369 Loader = "ld-linux.so.2";
4370 break;
4371 case llvm::Triple::x86_64: {
4372 bool X32 = Triple.getEnvironment() == llvm::Triple::GNUX32;
4373
4374 LibDir = X32 ? "libx32" : "lib64";
4375 Loader = X32 ? "ld-linux-x32.so.2" : "ld-linux-x86-64.so.2";
4376 break;
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004377 }
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004378 }
4379
4380 if (Distro == Exherbo && (Triple.getVendor() == llvm::Triple::UnknownVendor ||
4381 Triple.getVendor() == llvm::Triple::PC))
4382 return "/usr/" + Triple.str() + "/lib/" + Loader;
4383 return "/" + LibDir + "/" + Loader;
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004384}
4385
Chandler Carrutha796f532011-11-05 20:17:13 +00004386void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
4387 ArgStringList &CC1Args) const {
4388 const Driver &D = getDriver();
Simon Atanasyana0d89572013-10-05 14:37:55 +00004389 std::string SysRoot = computeSysRoot();
Chandler Carrutha796f532011-11-05 20:17:13 +00004390
4391 if (DriverArgs.hasArg(options::OPT_nostdinc))
4392 return;
4393
4394 if (!DriverArgs.hasArg(options::OPT_nostdlibinc))
Simon Atanasyan08450bd2013-04-20 08:15:03 +00004395 addSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/local/include");
Chandler Carrutha796f532011-11-05 20:17:13 +00004396
4397 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
Rafael Espindola358256c2013-06-26 02:13:00 +00004398 SmallString<128> P(D.ResourceDir);
4399 llvm::sys::path::append(P, "include");
Yaron Keren92e1b622015-03-18 10:17:07 +00004400 addSystemInclude(DriverArgs, CC1Args, P);
Chandler Carrutha796f532011-11-05 20:17:13 +00004401 }
4402
4403 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
4404 return;
4405
4406 // Check for configure-time C include directories.
4407 StringRef CIncludeDirs(C_INCLUDE_DIRS);
4408 if (CIncludeDirs != "") {
4409 SmallVector<StringRef, 5> dirs;
4410 CIncludeDirs.split(dirs, ":");
Simon Atanasyan6f657c42014-05-08 19:32:46 +00004411 for (StringRef dir : dirs) {
Benjamin Kramer33cd6dc2015-02-18 18:45:54 +00004412 StringRef Prefix =
4413 llvm::sys::path::is_absolute(dir) ? StringRef(SysRoot) : "";
Simon Atanasyan6f657c42014-05-08 19:32:46 +00004414 addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir);
Chandler Carrutha796f532011-11-05 20:17:13 +00004415 }
4416 return;
4417 }
4418
4419 // Lacking those, try to detect the correct set of system includes for the
4420 // target triple.
4421
Simon Atanasyan9e49e142014-08-06 05:44:47 +00004422 // Add include directories specific to the selected multilib set and multilib.
4423 if (GCCInstallation.isValid()) {
Benjamin Kramerac75baa2015-03-22 15:56:12 +00004424 const auto &Callback = Multilibs.includeDirsCallback();
Simon Atanasyan9e49e142014-08-06 05:44:47 +00004425 if (Callback) {
Simon Atanasyana45502d2016-05-19 15:07:21 +00004426 for (const auto &Path : Callback(GCCInstallation.getMultilib()))
4427 addExternCSystemIncludeIfExists(
4428 DriverArgs, CC1Args, GCCInstallation.getInstallPath() + Path);
Simon Atanasyan9e49e142014-08-06 05:44:47 +00004429 }
Simon Atanasyan08450bd2013-04-20 08:15:03 +00004430 }
4431
Chandler Carruth5b77c6c2011-11-06 08:21:07 +00004432 // Implement generic Debian multiarch support.
4433 const StringRef X86_64MultiarchIncludeDirs[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004434 "/usr/include/x86_64-linux-gnu",
Chandler Carruth5b77c6c2011-11-06 08:21:07 +00004435
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004436 // FIXME: These are older forms of multiarch. It's not clear that they're
4437 // in use in any released version of Debian, so we should consider
4438 // removing them.
4439 "/usr/include/i686-linux-gnu/64", "/usr/include/i486-linux-gnu/64"};
Chandler Carruth5b77c6c2011-11-06 08:21:07 +00004440 const StringRef X86MultiarchIncludeDirs[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004441 "/usr/include/i386-linux-gnu",
Chandler Carruth5b77c6c2011-11-06 08:21:07 +00004442
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004443 // FIXME: These are older forms of multiarch. It's not clear that they're
4444 // in use in any released version of Debian, so we should consider
4445 // removing them.
4446 "/usr/include/x86_64-linux-gnu/32", "/usr/include/i686-linux-gnu",
4447 "/usr/include/i486-linux-gnu"};
Tim Northover9bb857a2013-01-31 12:13:10 +00004448 const StringRef AArch64MultiarchIncludeDirs[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004449 "/usr/include/aarch64-linux-gnu"};
Chandler Carruth5b77c6c2011-11-06 08:21:07 +00004450 const StringRef ARMMultiarchIncludeDirs[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004451 "/usr/include/arm-linux-gnueabi"};
Jiangning Liu61b06cb2012-07-31 08:06:29 +00004452 const StringRef ARMHFMultiarchIncludeDirs[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004453 "/usr/include/arm-linux-gnueabihf"};
Saleem Abdulrasool20f733a2015-12-11 06:20:59 +00004454 const StringRef ARMEBMultiarchIncludeDirs[] = {
4455 "/usr/include/armeb-linux-gnueabi"};
4456 const StringRef ARMEBHFMultiarchIncludeDirs[] = {
4457 "/usr/include/armeb-linux-gnueabihf"};
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004458 const StringRef MIPSMultiarchIncludeDirs[] = {"/usr/include/mips-linux-gnu"};
Eli Friedman7771c832011-11-11 03:05:19 +00004459 const StringRef MIPSELMultiarchIncludeDirs[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004460 "/usr/include/mipsel-linux-gnu"};
Simon Atanasyan3a46afa2014-06-24 19:00:12 +00004461 const StringRef MIPS64MultiarchIncludeDirs[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004462 "/usr/include/mips64-linux-gnu", "/usr/include/mips64-linux-gnuabi64"};
Simon Atanasyan3a46afa2014-06-24 19:00:12 +00004463 const StringRef MIPS64ELMultiarchIncludeDirs[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004464 "/usr/include/mips64el-linux-gnu",
4465 "/usr/include/mips64el-linux-gnuabi64"};
Chandler Carruth2e9d7312012-02-26 09:21:43 +00004466 const StringRef PPCMultiarchIncludeDirs[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004467 "/usr/include/powerpc-linux-gnu"};
Chandler Carruth2e9d7312012-02-26 09:21:43 +00004468 const StringRef PPC64MultiarchIncludeDirs[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004469 "/usr/include/powerpc64-linux-gnu"};
Ulrich Weiganda8331b92014-06-20 13:41:24 +00004470 const StringRef PPC64LEMultiarchIncludeDirs[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004471 "/usr/include/powerpc64le-linux-gnu"};
James Y Knight09677ad2015-06-05 13:44:43 +00004472 const StringRef SparcMultiarchIncludeDirs[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004473 "/usr/include/sparc-linux-gnu"};
James Y Knight09677ad2015-06-05 13:44:43 +00004474 const StringRef Sparc64MultiarchIncludeDirs[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004475 "/usr/include/sparc64-linux-gnu"};
Sylvestre Ledruc0babf22015-08-28 12:26:09 +00004476 const StringRef SYSTEMZMultiarchIncludeDirs[] = {
4477 "/usr/include/s390x-linux-gnu"};
Chandler Carruth5b77c6c2011-11-06 08:21:07 +00004478 ArrayRef<StringRef> MultiarchIncludeDirs;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00004479 switch (getTriple().getArch()) {
4480 case llvm::Triple::x86_64:
Chandler Carruth5b77c6c2011-11-06 08:21:07 +00004481 MultiarchIncludeDirs = X86_64MultiarchIncludeDirs;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00004482 break;
4483 case llvm::Triple::x86:
Chandler Carruth5b77c6c2011-11-06 08:21:07 +00004484 MultiarchIncludeDirs = X86MultiarchIncludeDirs;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00004485 break;
4486 case llvm::Triple::aarch64:
4487 case llvm::Triple::aarch64_be:
Tim Northover9bb857a2013-01-31 12:13:10 +00004488 MultiarchIncludeDirs = AArch64MultiarchIncludeDirs;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00004489 break;
4490 case llvm::Triple::arm:
Saleem Abdulrasool20f733a2015-12-11 06:20:59 +00004491 case llvm::Triple::thumb:
Jiangning Liu61b06cb2012-07-31 08:06:29 +00004492 if (getTriple().getEnvironment() == llvm::Triple::GNUEABIHF)
4493 MultiarchIncludeDirs = ARMHFMultiarchIncludeDirs;
4494 else
4495 MultiarchIncludeDirs = ARMMultiarchIncludeDirs;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00004496 break;
Saleem Abdulrasool20f733a2015-12-11 06:20:59 +00004497 case llvm::Triple::armeb:
4498 case llvm::Triple::thumbeb:
4499 if (getTriple().getEnvironment() == llvm::Triple::GNUEABIHF)
4500 MultiarchIncludeDirs = ARMEBHFMultiarchIncludeDirs;
4501 else
4502 MultiarchIncludeDirs = ARMEBMultiarchIncludeDirs;
4503 break;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00004504 case llvm::Triple::mips:
Eli Friedman7771c832011-11-11 03:05:19 +00004505 MultiarchIncludeDirs = MIPSMultiarchIncludeDirs;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00004506 break;
4507 case llvm::Triple::mipsel:
Eli Friedman7771c832011-11-11 03:05:19 +00004508 MultiarchIncludeDirs = MIPSELMultiarchIncludeDirs;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00004509 break;
4510 case llvm::Triple::mips64:
Simon Atanasyan3a46afa2014-06-24 19:00:12 +00004511 MultiarchIncludeDirs = MIPS64MultiarchIncludeDirs;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00004512 break;
4513 case llvm::Triple::mips64el:
Simon Atanasyan3a46afa2014-06-24 19:00:12 +00004514 MultiarchIncludeDirs = MIPS64ELMultiarchIncludeDirs;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00004515 break;
4516 case llvm::Triple::ppc:
Chandler Carruth2e9d7312012-02-26 09:21:43 +00004517 MultiarchIncludeDirs = PPCMultiarchIncludeDirs;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00004518 break;
4519 case llvm::Triple::ppc64:
Chandler Carruth2e9d7312012-02-26 09:21:43 +00004520 MultiarchIncludeDirs = PPC64MultiarchIncludeDirs;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00004521 break;
4522 case llvm::Triple::ppc64le:
Ulrich Weiganda8331b92014-06-20 13:41:24 +00004523 MultiarchIncludeDirs = PPC64LEMultiarchIncludeDirs;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00004524 break;
4525 case llvm::Triple::sparc:
James Y Knight09677ad2015-06-05 13:44:43 +00004526 MultiarchIncludeDirs = SparcMultiarchIncludeDirs;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00004527 break;
4528 case llvm::Triple::sparcv9:
James Y Knight09677ad2015-06-05 13:44:43 +00004529 MultiarchIncludeDirs = Sparc64MultiarchIncludeDirs;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00004530 break;
Sylvestre Ledruc0babf22015-08-28 12:26:09 +00004531 case llvm::Triple::systemz:
4532 MultiarchIncludeDirs = SYSTEMZMultiarchIncludeDirs;
4533 break;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00004534 default:
4535 break;
Chandler Carruth5b77c6c2011-11-06 08:21:07 +00004536 }
Simon Atanasyan6f657c42014-05-08 19:32:46 +00004537 for (StringRef Dir : MultiarchIncludeDirs) {
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004538 if (D.getVFS().exists(SysRoot + Dir)) {
Simon Atanasyan6f657c42014-05-08 19:32:46 +00004539 addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + Dir);
Chandler Carruth5b77c6c2011-11-06 08:21:07 +00004540 break;
4541 }
Chandler Carrutha796f532011-11-05 20:17:13 +00004542 }
4543
4544 if (getTriple().getOS() == llvm::Triple::RTEMS)
4545 return;
4546
Chandler Carruth475ab6a2011-11-08 17:19:47 +00004547 // Add an include of '/include' directly. This isn't provided by default by
4548 // system GCCs, but is often used with cross-compiling GCCs, and harmless to
4549 // add even when Clang is acting as-if it were a system compiler.
Simon Atanasyan08450bd2013-04-20 08:15:03 +00004550 addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/include");
Chandler Carruth475ab6a2011-11-08 17:19:47 +00004551
Simon Atanasyan08450bd2013-04-20 08:15:03 +00004552 addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include");
Chandler Carrutha796f532011-11-05 20:17:13 +00004553}
4554
Evgeniy Stepanov65bc2b12015-11-09 21:10:54 +00004555static std::string DetectLibcxxIncludePath(StringRef base) {
4556 std::error_code EC;
4557 int MaxVersion = 0;
4558 std::string MaxVersionString = "";
4559 for (llvm::sys::fs::directory_iterator LI(base, EC), LE; !EC && LI != LE;
4560 LI = LI.increment(EC)) {
4561 StringRef VersionText = llvm::sys::path::filename(LI->path());
4562 int Version;
4563 if (VersionText[0] == 'v' &&
4564 !VersionText.slice(1, StringRef::npos).getAsInteger(10, Version)) {
4565 if (Version > MaxVersion) {
4566 MaxVersion = Version;
4567 MaxVersionString = VersionText;
4568 }
4569 }
4570 }
4571 return MaxVersion ? (base + "/" + MaxVersionString).str() : "";
4572}
4573
Chandler Carrutha796f532011-11-05 20:17:13 +00004574void Linux::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
4575 ArgStringList &CC1Args) const {
4576 if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
4577 DriverArgs.hasArg(options::OPT_nostdincxx))
4578 return;
4579
Chandler Carruthf4701732011-11-07 09:01:17 +00004580 // Check if libc++ has been enabled and provide its include paths if so.
4581 if (GetCXXStdlibType(DriverArgs) == ToolChain::CST_Libcxx) {
Chandler Carruth5a3d8982014-01-20 09:42:24 +00004582 const std::string LibCXXIncludePathCandidates[] = {
Evgeniy Stepanov65bc2b12015-11-09 21:10:54 +00004583 DetectLibcxxIncludePath(getDriver().Dir + "/../include/c++"),
Yaron Keren5439b642016-05-17 19:01:16 +00004584 // If this is a development, non-installed, clang, libcxx will
4585 // not be found at ../include/c++ but it likely to be found at
4586 // one of the following two locations:
4587 DetectLibcxxIncludePath(getDriver().SysRoot + "/usr/local/include/c++"),
4588 DetectLibcxxIncludePath(getDriver().SysRoot + "/usr/include/c++") };
Simon Atanasyan6f657c42014-05-08 19:32:46 +00004589 for (const auto &IncludePath : LibCXXIncludePathCandidates) {
Evgeniy Stepanov65bc2b12015-11-09 21:10:54 +00004590 if (IncludePath.empty() || !getVFS().exists(IncludePath))
Chandler Carruth5a3d8982014-01-20 09:42:24 +00004591 continue;
4592 // Add the first candidate that exists.
Simon Atanasyan6f657c42014-05-08 19:32:46 +00004593 addSystemInclude(DriverArgs, CC1Args, IncludePath);
Chandler Carruth5a3d8982014-01-20 09:42:24 +00004594 break;
4595 }
Chandler Carruthf4701732011-11-07 09:01:17 +00004596 return;
4597 }
4598
Chandler Carrutha1f1fd32012-01-25 08:04:13 +00004599 // We need a detected GCC installation on Linux to provide libstdc++'s
4600 // headers. We handled the libc++ case above.
4601 if (!GCCInstallation.isValid())
4602 return;
Chandler Carrutha796f532011-11-05 20:17:13 +00004603
Chandler Carruthf5d4df92011-11-06 10:31:01 +00004604 // By default, look for the C++ headers in an include directory adjacent to
4605 // the lib directory of the GCC installation. Note that this is expect to be
4606 // equivalent to '/usr/include/c++/X.Y' in almost all cases.
4607 StringRef LibDir = GCCInstallation.getParentLibPath();
4608 StringRef InstallDir = GCCInstallation.getInstallPath();
Evgeniy Stepanov763671e2012-09-03 09:05:50 +00004609 StringRef TripleStr = GCCInstallation.getTriple().str();
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00004610 const Multilib &Multilib = GCCInstallation.getMultilib();
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004611 const std::string GCCMultiarchTriple = getMultiarchTriple(
4612 getDriver(), GCCInstallation.getTriple(), getDriver().SysRoot);
Chandler Carruthc44f4d42014-08-27 08:41:41 +00004613 const std::string TargetMultiarchTriple =
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004614 getMultiarchTriple(getDriver(), getTriple(), getDriver().SysRoot);
Chandler Carruth1f2b2f82013-08-26 08:59:53 +00004615 const GCCVersion &Version = GCCInstallation.getVersion();
Evgeniy Stepanov763671e2012-09-03 09:05:50 +00004616
Chandler Carruthc44f4d42014-08-27 08:41:41 +00004617 // The primary search for libstdc++ supports multiarch variants.
Chandler Carruth8677d922013-10-29 08:53:03 +00004618 if (addLibStdCXXIncludePaths(LibDir.str() + "/../include",
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004619 "/c++/" + Version.Text, TripleStr,
4620 GCCMultiarchTriple, TargetMultiarchTriple,
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00004621 Multilib.includeSuffix(), DriverArgs, CC1Args))
Dmitri Gribenko15225ae2013-03-06 17:14:05 +00004622 return;
4623
Chandler Carruthc44f4d42014-08-27 08:41:41 +00004624 // Otherwise, fall back on a bunch of options which don't use multiarch
4625 // layouts for simplicity.
Chandler Carruth5a3d8982014-01-20 09:42:24 +00004626 const std::string LibStdCXXIncludePathCandidates[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004627 // Gentoo is weird and places its headers inside the GCC install,
4628 // so if the first attempt to find the headers fails, try these patterns.
Chandler Carruth81296fb2016-05-08 07:59:56 +00004629 InstallDir.str() + "/include/g++-v" + Version.Text,
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004630 InstallDir.str() + "/include/g++-v" + Version.MajorStr + "." +
4631 Version.MinorStr,
4632 InstallDir.str() + "/include/g++-v" + Version.MajorStr,
4633 // Android standalone toolchain has C++ headers in yet another place.
4634 LibDir.str() + "/../" + TripleStr.str() + "/include/c++/" + Version.Text,
4635 // Freescale SDK C++ headers are directly in <sysroot>/usr/include/c++,
4636 // without a subdirectory corresponding to the gcc version.
4637 LibDir.str() + "/../include/c++",
Evgeniy Stepanov763671e2012-09-03 09:05:50 +00004638 };
4639
Simon Atanasyan6f657c42014-05-08 19:32:46 +00004640 for (const auto &IncludePath : LibStdCXXIncludePathCandidates) {
Chandler Carruthc44f4d42014-08-27 08:41:41 +00004641 if (addLibStdCXXIncludePaths(IncludePath, /*Suffix*/ "", TripleStr,
4642 /*GCCMultiarchTriple*/ "",
4643 /*TargetMultiarchTriple*/ "",
4644 Multilib.includeSuffix(), DriverArgs, CC1Args))
Evgeniy Stepanov763671e2012-09-03 09:05:50 +00004645 break;
Chandler Carruthf5d4df92011-11-06 10:31:01 +00004646 }
Chandler Carrutha796f532011-11-05 20:17:13 +00004647}
4648
Artem Belevichfa11ab52015-11-17 22:28:46 +00004649void Linux::AddCudaIncludeArgs(const ArgList &DriverArgs,
4650 ArgStringList &CC1Args) const {
4651 if (DriverArgs.hasArg(options::OPT_nocudainc))
4652 return;
4653
Justin Lebar423019d2016-04-16 00:11:11 +00004654 if (!CudaInstallation.isValid()) {
4655 getDriver().Diag(diag::err_drv_no_cuda_installation);
4656 return;
Artem Belevich86017332015-11-17 22:28:55 +00004657 }
Justin Lebar423019d2016-04-16 00:11:11 +00004658
4659 addSystemInclude(DriverArgs, CC1Args, CudaInstallation.getIncludePath());
4660 CC1Args.push_back("-include");
4661 CC1Args.push_back("__clang_cuda_runtime_wrapper.h");
Artem Belevichfa11ab52015-11-17 22:28:46 +00004662}
4663
Andrey Turetskiy4798eb62016-06-16 10:36:09 +00004664void Linux::AddIAMCUIncludeArgs(const ArgList &DriverArgs,
4665 ArgStringList &CC1Args) const {
4666 if (GCCInstallation.isValid()) {
4667 CC1Args.push_back("-isystem");
4668 CC1Args.push_back(DriverArgs.MakeArgString(
4669 GCCInstallation.getParentLibPath() + "/../" +
4670 GCCInstallation.getTriple().str() + "/include"));
4671 }
4672}
4673
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004674bool Linux::isPIEDefault() const { return getSanitizerArgs().requiresPIE(); }
Peter Collingbourne54d770c2013-04-09 04:35:11 +00004675
Alexey Samsonov7f2a0d22015-06-19 21:36:47 +00004676SanitizerMask Linux::getSupportedSanitizers() const {
4677 const bool IsX86 = getTriple().getArch() == llvm::Triple::x86;
4678 const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64;
4679 const bool IsMIPS64 = getTriple().getArch() == llvm::Triple::mips64 ||
4680 getTriple().getArch() == llvm::Triple::mips64el;
Jay Foade967dd02015-06-25 10:35:19 +00004681 const bool IsPowerPC64 = getTriple().getArch() == llvm::Triple::ppc64 ||
4682 getTriple().getArch() == llvm::Triple::ppc64le;
Adhemerval Zanella76aee672015-07-30 20:50:39 +00004683 const bool IsAArch64 = getTriple().getArch() == llvm::Triple::aarch64 ||
4684 getTriple().getArch() == llvm::Triple::aarch64_be;
Alexey Samsonov7f2a0d22015-06-19 21:36:47 +00004685 SanitizerMask Res = ToolChain::getSupportedSanitizers();
4686 Res |= SanitizerKind::Address;
4687 Res |= SanitizerKind::KernelAddress;
4688 Res |= SanitizerKind::Vptr;
Evgeniy Stepanov299238a2015-09-24 17:22:46 +00004689 Res |= SanitizerKind::SafeStack;
Adhemerval Zanella76aee672015-07-30 20:50:39 +00004690 if (IsX86_64 || IsMIPS64 || IsAArch64)
Alexey Samsonov7f2a0d22015-06-19 21:36:47 +00004691 Res |= SanitizerKind::DataFlow;
Adhemerval Zanellabffb20d2015-10-05 19:16:42 +00004692 if (IsX86_64 || IsMIPS64 || IsAArch64)
Alexey Samsonov7f2a0d22015-06-19 21:36:47 +00004693 Res |= SanitizerKind::Leak;
Bill Schmidt4b8841a2015-12-08 22:48:02 +00004694 if (IsX86_64 || IsMIPS64 || IsAArch64 || IsPowerPC64)
Alexey Samsonov7f2a0d22015-06-19 21:36:47 +00004695 Res |= SanitizerKind::Thread;
Adhemerval Zanella567b9262015-09-16 15:11:21 +00004696 if (IsX86_64 || IsMIPS64 || IsPowerPC64 || IsAArch64)
Jay Foade967dd02015-06-25 10:35:19 +00004697 Res |= SanitizerKind::Memory;
Derek Bruening256c2e12016-04-21 21:32:04 +00004698 if (IsX86_64)
4699 Res |= SanitizerKind::Efficiency;
Alexey Samsonov7f2a0d22015-06-19 21:36:47 +00004700 if (IsX86 || IsX86_64) {
4701 Res |= SanitizerKind::Function;
Alexey Samsonov7f2a0d22015-06-19 21:36:47 +00004702 }
4703 return Res;
4704}
4705
Vedant Kumarbf51e702016-07-18 19:56:38 +00004706void Linux::addProfileRTLibs(const llvm::Triple &EffectiveTriple,
4707 const llvm::opt::ArgList &Args,
Xinliang David Li170cd102015-10-27 05:15:35 +00004708 llvm::opt::ArgStringList &CmdArgs) const {
Vedant Kumarbf51e702016-07-18 19:56:38 +00004709 if (!needsProfileRT(Args))
4710 return;
Xinliang David Li170cd102015-10-27 05:15:35 +00004711
4712 // Add linker option -u__llvm_runtime_variable to cause runtime
4713 // initialization module to be linked in.
4714 if (!Args.hasArg(options::OPT_coverage))
4715 CmdArgs.push_back(Args.MakeArgString(
4716 Twine("-u", llvm::getInstrProfRuntimeHookVarName())));
Vedant Kumarbf51e702016-07-18 19:56:38 +00004717 ToolChain::addProfileRTLibs(EffectiveTriple, Args, CmdArgs);
Xinliang David Li170cd102015-10-27 05:15:35 +00004718}
4719
Daniel Dunbarcc912342009-05-02 18:28:39 +00004720/// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly.
4721
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004722DragonFly::DragonFly(const Driver &D, const llvm::Triple &Triple,
4723 const ArgList &Args)
4724 : Generic_ELF(D, Triple, Args) {
Daniel Dunbarcc912342009-05-02 18:28:39 +00004725
4726 // Path mangling to find libexec
Daniel Dunbar88979912010-08-01 22:29:51 +00004727 getProgramPaths().push_back(getDriver().getInstalledDir());
Benjamin Kramer51477bd2011-03-01 22:50:47 +00004728 if (getDriver().getInstalledDir() != getDriver().Dir)
Daniel Dunbar88979912010-08-01 22:29:51 +00004729 getProgramPaths().push_back(getDriver().Dir);
Daniel Dunbarcc912342009-05-02 18:28:39 +00004730
Daniel Dunbar083edf72009-12-21 18:54:17 +00004731 getFilePaths().push_back(getDriver().Dir + "/../lib");
Daniel Dunbarcc912342009-05-02 18:28:39 +00004732 getFilePaths().push_back("/usr/lib");
Dimitry Andricf59a2b32015-12-27 10:01:44 +00004733 getFilePaths().push_back("/usr/lib/gcc50");
Daniel Dunbarcc912342009-05-02 18:28:39 +00004734}
4735
Rafael Espindola7cf32212013-03-20 03:05:54 +00004736Tool *DragonFly::buildAssembler() const {
Douglas Katzman95354292015-06-23 20:42:09 +00004737 return new tools::dragonfly::Assembler(*this);
Rafael Espindola7cf32212013-03-20 03:05:54 +00004738}
4739
4740Tool *DragonFly::buildLinker() const {
Douglas Katzman95354292015-06-23 20:42:09 +00004741 return new tools::dragonfly::Linker(*this);
Daniel Dunbarcc912342009-05-02 18:28:39 +00004742}
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004743
Justin Lebar21e5d4f2016-01-14 21:41:27 +00004744/// CUDA toolchain. Our assembler is ptxas, and our "linker" is fatbinary,
4745/// which isn't properly a linker but nonetheless performs the step of stitching
4746/// together object files from the assembler into a single blob.
Artem Belevich0ff05cd2015-07-13 23:27:56 +00004747
4748CudaToolChain::CudaToolChain(const Driver &D, const llvm::Triple &Triple,
4749 const ArgList &Args)
Justin Lebar21e5d4f2016-01-14 21:41:27 +00004750 : Linux(D, Triple, Args) {
4751 if (CudaInstallation.isValid())
4752 getProgramPaths().push_back(CudaInstallation.getBinPath());
4753}
Artem Belevich0ff05cd2015-07-13 23:27:56 +00004754
4755void
4756CudaToolChain::addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
4757 llvm::opt::ArgStringList &CC1Args) const {
4758 Linux::addClangTargetOptions(DriverArgs, CC1Args);
4759 CC1Args.push_back("-fcuda-is-device");
Artem Belevich34f481a2015-11-17 22:28:50 +00004760
Justin Lebard3a44f62016-04-05 18:26:20 +00004761 if (DriverArgs.hasFlag(options::OPT_fcuda_flush_denormals_to_zero,
4762 options::OPT_fno_cuda_flush_denormals_to_zero, false))
4763 CC1Args.push_back("-fcuda-flush-denormals-to-zero");
4764
Justin Lebar91f6f072016-05-23 20:19:56 +00004765 if (DriverArgs.hasFlag(options::OPT_fcuda_approx_transcendentals,
4766 options::OPT_fno_cuda_approx_transcendentals, false))
4767 CC1Args.push_back("-fcuda-approx-transcendentals");
4768
Artem Belevich34f481a2015-11-17 22:28:50 +00004769 if (DriverArgs.hasArg(options::OPT_nocudalib))
4770 return;
4771
4772 std::string LibDeviceFile = CudaInstallation.getLibDeviceFile(
4773 DriverArgs.getLastArgValue(options::OPT_march_EQ));
4774 if (!LibDeviceFile.empty()) {
4775 CC1Args.push_back("-mlink-cuda-bitcode");
4776 CC1Args.push_back(DriverArgs.MakeArgString(LibDeviceFile));
4777
4778 // Libdevice in CUDA-7.0 requires PTX version that's more recent
4779 // than LLVM defaults to. Use PTX4.2 which is the PTX version that
4780 // came with CUDA-7.0.
4781 CC1Args.push_back("-target-feature");
4782 CC1Args.push_back("+ptx42");
4783 }
Artem Belevich0ff05cd2015-07-13 23:27:56 +00004784}
4785
Justin Lebarc43ad9e2016-07-07 18:17:52 +00004786void CudaToolChain::AddCudaIncludeArgs(const ArgList &DriverArgs,
4787 ArgStringList &CC1Args) const {
4788 // Check our CUDA version if we're going to include the CUDA headers.
4789 if (!DriverArgs.hasArg(options::OPT_nocudainc) &&
Justin Lebarf3997712016-07-07 18:24:28 +00004790 !DriverArgs.hasArg(options::OPT_no_cuda_version_check)) {
Justin Lebarc43ad9e2016-07-07 18:17:52 +00004791 StringRef Arch = DriverArgs.getLastArgValue(options::OPT_march_EQ);
4792 assert(!Arch.empty() && "Must have an explicit GPU arch.");
4793 CudaInstallation.CheckCudaVersionSupportsArch(StringToCudaArch(Arch));
4794 }
4795 Linux::AddCudaIncludeArgs(DriverArgs, CC1Args);
4796}
4797
Artem Belevich0ff05cd2015-07-13 23:27:56 +00004798llvm::opt::DerivedArgList *
4799CudaToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args,
4800 const char *BoundArch) const {
4801 DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
4802 const OptTable &Opts = getDriver().getOpts();
4803
4804 for (Arg *A : Args) {
4805 if (A->getOption().matches(options::OPT_Xarch__)) {
4806 // Skip this argument unless the architecture matches BoundArch
Justin Lebar21e5d4f2016-01-14 21:41:27 +00004807 if (!BoundArch || A->getValue(0) != StringRef(BoundArch))
Artem Belevich0ff05cd2015-07-13 23:27:56 +00004808 continue;
4809
4810 unsigned Index = Args.getBaseArgs().MakeIndex(A->getValue(1));
4811 unsigned Prev = Index;
4812 std::unique_ptr<Arg> XarchArg(Opts.ParseOneArg(Args, Index));
4813
4814 // If the argument parsing failed or more than one argument was
4815 // consumed, the -Xarch_ argument's parameter tried to consume
4816 // extra arguments. Emit an error and ignore.
4817 //
4818 // We also want to disallow any options which would alter the
4819 // driver behavior; that isn't going to work in our model. We
4820 // use isDriverOption() as an approximation, although things
4821 // like -O4 are going to slip through.
4822 if (!XarchArg || Index > Prev + 1) {
4823 getDriver().Diag(diag::err_drv_invalid_Xarch_argument_with_args)
4824 << A->getAsString(Args);
4825 continue;
4826 } else if (XarchArg->getOption().hasFlag(options::DriverOption)) {
4827 getDriver().Diag(diag::err_drv_invalid_Xarch_argument_isdriver)
4828 << A->getAsString(Args);
4829 continue;
4830 }
4831 XarchArg->setBaseArg(A);
4832 A = XarchArg.release();
4833 DAL->AddSynthesizedArg(A);
4834 }
4835 DAL->append(A);
4836 }
4837
Justin Lebar4db224e2016-06-15 23:46:11 +00004838 if (BoundArch) {
4839 DAL->eraseArg(options::OPT_march_EQ);
Justin Lebar21e5d4f2016-01-14 21:41:27 +00004840 DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_march_EQ), BoundArch);
Justin Lebar4db224e2016-06-15 23:46:11 +00004841 }
Artem Belevich0ff05cd2015-07-13 23:27:56 +00004842 return DAL;
4843}
4844
Justin Lebar21e5d4f2016-01-14 21:41:27 +00004845Tool *CudaToolChain::buildAssembler() const {
4846 return new tools::NVPTX::Assembler(*this);
4847}
4848
4849Tool *CudaToolChain::buildLinker() const {
4850 return new tools::NVPTX::Linker(*this);
4851}
4852
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004853/// XCore tool chain
Douglas Katzman54366072015-07-27 16:53:08 +00004854XCoreToolChain::XCoreToolChain(const Driver &D, const llvm::Triple &Triple,
4855 const ArgList &Args)
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004856 : ToolChain(D, Triple, Args) {
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004857 // ProgramPaths are found via 'PATH' environment variable.
4858}
4859
Douglas Katzman54366072015-07-27 16:53:08 +00004860Tool *XCoreToolChain::buildAssembler() const {
Douglas Katzman95354292015-06-23 20:42:09 +00004861 return new tools::XCore::Assembler(*this);
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004862}
4863
Douglas Katzman54366072015-07-27 16:53:08 +00004864Tool *XCoreToolChain::buildLinker() const {
4865 return new tools::XCore::Linker(*this);
4866}
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004867
Douglas Katzman54366072015-07-27 16:53:08 +00004868bool XCoreToolChain::isPICDefault() const { return false; }
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004869
Douglas Katzman54366072015-07-27 16:53:08 +00004870bool XCoreToolChain::isPIEDefault() const { return false; }
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004871
Douglas Katzman54366072015-07-27 16:53:08 +00004872bool XCoreToolChain::isPICDefaultForced() const { return false; }
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004873
Douglas Katzman54366072015-07-27 16:53:08 +00004874bool XCoreToolChain::SupportsProfiling() const { return false; }
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004875
Douglas Katzman54366072015-07-27 16:53:08 +00004876bool XCoreToolChain::hasBlocksRuntime() const { return false; }
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004877
Douglas Katzman54366072015-07-27 16:53:08 +00004878void XCoreToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
4879 ArgStringList &CC1Args) const {
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004880 if (DriverArgs.hasArg(options::OPT_nostdinc) ||
4881 DriverArgs.hasArg(options::OPT_nostdlibinc))
4882 return;
4883 if (const char *cl_include_dir = getenv("XCC_C_INCLUDE_PATH")) {
4884 SmallVector<StringRef, 4> Dirs;
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004885 const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'};
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004886 StringRef(cl_include_dir).split(Dirs, StringRef(EnvPathSeparatorStr));
4887 ArrayRef<StringRef> DirVec(Dirs);
4888 addSystemIncludes(DriverArgs, CC1Args, DirVec);
4889 }
4890}
4891
Douglas Katzman54366072015-07-27 16:53:08 +00004892void XCoreToolChain::addClangTargetOptions(const ArgList &DriverArgs,
4893 ArgStringList &CC1Args) const {
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004894 CC1Args.push_back("-nostdsysteminc");
4895}
4896
Douglas Katzman54366072015-07-27 16:53:08 +00004897void XCoreToolChain::AddClangCXXStdlibIncludeArgs(
4898 const ArgList &DriverArgs, ArgStringList &CC1Args) const {
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004899 if (DriverArgs.hasArg(options::OPT_nostdinc) ||
Robert Lyttonf9710b32014-08-01 13:11:46 +00004900 DriverArgs.hasArg(options::OPT_nostdlibinc) ||
4901 DriverArgs.hasArg(options::OPT_nostdincxx))
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004902 return;
4903 if (const char *cl_include_dir = getenv("XCC_CPLUS_INCLUDE_PATH")) {
4904 SmallVector<StringRef, 4> Dirs;
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004905 const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'};
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004906 StringRef(cl_include_dir).split(Dirs, StringRef(EnvPathSeparatorStr));
4907 ArrayRef<StringRef> DirVec(Dirs);
4908 addSystemIncludes(DriverArgs, CC1Args, DirVec);
4909 }
4910}
4911
Douglas Katzman54366072015-07-27 16:53:08 +00004912void XCoreToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
4913 ArgStringList &CmdArgs) const {
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004914 // We don't output any lib args. This is handled by xcc.
4915}
Douglas Katzman84a75642015-06-19 14:55:19 +00004916
Douglas Katzmand6e597c2015-09-17 19:56:40 +00004917MyriadToolChain::MyriadToolChain(const Driver &D, const llvm::Triple &Triple,
4918 const ArgList &Args)
Douglas Katzman5eddc232016-05-09 19:09:59 +00004919 : Generic_ELF(D, Triple, Args) {
Douglas Katzmand6e597c2015-09-17 19:56:40 +00004920 // If a target of 'sparc-myriad-elf' is specified to clang, it wants to use
4921 // 'sparc-myriad--elf' (note the unknown OS) as the canonical triple.
4922 // This won't work to find gcc. Instead we give the installation detector an
4923 // extra triple, which is preferable to further hacks of the logic that at
4924 // present is based solely on getArch(). In particular, it would be wrong to
4925 // choose the myriad installation when targeting a non-myriad sparc install.
4926 switch (Triple.getArch()) {
4927 default:
Eric Christopherefef8ef2015-12-07 22:43:05 +00004928 D.Diag(diag::err_target_unsupported_arch) << Triple.getArchName()
4929 << "myriad";
Douglas Katzmand6e597c2015-09-17 19:56:40 +00004930 case llvm::Triple::sparc:
4931 case llvm::Triple::sparcel:
4932 case llvm::Triple::shave:
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004933 GCCInstallation.init(Triple, Args, {"sparc-myriad-elf"});
Douglas Katzmand6e597c2015-09-17 19:56:40 +00004934 }
Douglas Katzman674a3122015-11-18 16:24:46 +00004935
4936 if (GCCInstallation.isValid()) {
4937 // The contents of LibDir are independent of the version of gcc.
4938 // This contains libc, libg (a superset of libc), libm, libstdc++, libssp.
4939 SmallString<128> LibDir(GCCInstallation.getParentLibPath());
4940 if (Triple.getArch() == llvm::Triple::sparcel)
4941 llvm::sys::path::append(LibDir, "../sparc-myriad-elf/lib/le");
4942 else
4943 llvm::sys::path::append(LibDir, "../sparc-myriad-elf/lib");
4944 addPathIfExists(D, LibDir, getFilePaths());
4945
4946 // This directory contains crt{i,n,begin,end}.o as well as libgcc.
4947 // These files are tied to a particular version of gcc.
4948 SmallString<128> CompilerSupportDir(GCCInstallation.getInstallPath());
4949 // There are actually 4 choices: {le,be} x {fpu,nofpu}
4950 // but as this toolchain is for LEON sparc, it can assume FPU.
4951 if (Triple.getArch() == llvm::Triple::sparcel)
4952 llvm::sys::path::append(CompilerSupportDir, "le");
4953 addPathIfExists(D, CompilerSupportDir, getFilePaths());
4954 }
Douglas Katzmand6e597c2015-09-17 19:56:40 +00004955}
4956
Angel Garcia Gomez637d1e62015-10-20 13:23:58 +00004957MyriadToolChain::~MyriadToolChain() {}
Douglas Katzmand6e597c2015-09-17 19:56:40 +00004958
Douglas Katzmanb1278f32015-09-17 21:20:16 +00004959void MyriadToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
4960 ArgStringList &CC1Args) const {
4961 if (!DriverArgs.hasArg(options::OPT_nostdinc))
4962 addSystemInclude(DriverArgs, CC1Args, getDriver().SysRoot + "/include");
4963}
4964
Eric Christopherefef8ef2015-12-07 22:43:05 +00004965void MyriadToolChain::AddClangCXXStdlibIncludeArgs(
4966 const ArgList &DriverArgs, ArgStringList &CC1Args) const {
James Y Knighta6c9ee72015-10-16 18:46:26 +00004967 if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
4968 DriverArgs.hasArg(options::OPT_nostdincxx))
4969 return;
4970
4971 // Only libstdc++, for now.
4972 StringRef LibDir = GCCInstallation.getParentLibPath();
4973 const GCCVersion &Version = GCCInstallation.getVersion();
4974 StringRef TripleStr = GCCInstallation.getTriple().str();
4975 const Multilib &Multilib = GCCInstallation.getMultilib();
4976
Eric Christopherefef8ef2015-12-07 22:43:05 +00004977 addLibStdCXXIncludePaths(
4978 LibDir.str() + "/../" + TripleStr.str() + "/include/c++/" + Version.Text,
4979 "", TripleStr, "", "", Multilib.includeSuffix(), DriverArgs, CC1Args);
James Y Knighta6c9ee72015-10-16 18:46:26 +00004980}
4981
Douglas Katzmand6e597c2015-09-17 19:56:40 +00004982// MyriadToolChain handles several triples:
4983// {shave,sparc{,el}}-myriad-{rtems,unknown}-elf
4984Tool *MyriadToolChain::SelectTool(const JobAction &JA) const {
4985 // The inherited method works fine if not targeting the SHAVE.
4986 if (!isShaveCompilation(getTriple()))
4987 return ToolChain::SelectTool(JA);
Douglas Katzman84a75642015-06-19 14:55:19 +00004988 switch (JA.getKind()) {
Douglas Katzman9dc4c622015-11-20 04:58:12 +00004989 case Action::PreprocessJobClass:
Douglas Katzman84a75642015-06-19 14:55:19 +00004990 case Action::CompileJobClass:
4991 if (!Compiler)
Douglas Katzman95354292015-06-23 20:42:09 +00004992 Compiler.reset(new tools::SHAVE::Compiler(*this));
Douglas Katzman84a75642015-06-19 14:55:19 +00004993 return Compiler.get();
4994 case Action::AssembleJobClass:
4995 if (!Assembler)
Douglas Katzman95354292015-06-23 20:42:09 +00004996 Assembler.reset(new tools::SHAVE::Assembler(*this));
Douglas Katzman84a75642015-06-19 14:55:19 +00004997 return Assembler.get();
4998 default:
4999 return ToolChain::getTool(JA.getKind());
5000 }
5001}
5002
Douglas Katzmand6e597c2015-09-17 19:56:40 +00005003Tool *MyriadToolChain::buildLinker() const {
5004 return new tools::Myriad::Linker(*this);
Douglas Katzman84a75642015-06-19 14:55:19 +00005005}
Dan Gohmanc2853072015-09-03 22:51:53 +00005006
Dan Gohman52816862015-12-16 23:30:41 +00005007WebAssembly::WebAssembly(const Driver &D, const llvm::Triple &Triple,
5008 const llvm::opt::ArgList &Args)
5009 : ToolChain(D, Triple, Args) {
Dan Gohman57b62c52016-02-22 19:26:15 +00005010
5011 assert(Triple.isArch32Bit() != Triple.isArch64Bit());
5012 getFilePaths().push_back(
5013 getDriver().SysRoot + "/lib" + (Triple.isArch32Bit() ? "32" : "64"));
5014
Dan Gohman52816862015-12-16 23:30:41 +00005015 // Use LLD by default.
5016 DefaultLinker = "lld";
5017}
5018
Dan Gohmanc2853072015-09-03 22:51:53 +00005019bool WebAssembly::IsMathErrnoDefault() const { return false; }
5020
5021bool WebAssembly::IsObjCNonFragileABIDefault() const { return true; }
5022
5023bool WebAssembly::UseObjCMixedDispatch() const { return true; }
5024
5025bool WebAssembly::isPICDefault() const { return false; }
5026
5027bool WebAssembly::isPIEDefault() const { return false; }
5028
5029bool WebAssembly::isPICDefaultForced() const { return false; }
5030
5031bool WebAssembly::IsIntegratedAssemblerDefault() const { return true; }
5032
5033// TODO: Support Objective C stuff.
5034bool WebAssembly::SupportsObjCGC() const { return false; }
5035
5036bool WebAssembly::hasBlocksRuntime() const { return false; }
5037
5038// TODO: Support profiling.
5039bool WebAssembly::SupportsProfiling() const { return false; }
5040
Dan Gohman52816862015-12-16 23:30:41 +00005041bool WebAssembly::HasNativeLLVMSupport() const { return true; }
5042
Dan Gohmanc2853072015-09-03 22:51:53 +00005043void WebAssembly::addClangTargetOptions(const ArgList &DriverArgs,
5044 ArgStringList &CC1Args) const {
5045 if (DriverArgs.hasFlag(options::OPT_fuse_init_array,
5046 options::OPT_fno_use_init_array, true))
5047 CC1Args.push_back("-fuse-init-array");
5048}
Filipe Cabecinhasc888e192015-10-14 12:25:43 +00005049
Dan Gohman6ad8f612016-01-14 16:00:13 +00005050ToolChain::RuntimeLibType WebAssembly::GetDefaultRuntimeLibType() const {
5051 return ToolChain::RLT_CompilerRT;
5052}
5053
5054ToolChain::CXXStdlibType WebAssembly::GetCXXStdlibType(const ArgList &Args) const {
5055 return ToolChain::CST_Libcxx;
5056}
5057
5058void WebAssembly::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
5059 ArgStringList &CC1Args) const {
5060 if (!DriverArgs.hasArg(options::OPT_nostdinc))
5061 addSystemInclude(DriverArgs, CC1Args, getDriver().SysRoot + "/include");
5062}
5063
5064void WebAssembly::AddClangCXXStdlibIncludeArgs(
5065 const llvm::opt::ArgList &DriverArgs,
5066 llvm::opt::ArgStringList &CC1Args) const {
5067 if (!DriverArgs.hasArg(options::OPT_nostdlibinc) &&
5068 !DriverArgs.hasArg(options::OPT_nostdincxx))
5069 addSystemInclude(DriverArgs, CC1Args,
5070 getDriver().SysRoot + "/include/c++/v1");
5071}
5072
Dan Gohman52816862015-12-16 23:30:41 +00005073Tool *WebAssembly::buildLinker() const {
5074 return new tools::wasm::Linker(*this);
5075}
5076
Filipe Cabecinhasc888e192015-10-14 12:25:43 +00005077PS4CPU::PS4CPU(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
5078 : Generic_ELF(D, Triple, Args) {
5079 if (Args.hasArg(options::OPT_static))
5080 D.Diag(diag::err_drv_unsupported_opt_for_target) << "-static" << "PS4";
5081
Paul Robinson9d613612016-05-16 17:22:25 +00005082 // Determine where to find the PS4 libraries. We use SCE_ORBIS_SDK_DIR
Filipe Cabecinhasc888e192015-10-14 12:25:43 +00005083 // if it exists; otherwise use the driver's installation path, which
5084 // should be <SDK_DIR>/host_tools/bin.
5085
5086 SmallString<512> PS4SDKDir;
Paul Robinson9d613612016-05-16 17:22:25 +00005087 if (const char *EnvValue = getenv("SCE_ORBIS_SDK_DIR")) {
Filipe Cabecinhasc888e192015-10-14 12:25:43 +00005088 if (!llvm::sys::fs::exists(EnvValue))
5089 getDriver().Diag(clang::diag::warn_drv_ps4_sdk_dir) << EnvValue;
5090 PS4SDKDir = EnvValue;
5091 } else {
5092 PS4SDKDir = getDriver().Dir;
5093 llvm::sys::path::append(PS4SDKDir, "/../../");
Eric Christopherefef8ef2015-12-07 22:43:05 +00005094 }
Filipe Cabecinhasc888e192015-10-14 12:25:43 +00005095
Eric Christopherefef8ef2015-12-07 22:43:05 +00005096 // By default, the driver won't report a warning if it can't find
Filipe Cabecinhasc888e192015-10-14 12:25:43 +00005097 // PS4's include or lib directories. This behavior could be changed if
Eric Christopherefef8ef2015-12-07 22:43:05 +00005098 // -Weverything or -Winvalid-or-nonexistent-directory options are passed.
Filipe Cabecinhasc888e192015-10-14 12:25:43 +00005099 // If -isysroot was passed, use that as the SDK base path.
5100 std::string PrefixDir;
5101 if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
5102 PrefixDir = A->getValue();
5103 if (!llvm::sys::fs::exists(PrefixDir))
5104 getDriver().Diag(clang::diag::warn_missing_sysroot) << PrefixDir;
5105 } else
5106 PrefixDir = PS4SDKDir.str();
5107
5108 SmallString<512> PS4SDKIncludeDir(PrefixDir);
5109 llvm::sys::path::append(PS4SDKIncludeDir, "target/include");
5110 if (!Args.hasArg(options::OPT_nostdinc) &&
5111 !Args.hasArg(options::OPT_nostdlibinc) &&
5112 !Args.hasArg(options::OPT_isysroot) &&
5113 !Args.hasArg(options::OPT__sysroot_EQ) &&
5114 !llvm::sys::fs::exists(PS4SDKIncludeDir)) {
5115 getDriver().Diag(clang::diag::warn_drv_unable_to_find_directory_expected)
5116 << "PS4 system headers" << PS4SDKIncludeDir;
5117 }
5118
5119 SmallString<512> PS4SDKLibDir(PS4SDKDir);
5120 llvm::sys::path::append(PS4SDKLibDir, "target/lib");
5121 if (!Args.hasArg(options::OPT_nostdlib) &&
5122 !Args.hasArg(options::OPT_nodefaultlibs) &&
5123 !Args.hasArg(options::OPT__sysroot_EQ) && !Args.hasArg(options::OPT_E) &&
5124 !Args.hasArg(options::OPT_c) && !Args.hasArg(options::OPT_S) &&
5125 !Args.hasArg(options::OPT_emit_ast) &&
5126 !llvm::sys::fs::exists(PS4SDKLibDir)) {
5127 getDriver().Diag(clang::diag::warn_drv_unable_to_find_directory_expected)
5128 << "PS4 system libraries" << PS4SDKLibDir;
5129 return;
5130 }
5131 getFilePaths().push_back(PS4SDKLibDir.str());
5132}
5133
5134Tool *PS4CPU::buildAssembler() const {
5135 return new tools::PS4cpu::Assemble(*this);
5136}
5137
5138Tool *PS4CPU::buildLinker() const { return new tools::PS4cpu::Link(*this); }
5139
5140bool PS4CPU::isPICDefault() const { return true; }
5141
5142bool PS4CPU::HasNativeLLVMSupport() const { return true; }
5143
5144SanitizerMask PS4CPU::getSupportedSanitizers() const {
5145 SanitizerMask Res = ToolChain::getSupportedSanitizers();
5146 Res |= SanitizerKind::Address;
5147 Res |= SanitizerKind::Vptr;
5148 return Res;
5149}