blob: b9af30d286c6498ccee0bfad7ed249d450ace84d [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 Kumar5fb00e42016-07-27 23:01:55 +0000383void Darwin::addProfileRTLibs(const ArgList &Args,
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000384 ArgStringList &CmdArgs) const {
Vedant Kumar5fb00e42016-07-27 23:01:55 +0000385 if (!needsProfileRT(Args)) return;
Justin Bognerc7701242015-05-12 05:44:36 +0000386
Vedant Kumar5fb00e42016-07-27 23:01:55 +0000387 AddLinkRuntimeLib(Args, CmdArgs, (Twine("libclang_rt.profile_") +
388 getOSLibraryNameSuffix() + ".a").str(),
389 /*AlwaysLink*/ true);
Justin Bognerc7701242015-05-12 05:44:36 +0000390}
391
Alexey Samsonov498f3c32015-03-23 23:14:05 +0000392void DarwinClang::AddLinkSanitizerLibArgs(const ArgList &Args,
393 ArgStringList &CmdArgs,
394 StringRef Sanitizer) const {
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000395 AddLinkRuntimeLib(
396 Args, CmdArgs,
Anna Zakse67b4022016-02-02 02:04:48 +0000397 (Twine("libclang_rt.") + Sanitizer + "_" +
398 getOSLibraryNameSuffix() + "_dynamic.dylib").str(),
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000399 /*AlwaysLink*/ true, /*IsEmbedded*/ false,
400 /*AddRPath*/ true);
Alexey Samsonov498f3c32015-03-23 23:14:05 +0000401}
402
Jonas Hahnfeldd196fa52016-07-27 08:15:54 +0000403ToolChain::RuntimeLibType DarwinClang::GetRuntimeLibType(
404 const ArgList &Args) const {
405 if (Arg* A = Args.getLastArg(options::OPT_rtlib_EQ)) {
406 StringRef Value = A->getValue();
407 if (Value != "compiler-rt")
408 getDriver().Diag(diag::err_drv_unsupported_rtlib_for_platform)
409 << Value << "darwin";
410 }
411
412 return ToolChain::RLT_CompilerRT;
413}
414
Vedant Kumar5fb00e42016-07-27 23:01:55 +0000415void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args,
Daniel Dunbar6276f992009-09-18 08:15:13 +0000416 ArgStringList &CmdArgs) const {
Jonas Hahnfeldd196fa52016-07-27 08:15:54 +0000417 // Call once to ensure diagnostic is printed if wrong value was specified
418 GetRuntimeLibType(Args);
Daniel Dunbarf4916cd2011-12-07 23:03:15 +0000419
Daniel Dunbar7cde09a2010-01-22 03:38:14 +0000420 // Darwin doesn't support real static executables, don't link any runtime
421 // libraries with -static.
Daniel Dunbarbd847cc2012-10-15 22:23:53 +0000422 if (Args.hasArg(options::OPT_static) ||
423 Args.hasArg(options::OPT_fapple_kext) ||
424 Args.hasArg(options::OPT_mkernel))
Daniel Dunbar6276f992009-09-18 08:15:13 +0000425 return;
Daniel Dunbar6276f992009-09-18 08:15:13 +0000426
427 // Reject -static-libgcc for now, we can deal with this when and if someone
428 // cares. This is useful in situations where someone wants to statically link
429 // something like libstdc++, and needs its runtime support routines.
430 if (const Arg *A = Args.getLastArg(options::OPT_static_libgcc)) {
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000431 getDriver().Diag(diag::err_drv_unsupported_opt) << A->getAsString(Args);
Daniel Dunbar6276f992009-09-18 08:15:13 +0000432 return;
433 }
434
Peter Collingbourne32701642013-11-01 18:16:25 +0000435 const SanitizerArgs &Sanitize = getSanitizerArgs();
Alexey Samsonov7f2a0d22015-06-19 21:36:47 +0000436 if (Sanitize.needsAsanRt())
437 AddLinkSanitizerLibArgs(Args, CmdArgs, "asan");
438 if (Sanitize.needsUbsanRt())
439 AddLinkSanitizerLibArgs(Args, CmdArgs, "ubsan");
Kuba Brecka85e01c02015-11-06 15:09:20 +0000440 if (Sanitize.needsTsanRt())
441 AddLinkSanitizerLibArgs(Args, CmdArgs, "tsan");
Peter Collingbournedc134532016-01-16 00:31:22 +0000442 if (Sanitize.needsStatsRt()) {
443 StringRef OS = isTargetMacOS() ? "osx" : "iossim";
444 AddLinkRuntimeLib(Args, CmdArgs,
445 (Twine("libclang_rt.stats_client_") + OS + ".a").str(),
446 /*AlwaysLink=*/true);
447 AddLinkSanitizerLibArgs(Args, CmdArgs, "stats");
448 }
Derek Bruening256c2e12016-04-21 21:32:04 +0000449 if (Sanitize.needsEsanRt())
450 AddLinkSanitizerLibArgs(Args, CmdArgs, "esan");
Daniel Dunbar1d6469f2011-12-01 23:40:18 +0000451
Daniel Dunbar7cde09a2010-01-22 03:38:14 +0000452 // Otherwise link libSystem, then the dynamic runtime library, and finally any
453 // target specific static runtime library.
Daniel Dunbar6276f992009-09-18 08:15:13 +0000454 CmdArgs.push_back("-lSystem");
Daniel Dunbar7cde09a2010-01-22 03:38:14 +0000455
456 // Select the dynamic runtime library and the target specific static library.
Tim Northover6f3ff222015-10-30 16:30:27 +0000457 if (isTargetWatchOSBased()) {
458 // We currently always need a static runtime library for watchOS.
459 AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.watchos.a");
460 } else if (isTargetTvOSBased()) {
461 // We currently always need a static runtime library for tvOS.
462 AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.tvos.a");
463 } else if (isTargetIOSBased()) {
Daniel Dunbar2f31fb92011-04-30 04:25:16 +0000464 // If we are compiling as iOS / simulator, don't attempt to link libgcc_s.1,
465 // it never went into the SDK.
Bob Wilson102be442011-10-07 17:54:41 +0000466 // Linking against libgcc_s.1 isn't needed for iOS 5.0+
Tim Northovera2ee4332014-03-29 15:09:45 +0000467 if (isIPhoneOSVersionLT(5, 0) && !isTargetIOSSimulator() &&
Tim Northover40956e62014-07-23 12:32:58 +0000468 getTriple().getArch() != llvm::Triple::aarch64)
Bob Wilson102be442011-10-07 17:54:41 +0000469 CmdArgs.push_back("-lgcc_s.1");
Daniel Dunbar7cde09a2010-01-22 03:38:14 +0000470
Daniel Dunbard1076382011-04-18 23:48:36 +0000471 // We currently always need a static runtime library for iOS.
Eric Christopherc235d0c62011-06-22 17:41:40 +0000472 AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.ios.a");
Daniel Dunbar7cde09a2010-01-22 03:38:14 +0000473 } else {
Tim Northover9c7e0352013-12-12 11:55:52 +0000474 assert(isTargetMacOS() && "unexpected non MacOS platform");
Daniel Dunbar7cde09a2010-01-22 03:38:14 +0000475 // The dynamic runtime library was merged with libSystem for 10.6 and
476 // beyond; only 10.4 and 10.5 need an additional runtime library.
Daniel Dunbar6d23b2f2010-01-27 00:57:03 +0000477 if (isMacosxVersionLT(10, 5))
Daniel Dunbar7cde09a2010-01-22 03:38:14 +0000478 CmdArgs.push_back("-lgcc_s.10.4");
Daniel Dunbar6d23b2f2010-01-27 00:57:03 +0000479 else if (isMacosxVersionLT(10, 6))
Daniel Dunbar7cde09a2010-01-22 03:38:14 +0000480 CmdArgs.push_back("-lgcc_s.10.5");
481
Daniel Dunbarda4f6b52010-09-22 00:03:52 +0000482 // For OS X, we thought we would only need a static runtime library when
Chris Lattner57540c52011-04-15 05:22:18 +0000483 // targeting 10.4, to provide versions of the static functions which were
Daniel Dunbarda4f6b52010-09-22 00:03:52 +0000484 // omitted from 10.4.dylib.
485 //
486 // Unfortunately, that turned out to not be true, because Darwin system
487 // headers can still use eprintf on i386, and it is not exported from
488 // libSystem. Therefore, we still must provide a runtime library just for
489 // the tiny tiny handful of projects that *might* use that symbol.
490 if (isMacosxVersionLT(10, 5)) {
Eric Christopherc235d0c62011-06-22 17:41:40 +0000491 AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.10.4.a");
Daniel Dunbarda4f6b52010-09-22 00:03:52 +0000492 } else {
493 if (getTriple().getArch() == llvm::Triple::x86)
Eric Christopherc235d0c62011-06-22 17:41:40 +0000494 AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.eprintf.a");
495 AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.osx.a");
Daniel Dunbarda4f6b52010-09-22 00:03:52 +0000496 }
Daniel Dunbar7cde09a2010-01-22 03:38:14 +0000497 }
Daniel Dunbar6276f992009-09-18 08:15:13 +0000498}
499
Daniel Dunbar354e96d2010-07-19 17:11:36 +0000500void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
Daniel Dunbar083edf72009-12-21 18:54:17 +0000501 const OptTable &Opts = getDriver().getOpts();
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000502
Daniel Dunbar455a0492012-08-17 18:43:50 +0000503 // Support allowing the SDKROOT environment variable used by xcrun and other
504 // Xcode tools to define the default sysroot, by making it the default for
505 // isysroot.
Chad Rosier6c2b11c2012-12-19 23:41:50 +0000506 if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
507 // Warn if the path does not exist.
Benjamin Kramerd45b2052015-10-07 15:48:01 +0000508 if (!getVFS().exists(A->getValue()))
Chad Rosier6c2b11c2012-12-19 23:41:50 +0000509 getDriver().Diag(clang::diag::warn_missing_sysroot) << A->getValue();
510 } else {
Daniel Dunbar455a0492012-08-17 18:43:50 +0000511 if (char *env = ::getenv("SDKROOT")) {
Daniel Dunbarb2543042013-01-15 20:33:56 +0000512 // We only use this value as the default if it is an absolute path,
513 // exists, and it is not the root path.
Benjamin Kramerd45b2052015-10-07 15:48:01 +0000514 if (llvm::sys::path::is_absolute(env) && getVFS().exists(env) &&
Daniel Dunbarb2543042013-01-15 20:33:56 +0000515 StringRef(env) != "/") {
Daniel Dunbar455a0492012-08-17 18:43:50 +0000516 Args.append(Args.MakeSeparateArg(
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000517 nullptr, Opts.getOption(options::OPT_isysroot), env));
Daniel Dunbar455a0492012-08-17 18:43:50 +0000518 }
519 }
520 }
521
Daniel Dunbar3b8e50d2010-01-27 00:56:25 +0000522 Arg *OSXVersion = Args.getLastArg(options::OPT_mmacosx_version_min_EQ);
Daniel Dunbar9aaeb642011-04-30 04:15:58 +0000523 Arg *iOSVersion = Args.getLastArg(options::OPT_miphoneos_version_min_EQ);
Tim Northover6f3ff222015-10-30 16:30:27 +0000524 Arg *TvOSVersion = Args.getLastArg(options::OPT_mtvos_version_min_EQ);
525 Arg *WatchOSVersion = Args.getLastArg(options::OPT_mwatchos_version_min_EQ);
Eli Friedman027e9c32012-01-11 02:41:15 +0000526
Tim Northover6f3ff222015-10-30 16:30:27 +0000527 if (OSXVersion && (iOSVersion || TvOSVersion || WatchOSVersion)) {
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000528 getDriver().Diag(diag::err_drv_argument_not_allowed_with)
Tim Northover6f3ff222015-10-30 16:30:27 +0000529 << OSXVersion->getAsString(Args)
530 << (iOSVersion ? iOSVersion :
531 TvOSVersion ? TvOSVersion : WatchOSVersion)->getAsString(Args);
532 iOSVersion = TvOSVersion = WatchOSVersion = nullptr;
533 } else if (iOSVersion && (TvOSVersion || WatchOSVersion)) {
534 getDriver().Diag(diag::err_drv_argument_not_allowed_with)
535 << iOSVersion->getAsString(Args)
536 << (TvOSVersion ? TvOSVersion : WatchOSVersion)->getAsString(Args);
537 TvOSVersion = WatchOSVersion = nullptr;
538 } else if (TvOSVersion && WatchOSVersion) {
539 getDriver().Diag(diag::err_drv_argument_not_allowed_with)
540 << TvOSVersion->getAsString(Args)
541 << WatchOSVersion->getAsString(Args);
542 WatchOSVersion = nullptr;
543 } else if (!OSXVersion && !iOSVersion && !TvOSVersion && !WatchOSVersion) {
Chad Rosier64707fe2011-08-31 20:56:25 +0000544 // If no deployment target was specified on the command line, check for
Daniel Dunbard54669d2010-01-26 01:45:19 +0000545 // environment defines.
Alexey Samsonov905c8022015-06-18 21:46:05 +0000546 std::string OSXTarget;
547 std::string iOSTarget;
Tim Northover6f3ff222015-10-30 16:30:27 +0000548 std::string TvOSTarget;
549 std::string WatchOSTarget;
550
Chad Rosier64707fe2011-08-31 20:56:25 +0000551 if (char *env = ::getenv("MACOSX_DEPLOYMENT_TARGET"))
552 OSXTarget = env;
553 if (char *env = ::getenv("IPHONEOS_DEPLOYMENT_TARGET"))
554 iOSTarget = env;
Tim Northover6f3ff222015-10-30 16:30:27 +0000555 if (char *env = ::getenv("TVOS_DEPLOYMENT_TARGET"))
556 TvOSTarget = env;
557 if (char *env = ::getenv("WATCHOS_DEPLOYMENT_TARGET"))
558 WatchOSTarget = env;
Daniel Dunbarb5023e92009-04-10 21:00:07 +0000559
Steven Wu7a1372c2015-06-25 01:59:35 +0000560 // If there is no command-line argument to specify the Target version and
561 // no environment variable defined, see if we can set the default based
562 // on -isysroot.
Tim Northover6f3ff222015-10-30 16:30:27 +0000563 if (OSXTarget.empty() && iOSTarget.empty() && WatchOSTarget.empty() &&
Frederic Riss3ad83bd2016-01-12 23:47:59 +0000564 TvOSTarget.empty() && Args.hasArg(options::OPT_isysroot)) {
Chad Rosier64707fe2011-08-31 20:56:25 +0000565 if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
Richard Smithbd55daf2012-11-01 04:30:05 +0000566 StringRef isysroot = A->getValue();
Chris Bienemane60e7c22016-04-29 22:28:34 +0000567 StringRef SDK = getSDKName(isysroot);
568 if (SDK.size() > 0) {
Steven Wu7a1372c2015-06-25 01:59:35 +0000569 // Slice the version number out.
570 // Version number is between the first and the last number.
571 size_t StartVer = SDK.find_first_of("0123456789");
572 size_t EndVer = SDK.find_last_of("0123456789");
573 if (StartVer != StringRef::npos && EndVer > StartVer) {
574 StringRef Version = SDK.slice(StartVer, EndVer + 1);
575 if (SDK.startswith("iPhoneOS") ||
576 SDK.startswith("iPhoneSimulator"))
577 iOSTarget = Version;
578 else if (SDK.startswith("MacOSX"))
579 OSXTarget = Version;
Tim Northover6f3ff222015-10-30 16:30:27 +0000580 else if (SDK.startswith("WatchOS") ||
581 SDK.startswith("WatchSimulator"))
582 WatchOSTarget = Version;
583 else if (SDK.startswith("AppleTVOS") ||
584 SDK.startswith("AppleTVSimulator"))
585 TvOSTarget = Version;
Steven Wu7a1372c2015-06-25 01:59:35 +0000586 }
587 }
Chad Rosier64707fe2011-08-31 20:56:25 +0000588 }
589 }
Daniel Dunbard54669d2010-01-26 01:45:19 +0000590
Alexey Samsonovfd0bb3a2015-06-18 00:36:38 +0000591 // If no OSX or iOS target has been specified, try to guess platform
Alexey Samsonov905c8022015-06-18 21:46:05 +0000592 // from arch name and compute the version from the triple.
Tim Northover6f3ff222015-10-30 16:30:27 +0000593 if (OSXTarget.empty() && iOSTarget.empty() && TvOSTarget.empty() &&
594 WatchOSTarget.empty()) {
Alexey Samsonovfd0bb3a2015-06-18 00:36:38 +0000595 StringRef MachOArchName = getMachOArchName(Args);
Alexey Samsonov905c8022015-06-18 21:46:05 +0000596 unsigned Major, Minor, Micro;
Alexey Samsonovfd0bb3a2015-06-18 00:36:38 +0000597 if (MachOArchName == "armv7" || MachOArchName == "armv7s" ||
Alexey Samsonov905c8022015-06-18 21:46:05 +0000598 MachOArchName == "arm64") {
599 getTriple().getiOSVersion(Major, Minor, Micro);
600 llvm::raw_string_ostream(iOSTarget) << Major << '.' << Minor << '.'
601 << Micro;
Tim Northover6f3ff222015-10-30 16:30:27 +0000602 } else if (MachOArchName == "armv7k") {
603 getTriple().getWatchOSVersion(Major, Minor, Micro);
604 llvm::raw_string_ostream(WatchOSTarget) << Major << '.' << Minor << '.'
605 << Micro;
Alexey Samsonov905c8022015-06-18 21:46:05 +0000606 } else if (MachOArchName != "armv6m" && MachOArchName != "armv7m" &&
607 MachOArchName != "armv7em") {
608 if (!getTriple().getMacOSXVersion(Major, Minor, Micro)) {
609 getDriver().Diag(diag::err_drv_invalid_darwin_version)
610 << getTriple().getOSName();
611 }
612 llvm::raw_string_ostream(OSXTarget) << Major << '.' << Minor << '.'
613 << Micro;
614 }
Alexey Samsonovfd0bb3a2015-06-18 00:36:38 +0000615 }
Chad Rosierfe6fd362011-09-28 00:46:32 +0000616
Tim Northover6f3ff222015-10-30 16:30:27 +0000617 // Do not allow conflicts with the watchOS target.
618 if (!WatchOSTarget.empty() && (!iOSTarget.empty() || !TvOSTarget.empty())) {
619 getDriver().Diag(diag::err_drv_conflicting_deployment_targets)
620 << "WATCHOS_DEPLOYMENT_TARGET"
621 << (!iOSTarget.empty() ? "IPHONEOS_DEPLOYMENT_TARGET" :
622 "TVOS_DEPLOYMENT_TARGET");
623 }
624
625 // Do not allow conflicts with the tvOS target.
626 if (!TvOSTarget.empty() && !iOSTarget.empty()) {
627 getDriver().Diag(diag::err_drv_conflicting_deployment_targets)
628 << "TVOS_DEPLOYMENT_TARGET"
629 << "IPHONEOS_DEPLOYMENT_TARGET";
630 }
631
Daniel Dunbar9aaeb642011-04-30 04:15:58 +0000632 // Allow conflicts among OSX and iOS for historical reasons, but choose the
633 // default platform.
Tim Northover6f3ff222015-10-30 16:30:27 +0000634 if (!OSXTarget.empty() && (!iOSTarget.empty() ||
635 !WatchOSTarget.empty() ||
636 !TvOSTarget.empty())) {
Daniel Dunbarffa70e82010-02-02 17:31:12 +0000637 if (getTriple().getArch() == llvm::Triple::arm ||
Tim Northover573cbee2014-05-24 12:52:07 +0000638 getTriple().getArch() == llvm::Triple::aarch64 ||
Daniel Dunbarffa70e82010-02-02 17:31:12 +0000639 getTriple().getArch() == llvm::Triple::thumb)
Chad Rosier64707fe2011-08-31 20:56:25 +0000640 OSXTarget = "";
Daniel Dunbarffa70e82010-02-02 17:31:12 +0000641 else
Tim Northover6f3ff222015-10-30 16:30:27 +0000642 iOSTarget = WatchOSTarget = TvOSTarget = "";
Daniel Dunbarffa70e82010-02-02 17:31:12 +0000643 }
Daniel Dunbar65969842010-01-29 17:02:25 +0000644
Chad Rosier64707fe2011-08-31 20:56:25 +0000645 if (!OSXTarget.empty()) {
Michael J. Spencerfc790902012-10-19 22:36:40 +0000646 const Option O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
Craig Topper92fc2df2014-05-17 16:56:41 +0000647 OSXVersion = Args.MakeJoinedArg(nullptr, O, OSXTarget);
Daniel Dunbar354e96d2010-07-19 17:11:36 +0000648 Args.append(OSXVersion);
Chad Rosier64707fe2011-08-31 20:56:25 +0000649 } else if (!iOSTarget.empty()) {
Michael J. Spencerfc790902012-10-19 22:36:40 +0000650 const Option O = Opts.getOption(options::OPT_miphoneos_version_min_EQ);
Craig Topper92fc2df2014-05-17 16:56:41 +0000651 iOSVersion = Args.MakeJoinedArg(nullptr, O, iOSTarget);
Daniel Dunbar9aaeb642011-04-30 04:15:58 +0000652 Args.append(iOSVersion);
Tim Northover6f3ff222015-10-30 16:30:27 +0000653 } else if (!TvOSTarget.empty()) {
654 const Option O = Opts.getOption(options::OPT_mtvos_version_min_EQ);
655 TvOSVersion = Args.MakeJoinedArg(nullptr, O, TvOSTarget);
656 Args.append(TvOSVersion);
657 } else if (!WatchOSTarget.empty()) {
658 const Option O = Opts.getOption(options::OPT_mwatchos_version_min_EQ);
659 WatchOSVersion = Args.MakeJoinedArg(nullptr, O, WatchOSTarget);
660 Args.append(WatchOSVersion);
Daniel Dunbar84e727f2009-09-04 18:35:21 +0000661 }
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000662 }
Mike Stump11289f42009-09-09 15:08:12 +0000663
Tim Northover9c7e0352013-12-12 11:55:52 +0000664 DarwinPlatformKind Platform;
665 if (OSXVersion)
666 Platform = MacOS;
667 else if (iOSVersion)
668 Platform = IPhoneOS;
Tim Northover6f3ff222015-10-30 16:30:27 +0000669 else if (TvOSVersion)
670 Platform = TvOS;
671 else if (WatchOSVersion)
672 Platform = WatchOS;
Tim Northover9c7e0352013-12-12 11:55:52 +0000673 else
Tim Northover157d9112014-01-16 08:48:16 +0000674 llvm_unreachable("Unable to infer Darwin variant");
Tim Northover9c7e0352013-12-12 11:55:52 +0000675
Daniel Dunbar3b8e50d2010-01-27 00:56:25 +0000676 // Set the tool chain target information.
677 unsigned Major, Minor, Micro;
678 bool HadExtra;
Tim Northover9c7e0352013-12-12 11:55:52 +0000679 if (Platform == MacOS) {
Tim Northover6f3ff222015-10-30 16:30:27 +0000680 assert((!iOSVersion && !TvOSVersion && !WatchOSVersion) &&
681 "Unknown target platform!");
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000682 if (!Driver::GetReleaseVersion(OSXVersion->getValue(), Major, Minor, Micro,
683 HadExtra) ||
684 HadExtra || Major != 10 || Minor >= 100 || Micro >= 100)
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000685 getDriver().Diag(diag::err_drv_invalid_version_number)
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000686 << OSXVersion->getAsString(Args);
Bob Wilson7f294b52014-10-10 23:10:10 +0000687 } else if (Platform == IPhoneOS) {
688 assert(iOSVersion && "Unknown target platform!");
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000689 if (!Driver::GetReleaseVersion(iOSVersion->getValue(), Major, Minor, Micro,
690 HadExtra) ||
Bob Wilson4cf27c42016-07-18 20:29:14 +0000691 HadExtra || Major >= 100 || Minor >= 100 || Micro >= 100)
Eli Friedman027e9c32012-01-11 02:41:15 +0000692 getDriver().Diag(diag::err_drv_invalid_version_number)
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000693 << iOSVersion->getAsString(Args);
Tim Northover6f3ff222015-10-30 16:30:27 +0000694 } else if (Platform == TvOS) {
695 if (!Driver::GetReleaseVersion(TvOSVersion->getValue(), Major, Minor,
696 Micro, HadExtra) || HadExtra ||
Bob Wilson4cf27c42016-07-18 20:29:14 +0000697 Major >= 100 || Minor >= 100 || Micro >= 100)
Tim Northover6f3ff222015-10-30 16:30:27 +0000698 getDriver().Diag(diag::err_drv_invalid_version_number)
699 << TvOSVersion->getAsString(Args);
700 } else if (Platform == WatchOS) {
701 if (!Driver::GetReleaseVersion(WatchOSVersion->getValue(), Major, Minor,
702 Micro, HadExtra) || HadExtra ||
703 Major >= 10 || Minor >= 100 || Micro >= 100)
704 getDriver().Diag(diag::err_drv_invalid_version_number)
705 << WatchOSVersion->getAsString(Args);
Tim Northover157d9112014-01-16 08:48:16 +0000706 } else
707 llvm_unreachable("unknown kind of Darwin platform");
Daniel Dunbar9aaeb642011-04-30 04:15:58 +0000708
Bob Wilson7f294b52014-10-10 23:10:10 +0000709 // Recognize iOS targets with an x86 architecture as the iOS simulator.
Daniel Dunbarb1189432011-04-30 04:18:16 +0000710 if (iOSVersion && (getTriple().getArch() == llvm::Triple::x86 ||
711 getTriple().getArch() == llvm::Triple::x86_64))
Tim Northover9c7e0352013-12-12 11:55:52 +0000712 Platform = IPhoneOSSimulator;
Tim Northover6f3ff222015-10-30 16:30:27 +0000713 if (TvOSVersion && (getTriple().getArch() == llvm::Triple::x86 ||
714 getTriple().getArch() == llvm::Triple::x86_64))
715 Platform = TvOSSimulator;
716 if (WatchOSVersion && (getTriple().getArch() == llvm::Triple::x86 ||
717 getTriple().getArch() == llvm::Triple::x86_64))
718 Platform = WatchOSSimulator;
Daniel Dunbarb1189432011-04-30 04:18:16 +0000719
Tim Northover9c7e0352013-12-12 11:55:52 +0000720 setTarget(Platform, Major, Minor, Micro);
Chris Bienemane60e7c22016-04-29 22:28:34 +0000721
722 if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
723 StringRef SDK = getSDKName(A->getValue());
724 if (SDK.size() > 0) {
725 size_t StartVer = SDK.find_first_of("0123456789");
726 StringRef SDKName = SDK.slice(0, StartVer);
727 if (!SDKName.startswith(getPlatformFamily()))
728 getDriver().Diag(diag::warn_incompatible_sysroot)
729 << SDKName << getPlatformFamily();
730 }
731 }
Daniel Dunbarb2b8a912010-07-19 17:11:33 +0000732}
733
Daniel Dunbar3f7796f2010-09-17 01:20:05 +0000734void DarwinClang::AddCXXStdlibLibArgs(const ArgList &Args,
Daniel Dunbar8fa86b12010-09-17 01:16:06 +0000735 ArgStringList &CmdArgs) const {
736 CXXStdlibType Type = GetCXXStdlibType(Args);
737
738 switch (Type) {
739 case ToolChain::CST_Libcxx:
740 CmdArgs.push_back("-lc++");
741 break;
742
Hans Wennborgdcfba332015-10-06 23:40:43 +0000743 case ToolChain::CST_Libstdcxx:
Daniel Dunbar8fa86b12010-09-17 01:16:06 +0000744 // Unfortunately, -lstdc++ doesn't always exist in the standard search path;
745 // it was previously found in the gcc lib dir. However, for all the Darwin
746 // platforms we care about it was -lstdc++.6, so we search for that
747 // explicitly if we can't see an obvious -lstdc++ candidate.
748
749 // Check in the sysroot first.
750 if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
Rafael Espindola358256c2013-06-26 02:13:00 +0000751 SmallString<128> P(A->getValue());
Benjamin Kramer17381a02013-06-28 16:25:46 +0000752 llvm::sys::path::append(P, "usr", "lib", "libstdc++.dylib");
Daniel Dunbar8fa86b12010-09-17 01:16:06 +0000753
Benjamin Kramerd45b2052015-10-07 15:48:01 +0000754 if (!getVFS().exists(P)) {
Rafael Espindola358256c2013-06-26 02:13:00 +0000755 llvm::sys::path::remove_filename(P);
756 llvm::sys::path::append(P, "libstdc++.6.dylib");
Benjamin Kramerd45b2052015-10-07 15:48:01 +0000757 if (getVFS().exists(P)) {
Yaron Keren92e1b622015-03-18 10:17:07 +0000758 CmdArgs.push_back(Args.MakeArgString(P));
Daniel Dunbar8fa86b12010-09-17 01:16:06 +0000759 return;
760 }
761 }
762 }
763
764 // Otherwise, look in the root.
Bob Wilson1a9ad0f2011-11-11 07:47:04 +0000765 // FIXME: This should be removed someday when we don't have to care about
766 // 10.6 and earlier, where /usr/lib/libstdc++.dylib does not exist.
Benjamin Kramerd45b2052015-10-07 15:48:01 +0000767 if (!getVFS().exists("/usr/lib/libstdc++.dylib") &&
768 getVFS().exists("/usr/lib/libstdc++.6.dylib")) {
Daniel Dunbar8fa86b12010-09-17 01:16:06 +0000769 CmdArgs.push_back("/usr/lib/libstdc++.6.dylib");
770 return;
771 }
772
773 // Otherwise, let the linker search.
774 CmdArgs.push_back("-lstdc++");
775 break;
776 }
Daniel Dunbar8fa86b12010-09-17 01:16:06 +0000777}
778
Shantonu Senafeb03b2010-09-17 18:39:08 +0000779void DarwinClang::AddCCKextLibArgs(const ArgList &Args,
780 ArgStringList &CmdArgs) const {
Shantonu Senafeb03b2010-09-17 18:39:08 +0000781 // For Darwin platforms, use the compiler-rt-based support library
782 // instead of the gcc-provided one (which is also incidentally
783 // only present in the gcc lib dir, which makes it hard to find).
784
Rafael Espindola358256c2013-06-26 02:13:00 +0000785 SmallString<128> P(getDriver().ResourceDir);
Benjamin Kramer17381a02013-06-28 16:25:46 +0000786 llvm::sys::path::append(P, "lib", "darwin");
Daniel Dunbarbd847cc2012-10-15 22:23:53 +0000787
788 // Use the newer cc_kext for iOS ARM after 6.0.
Tim Northover6f3ff222015-10-30 16:30:27 +0000789 if (isTargetWatchOS()) {
790 llvm::sys::path::append(P, "libclang_rt.cc_kext_watchos.a");
791 } else if (isTargetTvOS()) {
792 llvm::sys::path::append(P, "libclang_rt.cc_kext_tvos.a");
793 } else if (isTargetIPhoneOS()) {
Chris Bieneman25bc0de2015-09-23 22:52:35 +0000794 llvm::sys::path::append(P, "libclang_rt.cc_kext_ios.a");
Daniel Dunbarbd847cc2012-10-15 22:23:53 +0000795 } else {
Chris Bieneman25bc0de2015-09-23 22:52:35 +0000796 llvm::sys::path::append(P, "libclang_rt.cc_kext.a");
Daniel Dunbarbd847cc2012-10-15 22:23:53 +0000797 }
NAKAMURA Takumi8b73b3e2011-06-03 03:49:51 +0000798
Shantonu Senafeb03b2010-09-17 18:39:08 +0000799 // For now, allow missing resource libraries to support developers who may
800 // not have compiler-rt checked out or integrated into their build.
Benjamin Kramerd45b2052015-10-07 15:48:01 +0000801 if (getVFS().exists(P))
Yaron Keren92e1b622015-03-18 10:17:07 +0000802 CmdArgs.push_back(Args.MakeArgString(P));
Shantonu Senafeb03b2010-09-17 18:39:08 +0000803}
804
Tim Northover157d9112014-01-16 08:48:16 +0000805DerivedArgList *MachO::TranslateArgs(const DerivedArgList &Args,
806 const char *BoundArch) const {
Daniel Dunbarb2b8a912010-07-19 17:11:33 +0000807 DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
808 const OptTable &Opts = getDriver().getOpts();
809
810 // FIXME: We really want to get out of the tool chain level argument
811 // translation business, as it makes the driver functionality much
812 // more opaque. For now, we follow gcc closely solely for the
813 // purpose of easily achieving feature parity & testability. Once we
814 // have something that works, we should reevaluate each translation
815 // and try to push it down into tool specific logic.
Daniel Dunbar3b8e50d2010-01-27 00:56:25 +0000816
Simon Atanasyan6f657c42014-05-08 19:32:46 +0000817 for (Arg *A : Args) {
Daniel Dunbaraabb0b12009-03-25 06:12:34 +0000818 if (A->getOption().matches(options::OPT_Xarch__)) {
Daniel Dunbar471c4f82011-06-21 00:20:17 +0000819 // Skip this argument unless the architecture matches either the toolchain
820 // triple arch, or the arch being bound.
Rafael Espindola35ca7d92012-10-07 04:44:33 +0000821 llvm::Triple::ArchType XarchArch =
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000822 tools::darwin::getArchTypeForMachOArchName(A->getValue(0));
823 if (!(XarchArch == getArch() ||
824 (BoundArch &&
825 XarchArch ==
826 tools::darwin::getArchTypeForMachOArchName(BoundArch))))
Daniel Dunbaraabb0b12009-03-25 06:12:34 +0000827 continue;
828
Daniel Dunbar1094bb12011-02-19 05:33:51 +0000829 Arg *OriginalArg = A;
Richard Smithbd55daf2012-11-01 04:30:05 +0000830 unsigned Index = Args.getBaseArgs().MakeIndex(A->getValue(1));
Daniel Dunbar3f1a1ff2010-06-14 21:23:08 +0000831 unsigned Prev = Index;
Nico Webera04d5f82014-05-11 17:27:13 +0000832 std::unique_ptr<Arg> XarchArg(Opts.ParseOneArg(Args, Index));
Mike Stump11289f42009-09-09 15:08:12 +0000833
Daniel Dunbaraabb0b12009-03-25 06:12:34 +0000834 // If the argument parsing failed or more than one argument was
835 // consumed, the -Xarch_ argument's parameter tried to consume
836 // extra arguments. Emit an error and ignore.
837 //
838 // We also want to disallow any options which would alter the
839 // driver behavior; that isn't going to work in our model. We
840 // use isDriverOption() as an approximation, although things
841 // like -O4 are going to slip through.
Daniel Dunbar5a784c82011-04-21 17:41:34 +0000842 if (!XarchArg || Index > Prev + 1) {
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000843 getDriver().Diag(diag::err_drv_invalid_Xarch_argument_with_args)
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000844 << A->getAsString(Args);
Daniel Dunbar6914a982011-04-21 17:32:21 +0000845 continue;
Michael J. Spencer66e2b202012-10-19 22:37:06 +0000846 } else if (XarchArg->getOption().hasFlag(options::DriverOption)) {
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000847 getDriver().Diag(diag::err_drv_invalid_Xarch_argument_isdriver)
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000848 << A->getAsString(Args);
Daniel Dunbaraabb0b12009-03-25 06:12:34 +0000849 continue;
850 }
851
Daniel Dunbar53b406f2009-03-29 22:29:05 +0000852 XarchArg->setBaseArg(A);
Daniel Dunbar3f1a1ff2010-06-14 21:23:08 +0000853
Nico Webera04d5f82014-05-11 17:27:13 +0000854 A = XarchArg.release();
Daniel Dunbar3f1a1ff2010-06-14 21:23:08 +0000855 DAL->AddSynthesizedArg(A);
Daniel Dunbar1094bb12011-02-19 05:33:51 +0000856
857 // Linker input arguments require custom handling. The problem is that we
858 // have already constructed the phase actions, so we can not treat them as
859 // "input arguments".
Michael J. Spencer66e2b202012-10-19 22:37:06 +0000860 if (A->getOption().hasFlag(options::LinkerInput)) {
Daniel Dunbar1094bb12011-02-19 05:33:51 +0000861 // Convert the argument into individual Zlinker_input_args.
Douglas Katzman6bbffc42015-06-25 18:51:37 +0000862 for (const char *Value : A->getValues()) {
863 DAL->AddSeparateArg(
864 OriginalArg, Opts.getOption(options::OPT_Zlinker_input), Value);
Daniel Dunbar1094bb12011-02-19 05:33:51 +0000865 }
866 continue;
867 }
Mike Stump11289f42009-09-09 15:08:12 +0000868 }
Daniel Dunbaraabb0b12009-03-25 06:12:34 +0000869
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000870 // Sob. These is strictly gcc compatible for the time being. Apple
871 // gcc translates options twice, which means that self-expanding
872 // options add duplicates.
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000873 switch ((options::ID)A->getOption().getID()) {
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000874 default:
875 DAL->append(A);
876 break;
877
878 case options::OPT_mkernel:
879 case options::OPT_fapple_kext:
880 DAL->append(A);
Daniel Dunbar2d6e9ee2010-06-14 20:20:41 +0000881 DAL->AddFlagArg(A, Opts.getOption(options::OPT_static));
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000882 break;
Mike Stump11289f42009-09-09 15:08:12 +0000883
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000884 case options::OPT_dependency_file:
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000885 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue());
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000886 break;
887
888 case options::OPT_gfull:
Daniel Dunbar2d6e9ee2010-06-14 20:20:41 +0000889 DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag));
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000890 DAL->AddFlagArg(
891 A, Opts.getOption(options::OPT_fno_eliminate_unused_debug_symbols));
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000892 break;
893
894 case options::OPT_gused:
Daniel Dunbar2d6e9ee2010-06-14 20:20:41 +0000895 DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag));
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000896 DAL->AddFlagArg(
897 A, Opts.getOption(options::OPT_feliminate_unused_debug_symbols));
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000898 break;
899
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000900 case options::OPT_shared:
Daniel Dunbar2d6e9ee2010-06-14 20:20:41 +0000901 DAL->AddFlagArg(A, Opts.getOption(options::OPT_dynamiclib));
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000902 break;
903
904 case options::OPT_fconstant_cfstrings:
Daniel Dunbar2d6e9ee2010-06-14 20:20:41 +0000905 DAL->AddFlagArg(A, Opts.getOption(options::OPT_mconstant_cfstrings));
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000906 break;
907
908 case options::OPT_fno_constant_cfstrings:
Daniel Dunbar2d6e9ee2010-06-14 20:20:41 +0000909 DAL->AddFlagArg(A, Opts.getOption(options::OPT_mno_constant_cfstrings));
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000910 break;
911
912 case options::OPT_Wnonportable_cfstrings:
Daniel Dunbar2d6e9ee2010-06-14 20:20:41 +0000913 DAL->AddFlagArg(A,
914 Opts.getOption(options::OPT_mwarn_nonportable_cfstrings));
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000915 break;
916
917 case options::OPT_Wno_nonportable_cfstrings:
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000918 DAL->AddFlagArg(
919 A, Opts.getOption(options::OPT_mno_warn_nonportable_cfstrings));
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000920 break;
921
922 case options::OPT_fpascal_strings:
Daniel Dunbar2d6e9ee2010-06-14 20:20:41 +0000923 DAL->AddFlagArg(A, Opts.getOption(options::OPT_mpascal_strings));
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000924 break;
925
926 case options::OPT_fno_pascal_strings:
Daniel Dunbar2d6e9ee2010-06-14 20:20:41 +0000927 DAL->AddFlagArg(A, Opts.getOption(options::OPT_mno_pascal_strings));
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000928 break;
929 }
Daniel Dunbaraabb0b12009-03-25 06:12:34 +0000930 }
931
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000932 if (getTriple().getArch() == llvm::Triple::x86 ||
933 getTriple().getArch() == llvm::Triple::x86_64)
Daniel Dunbarfffd1812009-11-19 04:00:53 +0000934 if (!Args.hasArgNoClaim(options::OPT_mtune_EQ))
Craig Topper92fc2df2014-05-17 16:56:41 +0000935 DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_mtune_EQ),
936 "core2");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000937
938 // Add the arch options based on the particular spelling of -arch, to match
Chad Rosier7c5d9082012-04-27 14:58:16 +0000939 // how the driver driver works.
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000940 if (BoundArch) {
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000941 StringRef Name = BoundArch;
Michael J. Spencerfc790902012-10-19 22:36:40 +0000942 const Option MCpu = Opts.getOption(options::OPT_mcpu_EQ);
943 const Option MArch = Opts.getOption(options::OPT_march_EQ);
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000944
945 // This code must be kept in sync with LLVM's getArchTypeForDarwinArch,
946 // which defines the list of which architectures we accept.
947 if (Name == "ppc")
948 ;
949 else if (Name == "ppc601")
Craig Topper92fc2df2014-05-17 16:56:41 +0000950 DAL->AddJoinedArg(nullptr, MCpu, "601");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000951 else if (Name == "ppc603")
Craig Topper92fc2df2014-05-17 16:56:41 +0000952 DAL->AddJoinedArg(nullptr, MCpu, "603");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000953 else if (Name == "ppc604")
Craig Topper92fc2df2014-05-17 16:56:41 +0000954 DAL->AddJoinedArg(nullptr, MCpu, "604");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000955 else if (Name == "ppc604e")
Craig Topper92fc2df2014-05-17 16:56:41 +0000956 DAL->AddJoinedArg(nullptr, MCpu, "604e");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000957 else if (Name == "ppc750")
Craig Topper92fc2df2014-05-17 16:56:41 +0000958 DAL->AddJoinedArg(nullptr, MCpu, "750");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000959 else if (Name == "ppc7400")
Craig Topper92fc2df2014-05-17 16:56:41 +0000960 DAL->AddJoinedArg(nullptr, MCpu, "7400");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000961 else if (Name == "ppc7450")
Craig Topper92fc2df2014-05-17 16:56:41 +0000962 DAL->AddJoinedArg(nullptr, MCpu, "7450");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000963 else if (Name == "ppc970")
Craig Topper92fc2df2014-05-17 16:56:41 +0000964 DAL->AddJoinedArg(nullptr, MCpu, "970");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000965
Bill Schmidt778d3872013-07-26 01:36:11 +0000966 else if (Name == "ppc64" || Name == "ppc64le")
Craig Topper92fc2df2014-05-17 16:56:41 +0000967 DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64));
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000968
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000969 else if (Name == "i386")
970 ;
971 else if (Name == "i486")
Craig Topper92fc2df2014-05-17 16:56:41 +0000972 DAL->AddJoinedArg(nullptr, MArch, "i486");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000973 else if (Name == "i586")
Craig Topper92fc2df2014-05-17 16:56:41 +0000974 DAL->AddJoinedArg(nullptr, MArch, "i586");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000975 else if (Name == "i686")
Craig Topper92fc2df2014-05-17 16:56:41 +0000976 DAL->AddJoinedArg(nullptr, MArch, "i686");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000977 else if (Name == "pentium")
Craig Topper92fc2df2014-05-17 16:56:41 +0000978 DAL->AddJoinedArg(nullptr, MArch, "pentium");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000979 else if (Name == "pentium2")
Craig Topper92fc2df2014-05-17 16:56:41 +0000980 DAL->AddJoinedArg(nullptr, MArch, "pentium2");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000981 else if (Name == "pentpro")
Craig Topper92fc2df2014-05-17 16:56:41 +0000982 DAL->AddJoinedArg(nullptr, MArch, "pentiumpro");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000983 else if (Name == "pentIIm3")
Craig Topper92fc2df2014-05-17 16:56:41 +0000984 DAL->AddJoinedArg(nullptr, MArch, "pentium2");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000985
986 else if (Name == "x86_64")
Craig Topper92fc2df2014-05-17 16:56:41 +0000987 DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64));
Jim Grosbach82eee262013-11-16 00:53:35 +0000988 else if (Name == "x86_64h") {
Craig Topper92fc2df2014-05-17 16:56:41 +0000989 DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64));
990 DAL->AddJoinedArg(nullptr, MArch, "x86_64h");
Jim Grosbach82eee262013-11-16 00:53:35 +0000991 }
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000992
993 else if (Name == "arm")
Craig Topper92fc2df2014-05-17 16:56:41 +0000994 DAL->AddJoinedArg(nullptr, MArch, "armv4t");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000995 else if (Name == "armv4t")
Craig Topper92fc2df2014-05-17 16:56:41 +0000996 DAL->AddJoinedArg(nullptr, MArch, "armv4t");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000997 else if (Name == "armv5")
Craig Topper92fc2df2014-05-17 16:56:41 +0000998 DAL->AddJoinedArg(nullptr, MArch, "armv5tej");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000999 else if (Name == "xscale")
Craig Topper92fc2df2014-05-17 16:56:41 +00001000 DAL->AddJoinedArg(nullptr, MArch, "xscale");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +00001001 else if (Name == "armv6")
Craig Topper92fc2df2014-05-17 16:56:41 +00001002 DAL->AddJoinedArg(nullptr, MArch, "armv6k");
Bob Wilson743bf672013-03-04 22:37:49 +00001003 else if (Name == "armv6m")
Craig Topper92fc2df2014-05-17 16:56:41 +00001004 DAL->AddJoinedArg(nullptr, MArch, "armv6m");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +00001005 else if (Name == "armv7")
Craig Topper92fc2df2014-05-17 16:56:41 +00001006 DAL->AddJoinedArg(nullptr, MArch, "armv7a");
Bob Wilson743bf672013-03-04 22:37:49 +00001007 else if (Name == "armv7em")
Craig Topper92fc2df2014-05-17 16:56:41 +00001008 DAL->AddJoinedArg(nullptr, MArch, "armv7em");
Bob Wilsond7cf1042012-09-29 23:52:50 +00001009 else if (Name == "armv7k")
Craig Topper92fc2df2014-05-17 16:56:41 +00001010 DAL->AddJoinedArg(nullptr, MArch, "armv7k");
Bob Wilson743bf672013-03-04 22:37:49 +00001011 else if (Name == "armv7m")
Craig Topper92fc2df2014-05-17 16:56:41 +00001012 DAL->AddJoinedArg(nullptr, MArch, "armv7m");
Bob Wilsond7cf1042012-09-29 23:52:50 +00001013 else if (Name == "armv7s")
Craig Topper92fc2df2014-05-17 16:56:41 +00001014 DAL->AddJoinedArg(nullptr, MArch, "armv7s");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +00001015 }
Daniel Dunbar0af75a12009-03-25 06:58:31 +00001016
Tim Northover157d9112014-01-16 08:48:16 +00001017 return DAL;
1018}
1019
Vedant Kumar5fb00e42016-07-27 23:01:55 +00001020void MachO::AddLinkRuntimeLibArgs(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 Kumar5fb00e42016-07-27 23:01:55 +00001026 CompilerRT +=
1027 (tools::arm::getARMFloatABI(*this, Args) == 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 Kumar5fb00e42016-07-27 23:01:55 +00002921std::string MipsLLVMToolChain::getCompilerRT(const ArgList &Args,
2922 StringRef Component,
2923 bool Shared) const {
Vasileios Kalintirisc744e122015-11-12 15:26:54 +00002924 SmallString<128> Path(getDriver().ResourceDir);
2925 llvm::sys::path::append(Path, SelectedMultilib.osSuffix(), "lib" + LibSuffix,
2926 getOS());
2927 llvm::sys::path::append(Path, Twine("libclang_rt." + Component + "-" +
Vasileios Kalintirisbbc99302015-11-16 15:41:30 +00002928 "mips" + (Shared ? ".so" : ".a")));
Vasileios Kalintirisc744e122015-11-12 15:26:54 +00002929 return Path.str();
2930}
2931
Tony Linthicum76329bf2011-12-12 21:14:55 +00002932/// Hexagon Toolchain
2933
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00002934std::string HexagonToolChain::getHexagonTargetDir(
2935 const std::string &InstalledDir,
2936 const SmallVectorImpl<std::string> &PrefixDirs) const {
2937 std::string InstallRelDir;
2938 const Driver &D = getDriver();
2939
Matthew Curtis22dd8da2012-12-06 12:43:18 +00002940 // Locate the rest of the toolchain ...
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00002941 for (auto &I : PrefixDirs)
2942 if (D.getVFS().exists(I))
2943 return I;
Samuel Antaoc909c992014-11-07 17:48:03 +00002944
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00002945 if (getVFS().exists(InstallRelDir = InstalledDir + "/../target"))
Matthew Curtis22dd8da2012-12-06 12:43:18 +00002946 return InstallRelDir;
2947
Matthew Curtis22dd8da2012-12-06 12:43:18 +00002948 return InstallRelDir;
2949}
2950
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00002951Optional<unsigned> HexagonToolChain::getSmallDataThreshold(
2952 const ArgList &Args) {
2953 StringRef Gn = "";
2954 if (Arg *A = Args.getLastArg(options::OPT_G, options::OPT_G_EQ,
2955 options::OPT_msmall_data_threshold_EQ)) {
2956 Gn = A->getValue();
2957 } else if (Args.getLastArg(options::OPT_shared, options::OPT_fpic,
2958 options::OPT_fPIC)) {
2959 Gn = "0";
2960 }
Ikhlas Ajbar522e6192015-05-14 13:52:08 +00002961
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00002962 unsigned G;
2963 if (!Gn.getAsInteger(10, G))
2964 return G;
Ikhlas Ajbar522e6192015-05-14 13:52:08 +00002965
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00002966 return None;
Ikhlas Ajbar522e6192015-05-14 13:52:08 +00002967}
2968
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00002969void HexagonToolChain::getHexagonLibraryPaths(const ArgList &Args,
2970 ToolChain::path_list &LibPaths) const {
2971 const Driver &D = getDriver();
Matthew Curtise689b052012-12-06 15:46:07 +00002972
2973 //----------------------------------------------------------------------------
2974 // -L Args
2975 //----------------------------------------------------------------------------
Douglas Katzman6bbffc42015-06-25 18:51:37 +00002976 for (Arg *A : Args.filtered(options::OPT_L))
2977 for (const char *Value : A->getValues())
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00002978 LibPaths.push_back(Value);
Matthew Curtise689b052012-12-06 15:46:07 +00002979
2980 //----------------------------------------------------------------------------
2981 // Other standard paths
2982 //----------------------------------------------------------------------------
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00002983 std::vector<std::string> RootDirs;
Krzysztof Parzyszekf4467cd2016-01-06 14:13:11 +00002984 std::copy(D.PrefixDirs.begin(), D.PrefixDirs.end(),
2985 std::back_inserter(RootDirs));
Matthew Curtise689b052012-12-06 15:46:07 +00002986
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00002987 std::string TargetDir = getHexagonTargetDir(D.getInstalledDir(),
2988 D.PrefixDirs);
2989 if (std::find(RootDirs.begin(), RootDirs.end(), TargetDir) == RootDirs.end())
2990 RootDirs.push_back(TargetDir);
2991
2992 bool HasPIC = Args.hasArg(options::OPT_fpic, options::OPT_fPIC);
2993 // Assume G0 with -shared.
2994 bool HasG0 = Args.hasArg(options::OPT_shared);
2995 if (auto G = getSmallDataThreshold(Args))
2996 HasG0 = G.getValue() == 0;
2997
2998 const std::string CpuVer = GetTargetCPUVersion(Args).str();
2999 for (auto &Dir : RootDirs) {
3000 std::string LibDir = Dir + "/hexagon/lib";
3001 std::string LibDirCpu = LibDir + '/' + CpuVer;
3002 if (HasG0) {
3003 if (HasPIC)
3004 LibPaths.push_back(LibDirCpu + "/G0/pic");
3005 LibPaths.push_back(LibDirCpu + "/G0");
3006 }
3007 LibPaths.push_back(LibDirCpu);
3008 LibPaths.push_back(LibDir);
Matthew Curtise689b052012-12-06 15:46:07 +00003009 }
Matthew Curtise689b052012-12-06 15:46:07 +00003010}
3011
Douglas Katzman54366072015-07-27 16:53:08 +00003012HexagonToolChain::HexagonToolChain(const Driver &D, const llvm::Triple &Triple,
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00003013 const llvm::opt::ArgList &Args)
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003014 : Linux(D, Triple, Args) {
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00003015 const std::string TargetDir = getHexagonTargetDir(D.getInstalledDir(),
3016 D.PrefixDirs);
Matthew Curtis22dd8da2012-12-06 12:43:18 +00003017
3018 // Note: Generic_GCC::Generic_GCC adds InstalledDir and getDriver().Dir to
3019 // program paths
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00003020 const std::string BinDir(TargetDir + "/bin");
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003021 if (D.getVFS().exists(BinDir))
Matthew Curtis22dd8da2012-12-06 12:43:18 +00003022 getProgramPaths().push_back(BinDir);
3023
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00003024 ToolChain::path_list &LibPaths = getFilePaths();
Matthew Curtise689b052012-12-06 15:46:07 +00003025
3026 // Remove paths added by Linux toolchain. Currently Hexagon_TC really targets
3027 // 'elf' OS type, so the Linux paths are not appropriate. When we actually
3028 // support 'linux' we'll need to fix this up
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00003029 LibPaths.clear();
3030 getHexagonLibraryPaths(Args, LibPaths);
Tony Linthicum76329bf2011-12-12 21:14:55 +00003031}
3032
Angel Garcia Gomez637d1e62015-10-20 13:23:58 +00003033HexagonToolChain::~HexagonToolChain() {}
Tony Linthicum76329bf2011-12-12 21:14:55 +00003034
Douglas Katzman54366072015-07-27 16:53:08 +00003035Tool *HexagonToolChain::buildAssembler() const {
Douglas Katzman95354292015-06-23 20:42:09 +00003036 return new tools::hexagon::Assembler(*this);
Rafael Espindola7cf32212013-03-20 03:05:54 +00003037}
3038
Douglas Katzman54366072015-07-27 16:53:08 +00003039Tool *HexagonToolChain::buildLinker() const {
Douglas Katzman95354292015-06-23 20:42:09 +00003040 return new tools::hexagon::Linker(*this);
Tony Linthicum76329bf2011-12-12 21:14:55 +00003041}
3042
Douglas Katzman54366072015-07-27 16:53:08 +00003043void HexagonToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
3044 ArgStringList &CC1Args) const {
Matthew Curtis22dd8da2012-12-06 12:43:18 +00003045 if (DriverArgs.hasArg(options::OPT_nostdinc) ||
3046 DriverArgs.hasArg(options::OPT_nostdlibinc))
3047 return;
3048
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00003049 const Driver &D = getDriver();
3050 std::string TargetDir = getHexagonTargetDir(D.getInstalledDir(),
3051 D.PrefixDirs);
3052 addExternCSystemInclude(DriverArgs, CC1Args, TargetDir + "/hexagon/include");
Tony Linthicum76329bf2011-12-12 21:14:55 +00003053}
3054
Douglas Katzman54366072015-07-27 16:53:08 +00003055void HexagonToolChain::AddClangCXXStdlibIncludeArgs(
3056 const ArgList &DriverArgs, ArgStringList &CC1Args) const {
Matthew Curtis22dd8da2012-12-06 12:43:18 +00003057 if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
3058 DriverArgs.hasArg(options::OPT_nostdincxx))
3059 return;
3060
3061 const Driver &D = getDriver();
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00003062 std::string TargetDir = getHexagonTargetDir(D.InstalledDir, D.PrefixDirs);
3063 addSystemInclude(DriverArgs, CC1Args, TargetDir + "/hexagon/include/c++");
Chandler Carruth76a943b2012-11-19 03:52:03 +00003064}
Matthew Curtisf10a5952012-12-06 14:16:43 +00003065
Matthew Curtise689b052012-12-06 15:46:07 +00003066ToolChain::CXXStdlibType
Douglas Katzman54366072015-07-27 16:53:08 +00003067HexagonToolChain::GetCXXStdlibType(const ArgList &Args) const {
Matthew Curtise689b052012-12-06 15:46:07 +00003068 Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
3069 if (!A)
3070 return ToolChain::CST_Libstdcxx;
3071
3072 StringRef Value = A->getValue();
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00003073 if (Value != "libstdc++")
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003074 getDriver().Diag(diag::err_drv_invalid_stdlib_name) << A->getAsString(Args);
Matthew Curtise689b052012-12-06 15:46:07 +00003075
3076 return ToolChain::CST_Libstdcxx;
3077}
3078
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00003079//
3080// Returns the default CPU for Hexagon. This is the default compilation target
3081// if no Hexagon processor is selected at the command-line.
3082//
3083const StringRef HexagonToolChain::GetDefaultCPU() {
3084 return "hexagonv60";
Matthew Curtisf10a5952012-12-06 14:16:43 +00003085}
3086
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00003087const StringRef HexagonToolChain::GetTargetCPUVersion(const ArgList &Args) {
3088 Arg *CpuArg = nullptr;
Krzysztof Parzyszek972f72c2016-01-06 21:12:03 +00003089 if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ, options::OPT_march_EQ))
3090 CpuArg = A;
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00003091
3092 StringRef CPU = CpuArg ? CpuArg->getValue() : GetDefaultCPU();
3093 if (CPU.startswith("hexagon"))
3094 return CPU.substr(sizeof("hexagon") - 1);
3095 return CPU;
Matthew Curtisf10a5952012-12-06 14:16:43 +00003096}
Matthew Curtis22dd8da2012-12-06 12:43:18 +00003097// End Hexagon
Daniel Dunbardac54a82009-03-25 04:13:45 +00003098
Tom Stellard8fa33092015-07-18 01:49:05 +00003099/// AMDGPU Toolchain
3100AMDGPUToolChain::AMDGPUToolChain(const Driver &D, const llvm::Triple &Triple,
3101 const ArgList &Args)
3102 : Generic_ELF(D, Triple, Args) { }
3103
3104Tool *AMDGPUToolChain::buildLinker() const {
3105 return new tools::amdgpu::Linker(*this);
3106}
3107// End AMDGPU
3108
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003109/// NaCl Toolchain
Douglas Katzman54366072015-07-27 16:53:08 +00003110NaClToolChain::NaClToolChain(const Driver &D, const llvm::Triple &Triple,
3111 const ArgList &Args)
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003112 : Generic_ELF(D, Triple, Args) {
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003113
3114 // Remove paths added by Generic_GCC. NaCl Toolchain cannot use the
3115 // default paths, and must instead only use the paths provided
3116 // with this toolchain based on architecture.
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003117 path_list &file_paths = getFilePaths();
3118 path_list &prog_paths = getProgramPaths();
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003119
3120 file_paths.clear();
3121 prog_paths.clear();
3122
3123 // Path for library files (libc.a, ...)
3124 std::string FilePath(getDriver().Dir + "/../");
3125
3126 // Path for tools (clang, ld, etc..)
3127 std::string ProgPath(getDriver().Dir + "/../");
3128
3129 // Path for toolchain libraries (libgcc.a, ...)
3130 std::string ToolPath(getDriver().ResourceDir + "/lib/");
3131
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003132 switch (Triple.getArch()) {
Hans Wennborgdcfba332015-10-06 23:40:43 +00003133 case llvm::Triple::x86:
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003134 file_paths.push_back(FilePath + "x86_64-nacl/lib32");
Derek Schuff9afb0502015-08-26 17:14:08 +00003135 file_paths.push_back(FilePath + "i686-nacl/usr/lib");
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003136 prog_paths.push_back(ProgPath + "x86_64-nacl/bin");
3137 file_paths.push_back(ToolPath + "i686-nacl");
3138 break;
Hans Wennborgdcfba332015-10-06 23:40:43 +00003139 case llvm::Triple::x86_64:
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003140 file_paths.push_back(FilePath + "x86_64-nacl/lib");
3141 file_paths.push_back(FilePath + "x86_64-nacl/usr/lib");
3142 prog_paths.push_back(ProgPath + "x86_64-nacl/bin");
3143 file_paths.push_back(ToolPath + "x86_64-nacl");
3144 break;
Hans Wennborgdcfba332015-10-06 23:40:43 +00003145 case llvm::Triple::arm:
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003146 file_paths.push_back(FilePath + "arm-nacl/lib");
3147 file_paths.push_back(FilePath + "arm-nacl/usr/lib");
3148 prog_paths.push_back(ProgPath + "arm-nacl/bin");
3149 file_paths.push_back(ToolPath + "arm-nacl");
3150 break;
Hans Wennborgdcfba332015-10-06 23:40:43 +00003151 case llvm::Triple::mipsel:
Petar Jovanovic26a4a402015-07-08 13:07:31 +00003152 file_paths.push_back(FilePath + "mipsel-nacl/lib");
3153 file_paths.push_back(FilePath + "mipsel-nacl/usr/lib");
3154 prog_paths.push_back(ProgPath + "bin");
3155 file_paths.push_back(ToolPath + "mipsel-nacl");
3156 break;
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003157 default:
3158 break;
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003159 }
3160
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003161 NaClArmMacrosPath = GetFilePath("nacl-arm-macros.s");
3162}
3163
Douglas Katzman54366072015-07-27 16:53:08 +00003164void NaClToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
3165 ArgStringList &CC1Args) const {
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003166 const Driver &D = getDriver();
3167 if (DriverArgs.hasArg(options::OPT_nostdinc))
3168 return;
3169
3170 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
3171 SmallString<128> P(D.ResourceDir);
3172 llvm::sys::path::append(P, "include");
3173 addSystemInclude(DriverArgs, CC1Args, P.str());
3174 }
3175
3176 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
3177 return;
3178
3179 SmallString<128> P(D.Dir + "/../");
Douglas Katzman7e37afb2015-06-23 03:02:39 +00003180 switch (getTriple().getArch()) {
Derek Schuff9afb0502015-08-26 17:14:08 +00003181 case llvm::Triple::x86:
3182 // x86 is special because multilib style uses x86_64-nacl/include for libc
3183 // headers but the SDK wants i686-nacl/usr/include. The other architectures
3184 // have the same substring.
3185 llvm::sys::path::append(P, "i686-nacl/usr/include");
3186 addSystemInclude(DriverArgs, CC1Args, P.str());
3187 llvm::sys::path::remove_filename(P);
3188 llvm::sys::path::remove_filename(P);
3189 llvm::sys::path::remove_filename(P);
3190 llvm::sys::path::append(P, "x86_64-nacl/include");
3191 addSystemInclude(DriverArgs, CC1Args, P.str());
3192 return;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00003193 case llvm::Triple::arm:
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003194 llvm::sys::path::append(P, "arm-nacl/usr/include");
Douglas Katzman7e37afb2015-06-23 03:02:39 +00003195 break;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00003196 case llvm::Triple::x86_64:
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003197 llvm::sys::path::append(P, "x86_64-nacl/usr/include");
Douglas Katzman7e37afb2015-06-23 03:02:39 +00003198 break;
Petar Jovanovic26a4a402015-07-08 13:07:31 +00003199 case llvm::Triple::mipsel:
3200 llvm::sys::path::append(P, "mipsel-nacl/usr/include");
3201 break;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00003202 default:
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003203 return;
3204 }
3205
3206 addSystemInclude(DriverArgs, CC1Args, P.str());
3207 llvm::sys::path::remove_filename(P);
3208 llvm::sys::path::remove_filename(P);
3209 llvm::sys::path::append(P, "include");
3210 addSystemInclude(DriverArgs, CC1Args, P.str());
3211}
3212
Douglas Katzman54366072015-07-27 16:53:08 +00003213void NaClToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
3214 ArgStringList &CmdArgs) const {
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003215 // Check for -stdlib= flags. We only support libc++ but this consumes the arg
3216 // if the value is libc++, and emits an error for other values.
3217 GetCXXStdlibType(Args);
3218 CmdArgs.push_back("-lc++");
3219}
3220
Douglas Katzman54366072015-07-27 16:53:08 +00003221void NaClToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
3222 ArgStringList &CC1Args) const {
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003223 const Driver &D = getDriver();
3224 if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
3225 DriverArgs.hasArg(options::OPT_nostdincxx))
3226 return;
3227
3228 // Check for -stdlib= flags. We only support libc++ but this consumes the arg
3229 // if the value is libc++, and emits an error for other values.
3230 GetCXXStdlibType(DriverArgs);
3231
Douglas Katzman7e37afb2015-06-23 03:02:39 +00003232 SmallString<128> P(D.Dir + "/../");
3233 switch (getTriple().getArch()) {
3234 case llvm::Triple::arm:
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003235 llvm::sys::path::append(P, "arm-nacl/include/c++/v1");
3236 addSystemInclude(DriverArgs, CC1Args, P.str());
Douglas Katzman7e37afb2015-06-23 03:02:39 +00003237 break;
3238 case llvm::Triple::x86:
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003239 llvm::sys::path::append(P, "x86_64-nacl/include/c++/v1");
3240 addSystemInclude(DriverArgs, CC1Args, P.str());
Douglas Katzman7e37afb2015-06-23 03:02:39 +00003241 break;
3242 case llvm::Triple::x86_64:
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003243 llvm::sys::path::append(P, "x86_64-nacl/include/c++/v1");
3244 addSystemInclude(DriverArgs, CC1Args, P.str());
Douglas Katzman7e37afb2015-06-23 03:02:39 +00003245 break;
Petar Jovanovic26a4a402015-07-08 13:07:31 +00003246 case llvm::Triple::mipsel:
3247 llvm::sys::path::append(P, "mipsel-nacl/include/c++/v1");
3248 addSystemInclude(DriverArgs, CC1Args, P.str());
3249 break;
Douglas Katzman9ad0ec22015-06-23 04:20:44 +00003250 default:
3251 break;
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003252 }
3253}
3254
Douglas Katzman54366072015-07-27 16:53:08 +00003255ToolChain::CXXStdlibType
3256NaClToolChain::GetCXXStdlibType(const ArgList &Args) const {
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003257 if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) {
3258 StringRef Value = A->getValue();
3259 if (Value == "libc++")
3260 return ToolChain::CST_Libcxx;
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003261 getDriver().Diag(diag::err_drv_invalid_stdlib_name) << A->getAsString(Args);
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003262 }
3263
3264 return ToolChain::CST_Libcxx;
3265}
3266
Douglas Katzman54366072015-07-27 16:53:08 +00003267std::string
3268NaClToolChain::ComputeEffectiveClangTriple(const ArgList &Args,
3269 types::ID InputType) const {
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003270 llvm::Triple TheTriple(ComputeLLVMTriple(Args, InputType));
3271 if (TheTriple.getArch() == llvm::Triple::arm &&
3272 TheTriple.getEnvironment() == llvm::Triple::UnknownEnvironment)
3273 TheTriple.setEnvironment(llvm::Triple::GNUEABIHF);
3274 return TheTriple.getTriple();
3275}
3276
Douglas Katzman54366072015-07-27 16:53:08 +00003277Tool *NaClToolChain::buildLinker() const {
Douglas Katzman95354292015-06-23 20:42:09 +00003278 return new tools::nacltools::Linker(*this);
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003279}
3280
Douglas Katzman54366072015-07-27 16:53:08 +00003281Tool *NaClToolChain::buildAssembler() const {
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003282 if (getTriple().getArch() == llvm::Triple::arm)
Douglas Katzman95354292015-06-23 20:42:09 +00003283 return new tools::nacltools::AssemblerARM(*this);
3284 return new tools::gnutools::Assembler(*this);
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003285}
3286// End NaCl
3287
Chris Lattner09797542010-03-04 21:07:38 +00003288/// TCEToolChain - A tool chain using the llvm bitcode tools to perform
3289/// all subcommands. See http://tce.cs.tut.fi for our peculiar target.
3290/// Currently does not support anything else but compilation.
3291
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003292TCEToolChain::TCEToolChain(const Driver &D, const llvm::Triple &Triple,
Rafael Espindola84b588b2013-03-18 18:10:27 +00003293 const ArgList &Args)
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003294 : ToolChain(D, Triple, Args) {
Chris Lattner09797542010-03-04 21:07:38 +00003295 // Path mangling to find libexec
3296 std::string Path(getDriver().Dir);
3297
3298 Path += "/../libexec";
3299 getProgramPaths().push_back(Path);
3300}
3301
Angel Garcia Gomez637d1e62015-10-20 13:23:58 +00003302TCEToolChain::~TCEToolChain() {}
Chris Lattner09797542010-03-04 21:07:38 +00003303
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003304bool TCEToolChain::IsMathErrnoDefault() const { return true; }
Chris Lattner09797542010-03-04 21:07:38 +00003305
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003306bool TCEToolChain::isPICDefault() const { return false; }
Chris Lattner09797542010-03-04 21:07:38 +00003307
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003308bool TCEToolChain::isPIEDefault() const { return false; }
Peter Collingbourne54d770c2013-04-09 04:35:11 +00003309
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003310bool TCEToolChain::isPICDefaultForced() const { return false; }
Chris Lattner09797542010-03-04 21:07:38 +00003311
Ed Schouten3c3e58c2015-03-26 11:13:44 +00003312// CloudABI - CloudABI tool chain which can call ld(1) directly.
3313
3314CloudABI::CloudABI(const Driver &D, const llvm::Triple &Triple,
3315 const ArgList &Args)
3316 : Generic_ELF(D, Triple, Args) {
3317 SmallString<128> P(getDriver().Dir);
3318 llvm::sys::path::append(P, "..", getTriple().str(), "lib");
3319 getFilePaths().push_back(P.str());
3320}
3321
3322void CloudABI::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
3323 ArgStringList &CC1Args) const {
3324 if (DriverArgs.hasArg(options::OPT_nostdlibinc) &&
3325 DriverArgs.hasArg(options::OPT_nostdincxx))
3326 return;
3327
3328 SmallString<128> P(getDriver().Dir);
3329 llvm::sys::path::append(P, "..", getTriple().str(), "include/c++/v1");
3330 addSystemInclude(DriverArgs, CC1Args, P.str());
3331}
3332
3333void CloudABI::AddCXXStdlibLibArgs(const ArgList &Args,
3334 ArgStringList &CmdArgs) const {
3335 CmdArgs.push_back("-lc++");
3336 CmdArgs.push_back("-lc++abi");
3337 CmdArgs.push_back("-lunwind");
3338}
3339
Douglas Katzman95354292015-06-23 20:42:09 +00003340Tool *CloudABI::buildLinker() const {
3341 return new tools::cloudabi::Linker(*this);
3342}
Ed Schouten3c3e58c2015-03-26 11:13:44 +00003343
Ed Schouten51bfbe72016-02-17 18:56:20 +00003344SanitizerMask CloudABI::getSupportedSanitizers() const {
3345 SanitizerMask Res = ToolChain::getSupportedSanitizers();
3346 Res |= SanitizerKind::SafeStack;
3347 return Res;
3348}
3349
Ed Schoutenfc79d2c2016-03-29 21:13:53 +00003350SanitizerMask CloudABI::getDefaultSanitizers() const {
3351 return SanitizerKind::SafeStack;
3352}
3353
Reid Kleckner330fb172016-05-11 16:19:05 +00003354/// Haiku - Haiku tool chain which can call as(1) and ld(1) directly.
3355
3356Haiku::Haiku(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
3357 : Generic_ELF(D, Triple, Args) {
3358
3359}
3360
3361void Haiku::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
3362 ArgStringList &CC1Args) const {
3363 if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
3364 DriverArgs.hasArg(options::OPT_nostdincxx))
3365 return;
3366
3367 switch (GetCXXStdlibType(DriverArgs)) {
3368 case ToolChain::CST_Libcxx:
3369 addSystemInclude(DriverArgs, CC1Args,
3370 getDriver().SysRoot + "/system/develop/headers/c++/v1");
3371 break;
3372 case ToolChain::CST_Libstdcxx:
3373 addSystemInclude(DriverArgs, CC1Args,
3374 getDriver().SysRoot + "/system/develop/headers/c++");
3375 addSystemInclude(DriverArgs, CC1Args,
3376 getDriver().SysRoot + "/system/develop/headers/c++/backward");
3377
3378 StringRef Triple = getTriple().str();
3379 addSystemInclude(DriverArgs, CC1Args,
3380 getDriver().SysRoot + "/system/develop/headers/c++/" +
3381 Triple);
3382 break;
3383 }
3384}
3385
Daniel Dunbar10de9e62009-06-29 20:52:51 +00003386/// OpenBSD - OpenBSD tool chain which can call as(1) and ld(1) directly.
3387
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003388OpenBSD::OpenBSD(const Driver &D, const llvm::Triple &Triple,
3389 const ArgList &Args)
3390 : Generic_ELF(D, Triple, Args) {
Daniel Dunbar083edf72009-12-21 18:54:17 +00003391 getFilePaths().push_back(getDriver().Dir + "/../lib");
Daniel Dunbar10de9e62009-06-29 20:52:51 +00003392 getFilePaths().push_back("/usr/lib");
3393}
3394
Rafael Espindola7cf32212013-03-20 03:05:54 +00003395Tool *OpenBSD::buildAssembler() const {
Douglas Katzman95354292015-06-23 20:42:09 +00003396 return new tools::openbsd::Assembler(*this);
Rafael Espindola7cf32212013-03-20 03:05:54 +00003397}
3398
Douglas Katzman95354292015-06-23 20:42:09 +00003399Tool *OpenBSD::buildLinker() const { return new tools::openbsd::Linker(*this); }
Daniel Dunbar10de9e62009-06-29 20:52:51 +00003400
Eli Friedman9fa28852012-08-08 23:57:20 +00003401/// Bitrig - Bitrig tool chain which can call as(1) and ld(1) directly.
3402
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003403Bitrig::Bitrig(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
3404 : Generic_ELF(D, Triple, Args) {
Eli Friedman9fa28852012-08-08 23:57:20 +00003405 getFilePaths().push_back(getDriver().Dir + "/../lib");
3406 getFilePaths().push_back("/usr/lib");
3407}
3408
Rafael Espindola7cf32212013-03-20 03:05:54 +00003409Tool *Bitrig::buildAssembler() const {
Douglas Katzman95354292015-06-23 20:42:09 +00003410 return new tools::bitrig::Assembler(*this);
Rafael Espindola7cf32212013-03-20 03:05:54 +00003411}
3412
Douglas Katzman95354292015-06-23 20:42:09 +00003413Tool *Bitrig::buildLinker() const { return new tools::bitrig::Linker(*this); }
Eli Friedman9fa28852012-08-08 23:57:20 +00003414
Jonas Hahnfeldaae83742016-02-12 07:48:37 +00003415ToolChain::CXXStdlibType Bitrig::GetDefaultCXXStdlibType() const {
Richard Smith51af5192014-05-01 23:24:24 +00003416 return ToolChain::CST_Libcxx;
3417}
3418
Eli Friedman9fa28852012-08-08 23:57:20 +00003419void Bitrig::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
3420 ArgStringList &CC1Args) const {
3421 if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
3422 DriverArgs.hasArg(options::OPT_nostdincxx))
3423 return;
3424
Chandler Carruthc0f5cd12012-10-08 21:31:38 +00003425 switch (GetCXXStdlibType(DriverArgs)) {
3426 case ToolChain::CST_Libcxx:
3427 addSystemInclude(DriverArgs, CC1Args,
Richard Smith51af5192014-05-01 23:24:24 +00003428 getDriver().SysRoot + "/usr/include/c++/v1");
Chandler Carruthc0f5cd12012-10-08 21:31:38 +00003429 break;
3430 case ToolChain::CST_Libstdcxx:
3431 addSystemInclude(DriverArgs, CC1Args,
3432 getDriver().SysRoot + "/usr/include/c++/stdc++");
3433 addSystemInclude(DriverArgs, CC1Args,
3434 getDriver().SysRoot + "/usr/include/c++/stdc++/backward");
Eli Friedman9fa28852012-08-08 23:57:20 +00003435
Chandler Carruthc0f5cd12012-10-08 21:31:38 +00003436 StringRef Triple = getTriple().str();
3437 if (Triple.startswith("amd64"))
3438 addSystemInclude(DriverArgs, CC1Args,
3439 getDriver().SysRoot + "/usr/include/c++/stdc++/x86_64" +
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003440 Triple.substr(5));
Chandler Carruthc0f5cd12012-10-08 21:31:38 +00003441 else
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003442 addSystemInclude(DriverArgs, CC1Args, getDriver().SysRoot +
3443 "/usr/include/c++/stdc++/" +
3444 Triple);
Chandler Carruthc0f5cd12012-10-08 21:31:38 +00003445 break;
3446 }
Eli Friedman9fa28852012-08-08 23:57:20 +00003447}
3448
3449void Bitrig::AddCXXStdlibLibArgs(const ArgList &Args,
3450 ArgStringList &CmdArgs) const {
Chandler Carruthc0f5cd12012-10-08 21:31:38 +00003451 switch (GetCXXStdlibType(Args)) {
3452 case ToolChain::CST_Libcxx:
3453 CmdArgs.push_back("-lc++");
Richard Smith51af5192014-05-01 23:24:24 +00003454 CmdArgs.push_back("-lc++abi");
3455 CmdArgs.push_back("-lpthread");
Chandler Carruthc0f5cd12012-10-08 21:31:38 +00003456 break;
3457 case ToolChain::CST_Libstdcxx:
3458 CmdArgs.push_back("-lstdc++");
3459 break;
3460 }
Eli Friedman9fa28852012-08-08 23:57:20 +00003461}
3462
Daniel Dunbare24297c2009-03-30 21:06:03 +00003463/// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly.
3464
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003465FreeBSD::FreeBSD(const Driver &D, const llvm::Triple &Triple,
3466 const ArgList &Args)
3467 : Generic_ELF(D, Triple, Args) {
Daniel Dunbara18a4872010-08-02 05:43:59 +00003468
Chandler Carruth0b1756b2012-01-26 01:35:15 +00003469 // When targeting 32-bit platforms, look for '/usr/lib32/crt1.o' and fall
3470 // back to '/usr/lib' if it doesn't exist.
Chandler Carruthf7bf3db2012-01-25 11:24:24 +00003471 if ((Triple.getArch() == llvm::Triple::x86 ||
3472 Triple.getArch() == llvm::Triple::ppc) &&
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003473 D.getVFS().exists(getDriver().SysRoot + "/usr/lib32/crt1.o"))
Chandler Carruthf7bf3db2012-01-25 11:24:24 +00003474 getFilePaths().push_back(getDriver().SysRoot + "/usr/lib32");
3475 else
3476 getFilePaths().push_back(getDriver().SysRoot + "/usr/lib");
Daniel Dunbare24297c2009-03-30 21:06:03 +00003477}
3478
Jonas Hahnfeld09954192016-03-14 14:34:04 +00003479ToolChain::CXXStdlibType FreeBSD::GetDefaultCXXStdlibType() const {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003480 if (getTriple().getOSMajorVersion() >= 10)
David Chisnall867ccd82013-11-09 15:10:56 +00003481 return ToolChain::CST_Libcxx;
3482 return ToolChain::CST_Libstdcxx;
3483}
3484
3485void FreeBSD::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
3486 ArgStringList &CC1Args) const {
3487 if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
3488 DriverArgs.hasArg(options::OPT_nostdincxx))
3489 return;
3490
3491 switch (GetCXXStdlibType(DriverArgs)) {
3492 case ToolChain::CST_Libcxx:
3493 addSystemInclude(DriverArgs, CC1Args,
3494 getDriver().SysRoot + "/usr/include/c++/v1");
3495 break;
3496 case ToolChain::CST_Libstdcxx:
3497 addSystemInclude(DriverArgs, CC1Args,
3498 getDriver().SysRoot + "/usr/include/c++/4.2");
3499 addSystemInclude(DriverArgs, CC1Args,
3500 getDriver().SysRoot + "/usr/include/c++/4.2/backward");
3501 break;
3502 }
3503}
3504
Dimitry Andric60907392016-02-14 16:08:20 +00003505void FreeBSD::AddCXXStdlibLibArgs(const ArgList &Args,
3506 ArgStringList &CmdArgs) const {
3507 CXXStdlibType Type = GetCXXStdlibType(Args);
3508 bool Profiling = Args.hasArg(options::OPT_pg);
3509
3510 switch (Type) {
3511 case ToolChain::CST_Libcxx:
3512 CmdArgs.push_back(Profiling ? "-lc++_p" : "-lc++");
3513 break;
3514
3515 case ToolChain::CST_Libstdcxx:
3516 CmdArgs.push_back(Profiling ? "-lstdc++_p" : "-lstdc++");
3517 break;
3518 }
3519}
3520
Rafael Espindola7cf32212013-03-20 03:05:54 +00003521Tool *FreeBSD::buildAssembler() const {
Douglas Katzman95354292015-06-23 20:42:09 +00003522 return new tools::freebsd::Assembler(*this);
Rafael Espindola7cf32212013-03-20 03:05:54 +00003523}
3524
Douglas Katzman95354292015-06-23 20:42:09 +00003525Tool *FreeBSD::buildLinker() const { return new tools::freebsd::Linker(*this); }
Daniel Dunbarcc912342009-05-02 18:28:39 +00003526
Tim Northovere931f9f2015-10-30 16:30:41 +00003527bool FreeBSD::UseSjLjExceptions(const ArgList &Args) const {
Rafael Espindola0f207ed2012-12-13 04:17:14 +00003528 // FreeBSD uses SjLj exceptions on ARM oabi.
3529 switch (getTriple().getEnvironment()) {
Renato Golinf4421f72014-02-19 10:44:07 +00003530 case llvm::Triple::GNUEABIHF:
Rafael Espindola0f207ed2012-12-13 04:17:14 +00003531 case llvm::Triple::GNUEABI:
3532 case llvm::Triple::EABI:
3533 return false;
3534
3535 default:
3536 return (getTriple().getArch() == llvm::Triple::arm ||
3537 getTriple().getArch() == llvm::Triple::thumb);
3538 }
3539}
3540
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003541bool FreeBSD::HasNativeLLVMSupport() const { return true; }
Alexey Samsonove65ceb92014-02-25 13:26:03 +00003542
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003543bool FreeBSD::isPIEDefault() const { return getSanitizerArgs().requiresPIE(); }
Alexey Samsonove65ceb92014-02-25 13:26:03 +00003544
Alexey Samsonov7f2a0d22015-06-19 21:36:47 +00003545SanitizerMask FreeBSD::getSupportedSanitizers() const {
3546 const bool IsX86 = getTriple().getArch() == llvm::Triple::x86;
3547 const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64;
3548 const bool IsMIPS64 = getTriple().getArch() == llvm::Triple::mips64 ||
3549 getTriple().getArch() == llvm::Triple::mips64el;
3550 SanitizerMask Res = ToolChain::getSupportedSanitizers();
3551 Res |= SanitizerKind::Address;
3552 Res |= SanitizerKind::Vptr;
3553 if (IsX86_64 || IsMIPS64) {
3554 Res |= SanitizerKind::Leak;
3555 Res |= SanitizerKind::Thread;
3556 }
3557 if (IsX86 || IsX86_64) {
3558 Res |= SanitizerKind::SafeStack;
3559 }
3560 return Res;
3561}
3562
Benjamin Kramer24f1d3e2011-02-02 18:59:27 +00003563/// NetBSD - NetBSD tool chain which can call as(1) and ld(1) directly.
3564
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003565NetBSD::NetBSD(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
3566 : Generic_ELF(D, Triple, Args) {
Joerg Sonnenbergerbc923f32011-03-21 13:59:26 +00003567 if (getDriver().UseStdLib) {
Chandler Carruth1ccbed82012-01-25 11:18:20 +00003568 // When targeting a 32-bit platform, try the special directory used on
3569 // 64-bit hosts, and only fall back to the main library directory if that
3570 // doesn't work.
3571 // FIXME: It'd be nicer to test if this directory exists, but I'm not sure
3572 // what all logic is needed to emulate the '=' prefix here.
Joerg Sonnenberger25de31d2014-02-02 22:47:37 +00003573 switch (Triple.getArch()) {
3574 case llvm::Triple::x86:
Joerg Sonnenbergerbc923f32011-03-21 13:59:26 +00003575 getFilePaths().push_back("=/usr/lib/i386");
Joerg Sonnenberger25de31d2014-02-02 22:47:37 +00003576 break;
3577 case llvm::Triple::arm:
Joerg Sonnenberger3a6c28a2014-05-07 08:24:23 +00003578 case llvm::Triple::armeb:
Joerg Sonnenberger25de31d2014-02-02 22:47:37 +00003579 case llvm::Triple::thumb:
Joerg Sonnenberger3a6c28a2014-05-07 08:24:23 +00003580 case llvm::Triple::thumbeb:
Joerg Sonnenberger25de31d2014-02-02 22:47:37 +00003581 switch (Triple.getEnvironment()) {
3582 case llvm::Triple::EABI:
Joerg Sonnenberger25de31d2014-02-02 22:47:37 +00003583 case llvm::Triple::GNUEABI:
Joerg Sonnenberger25de31d2014-02-02 22:47:37 +00003584 getFilePaths().push_back("=/usr/lib/eabi");
3585 break;
Joerg Sonnenberger17a80e42014-08-09 19:01:52 +00003586 case llvm::Triple::EABIHF:
3587 case llvm::Triple::GNUEABIHF:
3588 getFilePaths().push_back("=/usr/lib/eabihf");
3589 break;
Joerg Sonnenberger25de31d2014-02-02 22:47:37 +00003590 default:
3591 getFilePaths().push_back("=/usr/lib/oabi");
3592 break;
3593 }
3594 break;
Joerg Sonnenbergere7f97592014-02-02 22:59:16 +00003595 case llvm::Triple::mips64:
3596 case llvm::Triple::mips64el:
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00003597 if (tools::mips::hasMipsAbiArg(Args, "o32"))
Joerg Sonnenbergere7f97592014-02-02 22:59:16 +00003598 getFilePaths().push_back("=/usr/lib/o32");
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00003599 else if (tools::mips::hasMipsAbiArg(Args, "64"))
Joerg Sonnenbergere7f97592014-02-02 22:59:16 +00003600 getFilePaths().push_back("=/usr/lib/64");
3601 break;
Joerg Sonnenbergerdd13b302014-08-13 14:17:32 +00003602 case llvm::Triple::ppc:
3603 getFilePaths().push_back("=/usr/lib/powerpc");
3604 break;
Joerg Sonnenberger8280abe2014-04-16 20:44:17 +00003605 case llvm::Triple::sparc:
3606 getFilePaths().push_back("=/usr/lib/sparc");
3607 break;
Joerg Sonnenberger25de31d2014-02-02 22:47:37 +00003608 default:
3609 break;
3610 }
Chandler Carruth1ccbed82012-01-25 11:18:20 +00003611
3612 getFilePaths().push_back("=/usr/lib");
Benjamin Kramer24f1d3e2011-02-02 18:59:27 +00003613 }
3614}
3615
Rafael Espindola7cf32212013-03-20 03:05:54 +00003616Tool *NetBSD::buildAssembler() const {
Douglas Katzman95354292015-06-23 20:42:09 +00003617 return new tools::netbsd::Assembler(*this);
Rafael Espindola7cf32212013-03-20 03:05:54 +00003618}
3619
Douglas Katzman95354292015-06-23 20:42:09 +00003620Tool *NetBSD::buildLinker() const { return new tools::netbsd::Linker(*this); }
Benjamin Kramer24f1d3e2011-02-02 18:59:27 +00003621
Jonas Hahnfeld09954192016-03-14 14:34:04 +00003622ToolChain::CXXStdlibType NetBSD::GetDefaultCXXStdlibType() const {
Joerg Sonnenbergera4435632013-10-14 20:13:05 +00003623 unsigned Major, Minor, Micro;
3624 getTriple().getOSVersion(Major, Minor, Micro);
Joerg Sonnenberger21156e82016-02-11 23:35:03 +00003625 if (Major >= 7 || Major == 0) {
Joerg Sonnenbergerd769a1e2014-01-18 00:50:49 +00003626 switch (getArch()) {
Joerg Sonnenberger323cea92014-08-09 18:28:36 +00003627 case llvm::Triple::aarch64:
Joerg Sonnenberger1ea66472014-05-07 08:45:26 +00003628 case llvm::Triple::arm:
3629 case llvm::Triple::armeb:
3630 case llvm::Triple::thumb:
3631 case llvm::Triple::thumbeb:
Joerg Sonnenbergerc8887572014-07-25 20:57:24 +00003632 case llvm::Triple::ppc:
Joerg Sonnenbergerdd13b302014-08-13 14:17:32 +00003633 case llvm::Triple::ppc64:
3634 case llvm::Triple::ppc64le:
Joerg Sonnenberger059613c2016-02-11 23:18:36 +00003635 case llvm::Triple::sparc:
3636 case llvm::Triple::sparcv9:
Joerg Sonnenbergerd769a1e2014-01-18 00:50:49 +00003637 case llvm::Triple::x86:
3638 case llvm::Triple::x86_64:
Joerg Sonnenbergera4435632013-10-14 20:13:05 +00003639 return ToolChain::CST_Libcxx;
Joerg Sonnenbergerd769a1e2014-01-18 00:50:49 +00003640 default:
3641 break;
3642 }
Joerg Sonnenbergera4435632013-10-14 20:13:05 +00003643 }
Joerg Sonnenberger428ef1e2013-04-30 01:21:43 +00003644 return ToolChain::CST_Libstdcxx;
3645}
3646
3647void NetBSD::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
3648 ArgStringList &CC1Args) const {
3649 if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
3650 DriverArgs.hasArg(options::OPT_nostdincxx))
3651 return;
3652
3653 switch (GetCXXStdlibType(DriverArgs)) {
3654 case ToolChain::CST_Libcxx:
3655 addSystemInclude(DriverArgs, CC1Args,
3656 getDriver().SysRoot + "/usr/include/c++/");
3657 break;
3658 case ToolChain::CST_Libstdcxx:
3659 addSystemInclude(DriverArgs, CC1Args,
3660 getDriver().SysRoot + "/usr/include/g++");
3661 addSystemInclude(DriverArgs, CC1Args,
3662 getDriver().SysRoot + "/usr/include/g++/backward");
3663 break;
3664 }
3665}
3666
Chris Lattner3e2ee142010-07-07 16:01:42 +00003667/// Minix - Minix tool chain which can call as(1) and ld(1) directly.
3668
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003669Minix::Minix(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
3670 : Generic_ELF(D, Triple, Args) {
Chris Lattner3e2ee142010-07-07 16:01:42 +00003671 getFilePaths().push_back(getDriver().Dir + "/../lib");
3672 getFilePaths().push_back("/usr/lib");
Chris Lattner3e2ee142010-07-07 16:01:42 +00003673}
3674
Rafael Espindola7cf32212013-03-20 03:05:54 +00003675Tool *Minix::buildAssembler() const {
Douglas Katzman95354292015-06-23 20:42:09 +00003676 return new tools::minix::Assembler(*this);
Rafael Espindola7cf32212013-03-20 03:05:54 +00003677}
3678
Douglas Katzman95354292015-06-23 20:42:09 +00003679Tool *Minix::buildLinker() const { return new tools::minix::Linker(*this); }
Chris Lattner3e2ee142010-07-07 16:01:42 +00003680
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003681static void addPathIfExists(const Driver &D, const Twine &Path,
3682 ToolChain::path_list &Paths) {
3683 if (D.getVFS().exists(Path))
Rafael Espindolac53c5b12015-08-31 19:17:51 +00003684 Paths.push_back(Path.str());
3685}
3686
David Chisnallf571cde2012-02-15 13:39:01 +00003687/// Solaris - Solaris tool chain which can call as(1) and ld(1) directly.
3688
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003689Solaris::Solaris(const Driver &D, const llvm::Triple &Triple,
Rafael Espindola1af7c212012-02-19 01:38:32 +00003690 const ArgList &Args)
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003691 : Generic_GCC(D, Triple, Args) {
David Chisnallf571cde2012-02-15 13:39:01 +00003692
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003693 GCCInstallation.init(Triple, Args);
David Chisnallf571cde2012-02-15 13:39:01 +00003694
Rafael Espindolac53c5b12015-08-31 19:17:51 +00003695 path_list &Paths = getFilePaths();
3696 if (GCCInstallation.isValid())
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003697 addPathIfExists(D, GCCInstallation.getInstallPath(), Paths);
Rafael Espindolac53c5b12015-08-31 19:17:51 +00003698
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003699 addPathIfExists(D, getDriver().getInstalledDir(), Paths);
Rafael Espindolac53c5b12015-08-31 19:17:51 +00003700 if (getDriver().getInstalledDir() != getDriver().Dir)
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003701 addPathIfExists(D, getDriver().Dir, Paths);
Rafael Espindolac53c5b12015-08-31 19:17:51 +00003702
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003703 addPathIfExists(D, getDriver().SysRoot + getDriver().Dir + "/../lib", Paths);
Rafael Espindolac53c5b12015-08-31 19:17:51 +00003704
3705 std::string LibPath = "/usr/lib/";
3706 switch (Triple.getArch()) {
3707 case llvm::Triple::x86:
3708 case llvm::Triple::sparc:
3709 break;
3710 case llvm::Triple::x86_64:
3711 LibPath += "amd64/";
3712 break;
3713 case llvm::Triple::sparcv9:
3714 LibPath += "sparcv9/";
3715 break;
3716 default:
3717 llvm_unreachable("Unsupported architecture");
3718 }
3719
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003720 addPathIfExists(D, getDriver().SysRoot + LibPath, Paths);
David Chisnallf571cde2012-02-15 13:39:01 +00003721}
3722
Rafael Espindola7cf32212013-03-20 03:05:54 +00003723Tool *Solaris::buildAssembler() const {
Douglas Katzman95354292015-06-23 20:42:09 +00003724 return new tools::solaris::Assembler(*this);
Rafael Espindola7cf32212013-03-20 03:05:54 +00003725}
3726
Douglas Katzman95354292015-06-23 20:42:09 +00003727Tool *Solaris::buildLinker() const { return new tools::solaris::Linker(*this); }
Edward O'Callaghan856e4ff2009-08-22 01:06:46 +00003728
Rafael Espindolad5117262015-09-09 13:36:00 +00003729void Solaris::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
3730 ArgStringList &CC1Args) const {
3731 if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
3732 DriverArgs.hasArg(options::OPT_nostdincxx))
3733 return;
3734
3735 // Include the support directory for things like xlocale and fudged system
3736 // headers.
3737 addSystemInclude(DriverArgs, CC1Args, "/usr/include/c++/v1/support/solaris");
3738
3739 if (GCCInstallation.isValid()) {
3740 GCCVersion Version = GCCInstallation.getVersion();
3741 addSystemInclude(DriverArgs, CC1Args,
3742 getDriver().SysRoot + "/usr/gcc/" +
3743 Version.MajorStr + "." +
3744 Version.MinorStr +
3745 "/include/c++/" + Version.Text);
3746 addSystemInclude(DriverArgs, CC1Args,
3747 getDriver().SysRoot + "/usr/gcc/" + Version.MajorStr +
3748 "." + Version.MinorStr + "/include/c++/" +
3749 Version.Text + "/" +
3750 GCCInstallation.getTriple().str());
3751 }
3752}
3753
Thomas Schwinge6d94da02013-03-28 19:02:48 +00003754/// Distribution (very bare-bones at the moment).
Eli Friedman5cd659f2009-05-26 07:52:18 +00003755
Thomas Schwinge6d94da02013-03-28 19:02:48 +00003756enum Distro {
Douglas Katzmana5df0c82015-06-22 20:55:31 +00003757 // NB: Releases of a particular Linux distro should be kept together
3758 // in this enum, because some tests are done by integer comparison against
3759 // the first and last known member in the family, e.g. IsRedHat().
Chandler Carruth6a4e8e32011-02-25 06:39:53 +00003760 ArchLinux,
Rafael Espindolac8f008f2010-11-07 20:14:31 +00003761 DebianLenny,
3762 DebianSqueeze,
Eli Friedmanf7600942011-06-02 21:36:53 +00003763 DebianWheezy,
Sylvestre Ledrubdef2892013-01-06 08:09:29 +00003764 DebianJessie,
Benjamin Kramer1a8fa8b2015-04-06 12:30:43 +00003765 DebianStretch,
Rafael Espindola12479842010-11-11 02:07:13 +00003766 Exherbo,
Chris Lattner84e38552011-05-22 05:36:06 +00003767 RHEL5,
3768 RHEL6,
Benjamin Kramer1a8fa8b2015-04-06 12:30:43 +00003769 RHEL7,
Rafael Espindola0d2cbc02013-10-25 18:09:41 +00003770 Fedora,
Rafael Espindola10a63c22013-07-03 14:14:00 +00003771 OpenSUSE,
Douglas Gregor0a36f4d2011-03-14 15:39:50 +00003772 UbuntuHardy,
3773 UbuntuIntrepid,
Rafael Espindola66b291a2010-11-10 05:00:22 +00003774 UbuntuJaunty,
Zhongxing Xu14776cf2010-11-15 09:01:52 +00003775 UbuntuKarmic,
Rafael Espindolac8f008f2010-11-07 20:14:31 +00003776 UbuntuLucid,
3777 UbuntuMaverick,
Ted Kremenek43d47cc2011-04-05 22:04:27 +00003778 UbuntuNatty,
Benjamin Kramerf90b5de2011-06-05 16:08:59 +00003779 UbuntuOneiric,
Benjamin Kramer7c3f09d2012-02-06 14:36:09 +00003780 UbuntuPrecise,
Rafael Espindola62e87702012-12-13 20:26:05 +00003781 UbuntuQuantal,
3782 UbuntuRaring,
Sylvestre Ledru93c47b72013-06-13 11:52:27 +00003783 UbuntuSaucy,
Sylvestre Ledruaaf01a72013-11-07 09:31:30 +00003784 UbuntuTrusty,
Benjamin Kramer1a8fa8b2015-04-06 12:30:43 +00003785 UbuntuUtopic,
3786 UbuntuVivid,
Benjamin Kramer2d469802015-07-09 15:31:17 +00003787 UbuntuWily,
Sylvestre Ledru43b95712015-10-29 17:27:55 +00003788 UbuntuXenial,
Sylvestre Ledrud3078e72016-07-19 14:00:57 +00003789 UbuntuYakkety,
Rafael Espindolac8f008f2010-11-07 20:14:31 +00003790 UnknownDistro
3791};
3792
Thomas Schwinge6d94da02013-03-28 19:02:48 +00003793static bool IsRedhat(enum Distro Distro) {
Rafael Espindola52fe8962016-05-09 13:13:50 +00003794 return Distro == Fedora || (Distro >= RHEL5 && Distro <= RHEL7);
Rafael Espindolac8f008f2010-11-07 20:14:31 +00003795}
3796
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003797static bool IsOpenSUSE(enum Distro Distro) { return Distro == OpenSUSE; }
Rafael Espindolac8f008f2010-11-07 20:14:31 +00003798
Thomas Schwinge6d94da02013-03-28 19:02:48 +00003799static bool IsDebian(enum Distro Distro) {
Benjamin Kramer1a8fa8b2015-04-06 12:30:43 +00003800 return Distro >= DebianLenny && Distro <= DebianStretch;
Rafael Espindolac8f008f2010-11-07 20:14:31 +00003801}
3802
Thomas Schwinge6d94da02013-03-28 19:02:48 +00003803static bool IsUbuntu(enum Distro Distro) {
Sylvestre Ledrud3078e72016-07-19 14:00:57 +00003804 return Distro >= UbuntuHardy && Distro <= UbuntuYakkety;
Rafael Espindolac8f008f2010-11-07 20:14:31 +00003805}
3806
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003807static Distro DetectDistro(const Driver &D, llvm::Triple::ArchType Arch) {
Rafael Espindola2d2b4202014-07-06 17:43:24 +00003808 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> File =
3809 llvm::MemoryBuffer::getFile("/etc/lsb-release");
3810 if (File) {
Chris Lattner0e62c1c2011-07-23 10:55:15 +00003811 StringRef Data = File.get()->getBuffer();
Hans Wennborg3b7dd8d2014-08-11 18:09:32 +00003812 SmallVector<StringRef, 16> Lines;
Rafael Espindolac8f008f2010-11-07 20:14:31 +00003813 Data.split(Lines, "\n");
Thomas Schwinge6d94da02013-03-28 19:02:48 +00003814 Distro Version = UnknownDistro;
Benjamin Kramer72e64312015-09-24 14:48:49 +00003815 for (StringRef Line : Lines)
Douglas Katzman6bbffc42015-06-25 18:51:37 +00003816 if (Version == UnknownDistro && Line.startswith("DISTRIB_CODENAME="))
3817 Version = llvm::StringSwitch<Distro>(Line.substr(17))
3818 .Case("hardy", UbuntuHardy)
3819 .Case("intrepid", UbuntuIntrepid)
3820 .Case("jaunty", UbuntuJaunty)
3821 .Case("karmic", UbuntuKarmic)
3822 .Case("lucid", UbuntuLucid)
3823 .Case("maverick", UbuntuMaverick)
3824 .Case("natty", UbuntuNatty)
3825 .Case("oneiric", UbuntuOneiric)
3826 .Case("precise", UbuntuPrecise)
3827 .Case("quantal", UbuntuQuantal)
3828 .Case("raring", UbuntuRaring)
3829 .Case("saucy", UbuntuSaucy)
3830 .Case("trusty", UbuntuTrusty)
3831 .Case("utopic", UbuntuUtopic)
3832 .Case("vivid", UbuntuVivid)
Benjamin Kramer2d469802015-07-09 15:31:17 +00003833 .Case("wily", UbuntuWily)
Sylvestre Ledru43b95712015-10-29 17:27:55 +00003834 .Case("xenial", UbuntuXenial)
Sylvestre Ledrud3078e72016-07-19 14:00:57 +00003835 .Case("yakkety", UbuntuYakkety)
Douglas Katzman6bbffc42015-06-25 18:51:37 +00003836 .Default(UnknownDistro);
Rafael Espindola52fe8962016-05-09 13:13:50 +00003837 if (Version != UnknownDistro)
3838 return Version;
Rafael Espindolac8f008f2010-11-07 20:14:31 +00003839 }
3840
Rafael Espindola2d2b4202014-07-06 17:43:24 +00003841 File = llvm::MemoryBuffer::getFile("/etc/redhat-release");
3842 if (File) {
Chris Lattner0e62c1c2011-07-23 10:55:15 +00003843 StringRef Data = File.get()->getBuffer();
Rafael Espindola0d2cbc02013-10-25 18:09:41 +00003844 if (Data.startswith("Fedora release"))
3845 return Fedora;
Benjamin Kramer6af073b2014-05-05 12:39:32 +00003846 if (Data.startswith("Red Hat Enterprise Linux") ||
Rafael Espindola52fe8962016-05-09 13:13:50 +00003847 Data.startswith("CentOS") ||
3848 Data.startswith("Scientific Linux")) {
Benjamin Kramer1a8fa8b2015-04-06 12:30:43 +00003849 if (Data.find("release 7") != StringRef::npos)
3850 return RHEL7;
3851 else if (Data.find("release 6") != StringRef::npos)
Benjamin Kramer6af073b2014-05-05 12:39:32 +00003852 return RHEL6;
3853 else if (Data.find("release 5") != StringRef::npos)
3854 return RHEL5;
Benjamin Kramer6af073b2014-05-05 12:39:32 +00003855 }
Rafael Espindolac8f008f2010-11-07 20:14:31 +00003856 return UnknownDistro;
3857 }
3858
Rafael Espindola2d2b4202014-07-06 17:43:24 +00003859 File = llvm::MemoryBuffer::getFile("/etc/debian_version");
3860 if (File) {
Chris Lattner0e62c1c2011-07-23 10:55:15 +00003861 StringRef Data = File.get()->getBuffer();
Rafael Espindolac8f008f2010-11-07 20:14:31 +00003862 if (Data[0] == '5')
3863 return DebianLenny;
Rafael Espindola1510c852011-12-28 18:17:14 +00003864 else if (Data.startswith("squeeze/sid") || Data[0] == '6')
Rafael Espindolac8f008f2010-11-07 20:14:31 +00003865 return DebianSqueeze;
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003866 else if (Data.startswith("wheezy/sid") || Data[0] == '7')
Eli Friedmanf7600942011-06-02 21:36:53 +00003867 return DebianWheezy;
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003868 else if (Data.startswith("jessie/sid") || Data[0] == '8')
Sylvestre Ledrubdef2892013-01-06 08:09:29 +00003869 return DebianJessie;
Benjamin Kramer1a8fa8b2015-04-06 12:30:43 +00003870 else if (Data.startswith("stretch/sid") || Data[0] == '9')
3871 return DebianStretch;
Rafael Espindolac8f008f2010-11-07 20:14:31 +00003872 return UnknownDistro;
3873 }
3874
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003875 if (D.getVFS().exists("/etc/SuSE-release"))
Rafael Espindola10a63c22013-07-03 14:14:00 +00003876 return OpenSUSE;
Rafael Espindolac8f008f2010-11-07 20:14:31 +00003877
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003878 if (D.getVFS().exists("/etc/exherbo-release"))
Rafael Espindola12479842010-11-11 02:07:13 +00003879 return Exherbo;
3880
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003881 if (D.getVFS().exists("/etc/arch-release"))
Chandler Carruth6a4e8e32011-02-25 06:39:53 +00003882 return ArchLinux;
3883
Rafael Espindolac8f008f2010-11-07 20:14:31 +00003884 return UnknownDistro;
3885}
3886
Chandler Carruthfb7fa242011-10-31 08:42:24 +00003887/// \brief Get our best guess at the multiarch triple for a target.
3888///
3889/// Debian-based systems are starting to use a multiarch setup where they use
3890/// a target-triple directory in the library and header search paths.
3891/// Unfortunately, this triple does not align with the vanilla target triple,
3892/// so we provide a rough mapping here.
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003893static std::string getMultiarchTriple(const Driver &D,
3894 const llvm::Triple &TargetTriple,
Chandler Carruthfb7fa242011-10-31 08:42:24 +00003895 StringRef SysRoot) {
Eric Christopherefef8ef2015-12-07 22:43:05 +00003896 llvm::Triple::EnvironmentType TargetEnvironment =
3897 TargetTriple.getEnvironment();
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003898
Chandler Carruthfb7fa242011-10-31 08:42:24 +00003899 // For most architectures, just use whatever we have rather than trying to be
3900 // clever.
3901 switch (TargetTriple.getArch()) {
3902 default:
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003903 break;
Chandler Carruthfb7fa242011-10-31 08:42:24 +00003904
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003905 // We use the existence of '/lib/<triple>' as a directory to detect some
3906 // common linux triples that don't quite match the Clang triple for both
3907 // 32-bit and 64-bit targets. Multiarch fixes its install triples to these
3908 // regardless of what the actual target triple is.
Chad Rosier4dce73a2012-07-11 19:08:21 +00003909 case llvm::Triple::arm:
3910 case llvm::Triple::thumb:
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003911 if (TargetEnvironment == llvm::Triple::GNUEABIHF) {
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003912 if (D.getVFS().exists(SysRoot + "/lib/arm-linux-gnueabihf"))
Jiangning Liu61b06cb2012-07-31 08:06:29 +00003913 return "arm-linux-gnueabihf";
3914 } else {
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003915 if (D.getVFS().exists(SysRoot + "/lib/arm-linux-gnueabi"))
Jiangning Liu61b06cb2012-07-31 08:06:29 +00003916 return "arm-linux-gnueabi";
3917 }
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003918 break;
Christian Pirkerf01cd6f2014-03-28 14:40:46 +00003919 case llvm::Triple::armeb:
3920 case llvm::Triple::thumbeb:
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003921 if (TargetEnvironment == llvm::Triple::GNUEABIHF) {
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003922 if (D.getVFS().exists(SysRoot + "/lib/armeb-linux-gnueabihf"))
Christian Pirkerf01cd6f2014-03-28 14:40:46 +00003923 return "armeb-linux-gnueabihf";
3924 } else {
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003925 if (D.getVFS().exists(SysRoot + "/lib/armeb-linux-gnueabi"))
Christian Pirkerf01cd6f2014-03-28 14:40:46 +00003926 return "armeb-linux-gnueabi";
3927 }
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003928 break;
Chandler Carruthfb7fa242011-10-31 08:42:24 +00003929 case llvm::Triple::x86:
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003930 if (D.getVFS().exists(SysRoot + "/lib/i386-linux-gnu"))
Chandler Carruthfb7fa242011-10-31 08:42:24 +00003931 return "i386-linux-gnu";
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003932 break;
Chandler Carruthfb7fa242011-10-31 08:42:24 +00003933 case llvm::Triple::x86_64:
Zinovy Nis1db95732014-07-10 15:27:19 +00003934 // We don't want this for x32, otherwise it will match x86_64 libs
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003935 if (TargetEnvironment != llvm::Triple::GNUX32 &&
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003936 D.getVFS().exists(SysRoot + "/lib/x86_64-linux-gnu"))
Chandler Carruthfb7fa242011-10-31 08:42:24 +00003937 return "x86_64-linux-gnu";
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003938 break;
Tim Northover9bb857a2013-01-31 12:13:10 +00003939 case llvm::Triple::aarch64:
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003940 if (D.getVFS().exists(SysRoot + "/lib/aarch64-linux-gnu"))
Tim Northover9bb857a2013-01-31 12:13:10 +00003941 return "aarch64-linux-gnu";
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003942 break;
Christian Pirkera74c7912014-03-14 12:15:45 +00003943 case llvm::Triple::aarch64_be:
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003944 if (D.getVFS().exists(SysRoot + "/lib/aarch64_be-linux-gnu"))
Christian Pirkera74c7912014-03-14 12:15:45 +00003945 return "aarch64_be-linux-gnu";
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003946 break;
Eli Friedman27b8c4f2011-11-08 19:43:37 +00003947 case llvm::Triple::mips:
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003948 if (D.getVFS().exists(SysRoot + "/lib/mips-linux-gnu"))
Eli Friedman27b8c4f2011-11-08 19:43:37 +00003949 return "mips-linux-gnu";
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003950 break;
Eli Friedman27b8c4f2011-11-08 19:43:37 +00003951 case llvm::Triple::mipsel:
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003952 if (D.getVFS().exists(SysRoot + "/lib/mipsel-linux-gnu"))
Eli Friedman27b8c4f2011-11-08 19:43:37 +00003953 return "mipsel-linux-gnu";
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003954 break;
Simon Atanasyan3a46afa2014-06-24 19:00:12 +00003955 case llvm::Triple::mips64:
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003956 if (D.getVFS().exists(SysRoot + "/lib/mips64-linux-gnu"))
Simon Atanasyan3a46afa2014-06-24 19:00:12 +00003957 return "mips64-linux-gnu";
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003958 if (D.getVFS().exists(SysRoot + "/lib/mips64-linux-gnuabi64"))
Simon Atanasyan3a46afa2014-06-24 19:00:12 +00003959 return "mips64-linux-gnuabi64";
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003960 break;
Simon Atanasyan3a46afa2014-06-24 19:00:12 +00003961 case llvm::Triple::mips64el:
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003962 if (D.getVFS().exists(SysRoot + "/lib/mips64el-linux-gnu"))
Simon Atanasyan3a46afa2014-06-24 19:00:12 +00003963 return "mips64el-linux-gnu";
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003964 if (D.getVFS().exists(SysRoot + "/lib/mips64el-linux-gnuabi64"))
Simon Atanasyan3a46afa2014-06-24 19:00:12 +00003965 return "mips64el-linux-gnuabi64";
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003966 break;
Chandler Carruthaf3c2092012-02-26 09:03:21 +00003967 case llvm::Triple::ppc:
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003968 if (D.getVFS().exists(SysRoot + "/lib/powerpc-linux-gnuspe"))
Sylvestre Ledrue0bf5812013-03-15 16:22:43 +00003969 return "powerpc-linux-gnuspe";
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003970 if (D.getVFS().exists(SysRoot + "/lib/powerpc-linux-gnu"))
Chandler Carruthaf3c2092012-02-26 09:03:21 +00003971 return "powerpc-linux-gnu";
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003972 break;
Chandler Carruthaf3c2092012-02-26 09:03:21 +00003973 case llvm::Triple::ppc64:
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003974 if (D.getVFS().exists(SysRoot + "/lib/powerpc64-linux-gnu"))
Chandler Carruthaf3c2092012-02-26 09:03:21 +00003975 return "powerpc64-linux-gnu";
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003976 break;
Bill Schmidt778d3872013-07-26 01:36:11 +00003977 case llvm::Triple::ppc64le:
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003978 if (D.getVFS().exists(SysRoot + "/lib/powerpc64le-linux-gnu"))
Bill Schmidt778d3872013-07-26 01:36:11 +00003979 return "powerpc64le-linux-gnu";
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003980 break;
James Y Knightc0aeadf2015-06-04 15:36:30 +00003981 case llvm::Triple::sparc:
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003982 if (D.getVFS().exists(SysRoot + "/lib/sparc-linux-gnu"))
James Y Knightc0aeadf2015-06-04 15:36:30 +00003983 return "sparc-linux-gnu";
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003984 break;
James Y Knightc0aeadf2015-06-04 15:36:30 +00003985 case llvm::Triple::sparcv9:
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003986 if (D.getVFS().exists(SysRoot + "/lib/sparc64-linux-gnu"))
James Y Knightc0aeadf2015-06-04 15:36:30 +00003987 return "sparc64-linux-gnu";
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003988 break;
Sylvestre Ledruc0babf22015-08-28 12:26:09 +00003989 case llvm::Triple::systemz:
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003990 if (D.getVFS().exists(SysRoot + "/lib/s390x-linux-gnu"))
Sylvestre Ledruc0babf22015-08-28 12:26:09 +00003991 return "s390x-linux-gnu";
3992 break;
Chandler Carruthfb7fa242011-10-31 08:42:24 +00003993 }
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003994 return TargetTriple.str();
Chandler Carruthfb7fa242011-10-31 08:42:24 +00003995}
3996
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00003997static StringRef getOSLibDir(const llvm::Triple &Triple, const ArgList &Args) {
Chandler Carruthda797042013-10-29 10:27:30 +00003998 if (isMipsArch(Triple.getArch())) {
Simon Atanasyan603018a2016-07-19 07:09:48 +00003999 if (Triple.isAndroid()) {
4000 StringRef CPUName;
4001 StringRef ABIName;
4002 tools::mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
4003 if (CPUName == "mips32r6")
4004 return "libr6";
4005 if (CPUName == "mips32r2")
4006 return "libr2";
4007 }
Chandler Carruthda797042013-10-29 10:27:30 +00004008 // lib32 directory has a special meaning on MIPS targets.
4009 // It contains N32 ABI binaries. Use this folder if produce
4010 // code for N32 ABI only.
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00004011 if (tools::mips::hasMipsAbiArg(Args, "n32"))
Chandler Carruthda797042013-10-29 10:27:30 +00004012 return "lib32";
4013 return Triple.isArch32Bit() ? "lib" : "lib64";
4014 }
Simon Atanasyand4413882012-09-14 11:27:24 +00004015
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00004016 // It happens that only x86 and PPC use the 'lib32' variant of oslibdir, and
Chandler Carruthda797042013-10-29 10:27:30 +00004017 // using that variant while targeting other architectures causes problems
4018 // because the libraries are laid out in shared system roots that can't cope
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00004019 // with a 'lib32' library search path being considered. So we only enable
Chandler Carruthda797042013-10-29 10:27:30 +00004020 // them when we know we may need it.
4021 //
4022 // FIXME: This is a bit of a hack. We should really unify this code for
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00004023 // reasoning about oslibdir spellings with the lib dir spellings in the
Chandler Carruthda797042013-10-29 10:27:30 +00004024 // GCCInstallationDetector, but that is a more significant refactoring.
4025 if (Triple.getArch() == llvm::Triple::x86 ||
4026 Triple.getArch() == llvm::Triple::ppc)
Simon Atanasyand4413882012-09-14 11:27:24 +00004027 return "lib32";
4028
Zinovy Nis1db95732014-07-10 15:27:19 +00004029 if (Triple.getArch() == llvm::Triple::x86_64 &&
4030 Triple.getEnvironment() == llvm::Triple::GNUX32)
4031 return "libx32";
4032
Simon Atanasyand4413882012-09-14 11:27:24 +00004033 return Triple.isArch32Bit() ? "lib" : "lib64";
4034}
4035
Simon Atanasyan2834a222016-05-22 18:18:07 +00004036static void addMultilibsFilePaths(const Driver &D, const MultilibSet &Multilibs,
4037 const Multilib &Multilib,
4038 StringRef InstallPath,
4039 ToolChain::path_list &Paths) {
4040 if (const auto &PathsCallback = Multilibs.filePathsCallback())
4041 for (const auto &Path : PathsCallback(Multilib))
4042 addPathIfExists(D, InstallPath + Path, Paths);
4043}
4044
Rafael Espindola1af7c212012-02-19 01:38:32 +00004045Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004046 : Generic_ELF(D, Triple, Args) {
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004047 GCCInstallation.init(Triple, Args);
4048 CudaInstallation.init(Triple, Args);
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00004049 Multilibs = GCCInstallation.getMultilibs();
Chandler Carruth96bae7b2012-01-24 20:08:17 +00004050 llvm::Triple::ArchType Arch = Triple.getArch();
Simon Atanasyana0d89572013-10-05 14:37:55 +00004051 std::string SysRoot = computeSysRoot();
Rafael Espindolac8f008f2010-11-07 20:14:31 +00004052
Rafael Espindola10a63c22013-07-03 14:14:00 +00004053 // Cross-compiling binutils and GCC installations (vanilla and openSUSE at
Chandler Carruthd6c62b62013-06-20 23:37:54 +00004054 // least) put various tools in a triple-prefixed directory off of the parent
4055 // of the GCC installation. We use the GCC triple here to ensure that we end
4056 // up with tools that support the same amount of cross compiling as the
4057 // detected GCC installation. For example, if we find a GCC installation
4058 // targeting x86_64, but it is a bi-arch GCC installation, it can also be
4059 // used to target i386.
4060 // FIXME: This seems unlikely to be Linux-specific.
Rafael Espindola5f344ff2011-09-01 16:25:49 +00004061 ToolChain::path_list &PPaths = getProgramPaths();
Chandler Carruth4be70dd2011-11-06 09:21:54 +00004062 PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + "/../" +
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004063 GCCInstallation.getTriple().str() + "/bin")
4064 .str());
Rafael Espindola5f344ff2011-09-01 16:25:49 +00004065
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004066 Distro Distro = DetectDistro(D, Arch);
Rafael Espindolac8f008f2010-11-07 20:14:31 +00004067
Rafael Espindola10a63c22013-07-03 14:14:00 +00004068 if (IsOpenSUSE(Distro) || IsUbuntu(Distro)) {
Rafael Espindolac5688622010-11-08 14:48:47 +00004069 ExtraOpts.push_back("-z");
4070 ExtraOpts.push_back("relro");
4071 }
Rafael Espindolac8f008f2010-11-07 20:14:31 +00004072
Douglas Gregord9bb1522011-03-06 19:11:49 +00004073 if (Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb)
Rafael Espindolac8f008f2010-11-07 20:14:31 +00004074 ExtraOpts.push_back("-X");
4075
Evgeniy Stepanov14deb7b2015-10-08 21:21:44 +00004076 const bool IsAndroid = Triple.isAndroid();
Simon Atanasyan08450bd2013-04-20 08:15:03 +00004077 const bool IsMips = isMipsArch(Arch);
4078
4079 if (IsMips && !SysRoot.empty())
4080 ExtraOpts.push_back("--sysroot=" + SysRoot);
Evgeniy Stepanov2ca1aa52012-01-13 09:30:38 +00004081
Chandler Carruth0b842912011-12-09 04:45:18 +00004082 // Do not use 'gnu' hash style for Mips targets because .gnu.hash
4083 // and the MIPS ABI require .dynsym to be sorted in different ways.
4084 // .gnu.hash needs symbols to be grouped by hash code whereas the MIPS
4085 // ABI requires a mapping between the GOT and the symbol table.
Evgeniy Stepanov2ca1aa52012-01-13 09:30:38 +00004086 // Android loader does not support .gnu.hash.
Simon Atanasyan08450bd2013-04-20 08:15:03 +00004087 if (!IsMips && !IsAndroid) {
Rafael Espindola10a63c22013-07-03 14:14:00 +00004088 if (IsRedhat(Distro) || IsOpenSUSE(Distro) ||
Benjamin Kramer7c3f09d2012-02-06 14:36:09 +00004089 (IsUbuntu(Distro) && Distro >= UbuntuMaverick))
Chandler Carruth0b842912011-12-09 04:45:18 +00004090 ExtraOpts.push_back("--hash-style=gnu");
4091
Rafael Espindola10a63c22013-07-03 14:14:00 +00004092 if (IsDebian(Distro) || IsOpenSUSE(Distro) || Distro == UbuntuLucid ||
Chandler Carruth0b842912011-12-09 04:45:18 +00004093 Distro == UbuntuJaunty || Distro == UbuntuKarmic)
4094 ExtraOpts.push_back("--hash-style=both");
4095 }
Rafael Espindolac8f008f2010-11-07 20:14:31 +00004096
Rafael Espindola52fe8962016-05-09 13:13:50 +00004097 if (IsRedhat(Distro) && Distro != RHEL5 && Distro != RHEL6)
Rafael Espindolac8f008f2010-11-07 20:14:31 +00004098 ExtraOpts.push_back("--no-add-needed");
4099
Rafael Espindola5ed89d42016-06-03 17:26:16 +00004100#ifdef ENABLE_LINKER_BUILD_ID
4101 ExtraOpts.push_back("--build-id");
4102#endif
Rafael Espindolac8f008f2010-11-07 20:14:31 +00004103
Rafael Espindola10a63c22013-07-03 14:14:00 +00004104 if (IsOpenSUSE(Distro))
Chandler Carruthe5d9d902011-05-24 07:51:17 +00004105 ExtraOpts.push_back("--enable-new-dtags");
Chris Lattnerd075c822011-05-22 16:45:07 +00004106
Chandler Carruth413e5ac2011-10-03 05:28:29 +00004107 // The selection of paths to try here is designed to match the patterns which
4108 // the GCC driver itself uses, as this is part of the GCC-compatible driver.
4109 // This was determined by running GCC in a fake filesystem, creating all
4110 // possible permutations of these directories, and seeing which ones it added
4111 // to the link paths.
4112 path_list &Paths = getFilePaths();
Chandler Carruth6a4e8e32011-02-25 06:39:53 +00004113
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00004114 const std::string OSLibDir = getOSLibDir(Triple, Args);
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004115 const std::string MultiarchTriple = getMultiarchTriple(D, Triple, SysRoot);
Chandler Carruth413e5ac2011-10-03 05:28:29 +00004116
Chandler Carruthd0b93d62011-11-06 23:09:05 +00004117 // Add the multilib suffixed paths where they are available.
4118 if (GCCInstallation.isValid()) {
Chandler Carruth4d9d7682012-01-24 19:28:29 +00004119 const llvm::Triple &GCCTriple = GCCInstallation.getTriple();
Chandler Carruth96bae7b2012-01-24 20:08:17 +00004120 const std::string &LibPath = GCCInstallation.getParentLibPath();
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00004121 const Multilib &Multilib = GCCInstallation.getMultilib();
Simon Atanasyan2834a222016-05-22 18:18:07 +00004122 const MultilibSet &Multilibs = GCCInstallation.getMultilibs();
4123
4124 // Add toolchain / multilib specific file paths.
4125 addMultilibsFilePaths(D, Multilibs, Multilib,
4126 GCCInstallation.getInstallPath(), Paths);
Simon Atanasyan53fefd12012-10-03 17:46:38 +00004127
Chandler Carruth7f8042c2013-07-31 00:37:07 +00004128 // Sourcery CodeBench MIPS toolchain holds some libraries under
Chandler Carruth9b6ce932013-10-29 02:27:56 +00004129 // a biarch-like suffix of the GCC installation.
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004130 addPathIfExists(D, GCCInstallation.getInstallPath() + Multilib.gccSuffix(),
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00004131 Paths);
Chandler Carruth7f8042c2013-07-31 00:37:07 +00004132
4133 // GCC cross compiling toolchains will install target libraries which ship
4134 // as part of the toolchain under <prefix>/<triple>/<libdir> rather than as
4135 // any part of the GCC installation in
4136 // <prefix>/<libdir>/gcc/<triple>/<version>. This decision is somewhat
4137 // debatable, but is the reality today. We need to search this tree even
4138 // when we have a sysroot somewhere else. It is the responsibility of
Alp Tokerf6a24ce2013-12-05 16:25:25 +00004139 // whomever is doing the cross build targeting a sysroot using a GCC
Chandler Carruth7f8042c2013-07-31 00:37:07 +00004140 // installation that is *not* within the system root to ensure two things:
4141 //
4142 // 1) Any DSOs that are linked in from this tree or from the install path
Alexander Potapenkoc8e749a2014-09-01 12:35:57 +00004143 // above must be present on the system root and found via an
Chandler Carruth7f8042c2013-07-31 00:37:07 +00004144 // appropriate rpath.
4145 // 2) There must not be libraries installed into
4146 // <prefix>/<triple>/<libdir> unless they should be preferred over
4147 // those within the system root.
4148 //
4149 // Note that this matches the GCC behavior. See the below comment for where
4150 // Clang diverges from GCC's behavior.
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004151 addPathIfExists(D, LibPath + "/../" + GCCTriple.str() + "/lib/../" +
4152 OSLibDir + Multilib.osSuffix(),
Chandler Carruth7f8042c2013-07-31 00:37:07 +00004153 Paths);
4154
Chandler Carruth69a125b2012-04-06 16:32:06 +00004155 // If the GCC installation we found is inside of the sysroot, we want to
4156 // prefer libraries installed in the parent prefix of the GCC installation.
4157 // It is important to *not* use these paths when the GCC installation is
Gabor Greif5d3231c2012-04-18 10:59:08 +00004158 // outside of the system root as that can pick up unintended libraries.
Chandler Carruth69a125b2012-04-06 16:32:06 +00004159 // This usually happens when there is an external cross compiler on the
4160 // host system, and a more minimal sysroot available that is the target of
Chandler Carruth7f8042c2013-07-31 00:37:07 +00004161 // the cross. Note that GCC does include some of these directories in some
4162 // configurations but this seems somewhere between questionable and simply
4163 // a bug.
Chandler Carruth69a125b2012-04-06 16:32:06 +00004164 if (StringRef(LibPath).startswith(SysRoot)) {
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004165 addPathIfExists(D, LibPath + "/" + MultiarchTriple, Paths);
4166 addPathIfExists(D, LibPath + "/../" + OSLibDir, Paths);
Chandler Carruth69a125b2012-04-06 16:32:06 +00004167 }
Rafael Espindolac8f008f2010-11-07 20:14:31 +00004168 }
Chandler Carruth902efc62014-01-21 22:49:05 +00004169
4170 // Similar to the logic for GCC above, if we currently running Clang inside
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00004171 // of the requested system root, add its parent library paths to
Chandler Carruth902efc62014-01-21 22:49:05 +00004172 // those searched.
4173 // FIXME: It's not clear whether we should use the driver's installed
4174 // directory ('Dir' below) or the ResourceDir.
4175 if (StringRef(D.Dir).startswith(SysRoot)) {
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004176 addPathIfExists(D, D.Dir + "/../lib/" + MultiarchTriple, Paths);
4177 addPathIfExists(D, D.Dir + "/../" + OSLibDir, Paths);
Chandler Carruth902efc62014-01-21 22:49:05 +00004178 }
4179
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004180 addPathIfExists(D, SysRoot + "/lib/" + MultiarchTriple, Paths);
4181 addPathIfExists(D, SysRoot + "/lib/../" + OSLibDir, Paths);
4182 addPathIfExists(D, SysRoot + "/usr/lib/" + MultiarchTriple, Paths);
4183 addPathIfExists(D, SysRoot + "/usr/lib/../" + OSLibDir, Paths);
Chandler Carruthd0b93d62011-11-06 23:09:05 +00004184
Chandler Carruthb427c562013-06-22 11:35:51 +00004185 // Try walking via the GCC triple path in case of biarch or multiarch GCC
Chandler Carruthd0b93d62011-11-06 23:09:05 +00004186 // installations with strange symlinks.
Rafael Espindolab6250162013-10-25 17:06:04 +00004187 if (GCCInstallation.isValid()) {
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004188 addPathIfExists(D,
4189 SysRoot + "/usr/lib/" + GCCInstallation.getTriple().str() +
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004190 "/../../" + OSLibDir,
4191 Paths);
Rafael Espindola30490212011-06-03 15:39:42 +00004192
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00004193 // Add the 'other' biarch variant path
4194 Multilib BiarchSibling;
4195 if (GCCInstallation.getBiarchSibling(BiarchSibling)) {
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004196 addPathIfExists(D, GCCInstallation.getInstallPath() +
4197 BiarchSibling.gccSuffix(),
4198 Paths);
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00004199 }
Chandler Carruth69a125b2012-04-06 16:32:06 +00004200
Chandler Carruth7f8042c2013-07-31 00:37:07 +00004201 // See comments above on the multilib variant for details of why this is
4202 // included even from outside the sysroot.
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00004203 const std::string &LibPath = GCCInstallation.getParentLibPath();
4204 const llvm::Triple &GCCTriple = GCCInstallation.getTriple();
4205 const Multilib &Multilib = GCCInstallation.getMultilib();
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004206 addPathIfExists(D, LibPath + "/../" + GCCTriple.str() + "/lib" +
4207 Multilib.osSuffix(),
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004208 Paths);
Chandler Carruth7f8042c2013-07-31 00:37:07 +00004209
4210 // See comments above on the multilib variant for details of why this is
4211 // only included from within the sysroot.
4212 if (StringRef(LibPath).startswith(SysRoot))
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004213 addPathIfExists(D, LibPath, Paths);
Chandler Carruth413e5ac2011-10-03 05:28:29 +00004214 }
Chandler Carruth902efc62014-01-21 22:49:05 +00004215
4216 // Similar to the logic for GCC above, if we are currently running Clang
4217 // inside of the requested system root, add its parent library path to those
4218 // searched.
4219 // FIXME: It's not clear whether we should use the driver's installed
4220 // directory ('Dir' below) or the ResourceDir.
4221 if (StringRef(D.Dir).startswith(SysRoot))
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004222 addPathIfExists(D, D.Dir + "/../lib", Paths);
Chandler Carruth902efc62014-01-21 22:49:05 +00004223
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004224 addPathIfExists(D, SysRoot + "/lib", Paths);
4225 addPathIfExists(D, SysRoot + "/usr/lib", Paths);
Rafael Espindolac8f008f2010-11-07 20:14:31 +00004226}
4227
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004228bool Linux::HasNativeLLVMSupport() const { return true; }
Eli Friedman5cd659f2009-05-26 07:52:18 +00004229
Douglas Katzman95354292015-06-23 20:42:09 +00004230Tool *Linux::buildLinker() const { return new tools::gnutools::Linker(*this); }
Rafael Espindola7cf32212013-03-20 03:05:54 +00004231
4232Tool *Linux::buildAssembler() const {
Douglas Katzman95354292015-06-23 20:42:09 +00004233 return new tools::gnutools::Assembler(*this);
Rafael Espindola92b00932010-08-10 00:25:48 +00004234}
4235
Simon Atanasyana0d89572013-10-05 14:37:55 +00004236std::string Linux::computeSysRoot() const {
Simon Atanasyan08450bd2013-04-20 08:15:03 +00004237 if (!getDriver().SysRoot.empty())
4238 return getDriver().SysRoot;
4239
4240 if (!GCCInstallation.isValid() || !isMipsArch(getTriple().getArch()))
4241 return std::string();
4242
Simon Atanasyana61b7ec2013-10-10 07:57:44 +00004243 // Standalone MIPS toolchains use different names for sysroot folder
4244 // and put it into different places. Here we try to check some known
4245 // variants.
Simon Atanasyan08450bd2013-04-20 08:15:03 +00004246
Simon Atanasyana61b7ec2013-10-10 07:57:44 +00004247 const StringRef InstallDir = GCCInstallation.getInstallPath();
4248 const StringRef TripleStr = GCCInstallation.getTriple().str();
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00004249 const Multilib &Multilib = GCCInstallation.getMultilib();
Simon Atanasyana61b7ec2013-10-10 07:57:44 +00004250
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004251 std::string Path =
4252 (InstallDir + "/../../../../" + TripleStr + "/libc" + Multilib.osSuffix())
4253 .str();
Simon Atanasyana61b7ec2013-10-10 07:57:44 +00004254
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004255 if (getVFS().exists(Path))
Simon Atanasyana61b7ec2013-10-10 07:57:44 +00004256 return Path;
4257
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00004258 Path = (InstallDir + "/../../../../sysroot" + Multilib.osSuffix()).str();
Simon Atanasyana61b7ec2013-10-10 07:57:44 +00004259
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004260 if (getVFS().exists(Path))
Simon Atanasyana61b7ec2013-10-10 07:57:44 +00004261 return Path;
4262
4263 return std::string();
Simon Atanasyan08450bd2013-04-20 08:15:03 +00004264}
4265
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004266std::string Linux::getDynamicLinker(const ArgList &Args) const {
4267 const llvm::Triple::ArchType Arch = getArch();
4268 const llvm::Triple &Triple = getTriple();
4269
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004270 const enum Distro Distro = DetectDistro(getDriver(), Arch);
4271
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004272 if (Triple.isAndroid())
4273 return Triple.isArch64Bit() ? "/system/bin/linker64" : "/system/bin/linker";
Rafael Espindola0fa66802016-06-24 21:35:06 +00004274 else if (Triple.isMusl()) {
4275 std::string ArchName;
4276 switch (Arch) {
4277 case llvm::Triple::thumb:
4278 ArchName = "arm";
4279 break;
4280 case llvm::Triple::thumbeb:
4281 ArchName = "armeb";
4282 break;
4283 default:
4284 ArchName = Triple.getArchName().str();
4285 }
4286 if (Triple.getEnvironment() == llvm::Triple::MuslEABIHF)
4287 ArchName += "hf";
4288
4289 return "/lib/ld-musl-" + ArchName + ".so.1";
4290 }
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004291
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004292 std::string LibDir;
4293 std::string Loader;
4294
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004295 switch (Arch) {
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004296 default:
4297 llvm_unreachable("unsupported architecture");
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004298
4299 case llvm::Triple::aarch64:
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004300 LibDir = "lib";
4301 Loader = "ld-linux-aarch64.so.1";
4302 break;
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004303 case llvm::Triple::aarch64_be:
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004304 LibDir = "lib";
4305 Loader = "ld-linux-aarch64_be.so.1";
4306 break;
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004307 case llvm::Triple::arm:
4308 case llvm::Triple::thumb:
4309 case llvm::Triple::armeb:
4310 case llvm::Triple::thumbeb: {
Vedant Kumar5fb00e42016-07-27 23:01:55 +00004311 const bool HF =
4312 Triple.getEnvironment() == llvm::Triple::GNUEABIHF ||
4313 tools::arm::getARMFloatABI(*this, Args) == tools::arm::FloatABI::Hard;
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004314
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004315 LibDir = "lib";
4316 Loader = HF ? "ld-linux-armhf.so.3" : "ld-linux.so.3";
4317 break;
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004318 }
4319 case llvm::Triple::mips:
4320 case llvm::Triple::mipsel:
4321 case llvm::Triple::mips64:
4322 case llvm::Triple::mips64el: {
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004323 bool LE = (Triple.getArch() == llvm::Triple::mipsel) ||
4324 (Triple.getArch() == llvm::Triple::mips64el);
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004325 bool IsNaN2008 = tools::mips::isNaN2008(Args, Triple);
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004326
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004327 LibDir = "lib" + tools::mips::getMipsABILibSuffix(Args, Triple);
4328
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004329 if (tools::mips::isUCLibc(Args))
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004330 Loader = IsNaN2008 ? "ld-uClibc-mipsn8.so.0" : "ld-uClibc.so.0";
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004331 else if (!Triple.hasEnvironment() &&
4332 Triple.getVendor() == llvm::Triple::VendorType::MipsTechnologies)
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004333 Loader = LE ? "ld-musl-mipsel.so.1" : "ld-musl-mips.so.1";
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004334 else
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004335 Loader = IsNaN2008 ? "ld-linux-mipsn8.so.1" : "ld.so.1";
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004336
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004337 break;
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004338 }
4339 case llvm::Triple::ppc:
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004340 LibDir = "lib";
4341 Loader = "ld.so.1";
4342 break;
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004343 case llvm::Triple::ppc64:
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004344 LibDir = "lib64";
4345 Loader =
4346 (tools::ppc::hasPPCAbiArg(Args, "elfv2")) ? "ld64.so.2" : "ld64.so.1";
4347 break;
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004348 case llvm::Triple::ppc64le:
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004349 LibDir = "lib64";
4350 Loader =
4351 (tools::ppc::hasPPCAbiArg(Args, "elfv1")) ? "ld64.so.1" : "ld64.so.2";
4352 break;
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004353 case llvm::Triple::sparc:
4354 case llvm::Triple::sparcel:
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004355 LibDir = "lib";
4356 Loader = "ld-linux.so.2";
4357 break;
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004358 case llvm::Triple::sparcv9:
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004359 LibDir = "lib64";
4360 Loader = "ld-linux.so.2";
4361 break;
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004362 case llvm::Triple::systemz:
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004363 LibDir = "lib";
4364 Loader = "ld64.so.1";
4365 break;
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004366 case llvm::Triple::x86:
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004367 LibDir = "lib";
4368 Loader = "ld-linux.so.2";
4369 break;
4370 case llvm::Triple::x86_64: {
4371 bool X32 = Triple.getEnvironment() == llvm::Triple::GNUX32;
4372
4373 LibDir = X32 ? "libx32" : "lib64";
4374 Loader = X32 ? "ld-linux-x32.so.2" : "ld-linux-x86-64.so.2";
4375 break;
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004376 }
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004377 }
4378
4379 if (Distro == Exherbo && (Triple.getVendor() == llvm::Triple::UnknownVendor ||
4380 Triple.getVendor() == llvm::Triple::PC))
4381 return "/usr/" + Triple.str() + "/lib/" + Loader;
4382 return "/" + LibDir + "/" + Loader;
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004383}
4384
Chandler Carrutha796f532011-11-05 20:17:13 +00004385void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
4386 ArgStringList &CC1Args) const {
4387 const Driver &D = getDriver();
Simon Atanasyana0d89572013-10-05 14:37:55 +00004388 std::string SysRoot = computeSysRoot();
Chandler Carrutha796f532011-11-05 20:17:13 +00004389
4390 if (DriverArgs.hasArg(options::OPT_nostdinc))
4391 return;
4392
4393 if (!DriverArgs.hasArg(options::OPT_nostdlibinc))
Simon Atanasyan08450bd2013-04-20 08:15:03 +00004394 addSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/local/include");
Chandler Carrutha796f532011-11-05 20:17:13 +00004395
4396 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
Rafael Espindola358256c2013-06-26 02:13:00 +00004397 SmallString<128> P(D.ResourceDir);
4398 llvm::sys::path::append(P, "include");
Yaron Keren92e1b622015-03-18 10:17:07 +00004399 addSystemInclude(DriverArgs, CC1Args, P);
Chandler Carrutha796f532011-11-05 20:17:13 +00004400 }
4401
4402 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
4403 return;
4404
4405 // Check for configure-time C include directories.
4406 StringRef CIncludeDirs(C_INCLUDE_DIRS);
4407 if (CIncludeDirs != "") {
4408 SmallVector<StringRef, 5> dirs;
4409 CIncludeDirs.split(dirs, ":");
Simon Atanasyan6f657c42014-05-08 19:32:46 +00004410 for (StringRef dir : dirs) {
Benjamin Kramer33cd6dc2015-02-18 18:45:54 +00004411 StringRef Prefix =
4412 llvm::sys::path::is_absolute(dir) ? StringRef(SysRoot) : "";
Simon Atanasyan6f657c42014-05-08 19:32:46 +00004413 addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir);
Chandler Carrutha796f532011-11-05 20:17:13 +00004414 }
4415 return;
4416 }
4417
4418 // Lacking those, try to detect the correct set of system includes for the
4419 // target triple.
4420
Simon Atanasyan9e49e142014-08-06 05:44:47 +00004421 // Add include directories specific to the selected multilib set and multilib.
4422 if (GCCInstallation.isValid()) {
Benjamin Kramerac75baa2015-03-22 15:56:12 +00004423 const auto &Callback = Multilibs.includeDirsCallback();
Simon Atanasyan9e49e142014-08-06 05:44:47 +00004424 if (Callback) {
Simon Atanasyana45502d2016-05-19 15:07:21 +00004425 for (const auto &Path : Callback(GCCInstallation.getMultilib()))
4426 addExternCSystemIncludeIfExists(
4427 DriverArgs, CC1Args, GCCInstallation.getInstallPath() + Path);
Simon Atanasyan9e49e142014-08-06 05:44:47 +00004428 }
Simon Atanasyan08450bd2013-04-20 08:15:03 +00004429 }
4430
Chandler Carruth5b77c6c2011-11-06 08:21:07 +00004431 // Implement generic Debian multiarch support.
4432 const StringRef X86_64MultiarchIncludeDirs[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004433 "/usr/include/x86_64-linux-gnu",
Chandler Carruth5b77c6c2011-11-06 08:21:07 +00004434
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004435 // FIXME: These are older forms of multiarch. It's not clear that they're
4436 // in use in any released version of Debian, so we should consider
4437 // removing them.
4438 "/usr/include/i686-linux-gnu/64", "/usr/include/i486-linux-gnu/64"};
Chandler Carruth5b77c6c2011-11-06 08:21:07 +00004439 const StringRef X86MultiarchIncludeDirs[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004440 "/usr/include/i386-linux-gnu",
Chandler Carruth5b77c6c2011-11-06 08:21:07 +00004441
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004442 // FIXME: These are older forms of multiarch. It's not clear that they're
4443 // in use in any released version of Debian, so we should consider
4444 // removing them.
4445 "/usr/include/x86_64-linux-gnu/32", "/usr/include/i686-linux-gnu",
4446 "/usr/include/i486-linux-gnu"};
Tim Northover9bb857a2013-01-31 12:13:10 +00004447 const StringRef AArch64MultiarchIncludeDirs[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004448 "/usr/include/aarch64-linux-gnu"};
Chandler Carruth5b77c6c2011-11-06 08:21:07 +00004449 const StringRef ARMMultiarchIncludeDirs[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004450 "/usr/include/arm-linux-gnueabi"};
Jiangning Liu61b06cb2012-07-31 08:06:29 +00004451 const StringRef ARMHFMultiarchIncludeDirs[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004452 "/usr/include/arm-linux-gnueabihf"};
Saleem Abdulrasool20f733a2015-12-11 06:20:59 +00004453 const StringRef ARMEBMultiarchIncludeDirs[] = {
4454 "/usr/include/armeb-linux-gnueabi"};
4455 const StringRef ARMEBHFMultiarchIncludeDirs[] = {
4456 "/usr/include/armeb-linux-gnueabihf"};
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004457 const StringRef MIPSMultiarchIncludeDirs[] = {"/usr/include/mips-linux-gnu"};
Eli Friedman7771c832011-11-11 03:05:19 +00004458 const StringRef MIPSELMultiarchIncludeDirs[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004459 "/usr/include/mipsel-linux-gnu"};
Simon Atanasyan3a46afa2014-06-24 19:00:12 +00004460 const StringRef MIPS64MultiarchIncludeDirs[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004461 "/usr/include/mips64-linux-gnu", "/usr/include/mips64-linux-gnuabi64"};
Simon Atanasyan3a46afa2014-06-24 19:00:12 +00004462 const StringRef MIPS64ELMultiarchIncludeDirs[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004463 "/usr/include/mips64el-linux-gnu",
4464 "/usr/include/mips64el-linux-gnuabi64"};
Chandler Carruth2e9d7312012-02-26 09:21:43 +00004465 const StringRef PPCMultiarchIncludeDirs[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004466 "/usr/include/powerpc-linux-gnu"};
Chandler Carruth2e9d7312012-02-26 09:21:43 +00004467 const StringRef PPC64MultiarchIncludeDirs[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004468 "/usr/include/powerpc64-linux-gnu"};
Ulrich Weiganda8331b92014-06-20 13:41:24 +00004469 const StringRef PPC64LEMultiarchIncludeDirs[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004470 "/usr/include/powerpc64le-linux-gnu"};
James Y Knight09677ad2015-06-05 13:44:43 +00004471 const StringRef SparcMultiarchIncludeDirs[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004472 "/usr/include/sparc-linux-gnu"};
James Y Knight09677ad2015-06-05 13:44:43 +00004473 const StringRef Sparc64MultiarchIncludeDirs[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004474 "/usr/include/sparc64-linux-gnu"};
Sylvestre Ledruc0babf22015-08-28 12:26:09 +00004475 const StringRef SYSTEMZMultiarchIncludeDirs[] = {
4476 "/usr/include/s390x-linux-gnu"};
Chandler Carruth5b77c6c2011-11-06 08:21:07 +00004477 ArrayRef<StringRef> MultiarchIncludeDirs;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00004478 switch (getTriple().getArch()) {
4479 case llvm::Triple::x86_64:
Chandler Carruth5b77c6c2011-11-06 08:21:07 +00004480 MultiarchIncludeDirs = X86_64MultiarchIncludeDirs;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00004481 break;
4482 case llvm::Triple::x86:
Chandler Carruth5b77c6c2011-11-06 08:21:07 +00004483 MultiarchIncludeDirs = X86MultiarchIncludeDirs;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00004484 break;
4485 case llvm::Triple::aarch64:
4486 case llvm::Triple::aarch64_be:
Tim Northover9bb857a2013-01-31 12:13:10 +00004487 MultiarchIncludeDirs = AArch64MultiarchIncludeDirs;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00004488 break;
4489 case llvm::Triple::arm:
Saleem Abdulrasool20f733a2015-12-11 06:20:59 +00004490 case llvm::Triple::thumb:
Jiangning Liu61b06cb2012-07-31 08:06:29 +00004491 if (getTriple().getEnvironment() == llvm::Triple::GNUEABIHF)
4492 MultiarchIncludeDirs = ARMHFMultiarchIncludeDirs;
4493 else
4494 MultiarchIncludeDirs = ARMMultiarchIncludeDirs;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00004495 break;
Saleem Abdulrasool20f733a2015-12-11 06:20:59 +00004496 case llvm::Triple::armeb:
4497 case llvm::Triple::thumbeb:
4498 if (getTriple().getEnvironment() == llvm::Triple::GNUEABIHF)
4499 MultiarchIncludeDirs = ARMEBHFMultiarchIncludeDirs;
4500 else
4501 MultiarchIncludeDirs = ARMEBMultiarchIncludeDirs;
4502 break;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00004503 case llvm::Triple::mips:
Eli Friedman7771c832011-11-11 03:05:19 +00004504 MultiarchIncludeDirs = MIPSMultiarchIncludeDirs;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00004505 break;
4506 case llvm::Triple::mipsel:
Eli Friedman7771c832011-11-11 03:05:19 +00004507 MultiarchIncludeDirs = MIPSELMultiarchIncludeDirs;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00004508 break;
4509 case llvm::Triple::mips64:
Simon Atanasyan3a46afa2014-06-24 19:00:12 +00004510 MultiarchIncludeDirs = MIPS64MultiarchIncludeDirs;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00004511 break;
4512 case llvm::Triple::mips64el:
Simon Atanasyan3a46afa2014-06-24 19:00:12 +00004513 MultiarchIncludeDirs = MIPS64ELMultiarchIncludeDirs;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00004514 break;
4515 case llvm::Triple::ppc:
Chandler Carruth2e9d7312012-02-26 09:21:43 +00004516 MultiarchIncludeDirs = PPCMultiarchIncludeDirs;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00004517 break;
4518 case llvm::Triple::ppc64:
Chandler Carruth2e9d7312012-02-26 09:21:43 +00004519 MultiarchIncludeDirs = PPC64MultiarchIncludeDirs;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00004520 break;
4521 case llvm::Triple::ppc64le:
Ulrich Weiganda8331b92014-06-20 13:41:24 +00004522 MultiarchIncludeDirs = PPC64LEMultiarchIncludeDirs;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00004523 break;
4524 case llvm::Triple::sparc:
James Y Knight09677ad2015-06-05 13:44:43 +00004525 MultiarchIncludeDirs = SparcMultiarchIncludeDirs;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00004526 break;
4527 case llvm::Triple::sparcv9:
James Y Knight09677ad2015-06-05 13:44:43 +00004528 MultiarchIncludeDirs = Sparc64MultiarchIncludeDirs;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00004529 break;
Sylvestre Ledruc0babf22015-08-28 12:26:09 +00004530 case llvm::Triple::systemz:
4531 MultiarchIncludeDirs = SYSTEMZMultiarchIncludeDirs;
4532 break;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00004533 default:
4534 break;
Chandler Carruth5b77c6c2011-11-06 08:21:07 +00004535 }
Simon Atanasyan6f657c42014-05-08 19:32:46 +00004536 for (StringRef Dir : MultiarchIncludeDirs) {
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004537 if (D.getVFS().exists(SysRoot + Dir)) {
Simon Atanasyan6f657c42014-05-08 19:32:46 +00004538 addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + Dir);
Chandler Carruth5b77c6c2011-11-06 08:21:07 +00004539 break;
4540 }
Chandler Carrutha796f532011-11-05 20:17:13 +00004541 }
4542
4543 if (getTriple().getOS() == llvm::Triple::RTEMS)
4544 return;
4545
Chandler Carruth475ab6a2011-11-08 17:19:47 +00004546 // Add an include of '/include' directly. This isn't provided by default by
4547 // system GCCs, but is often used with cross-compiling GCCs, and harmless to
4548 // add even when Clang is acting as-if it were a system compiler.
Simon Atanasyan08450bd2013-04-20 08:15:03 +00004549 addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/include");
Chandler Carruth475ab6a2011-11-08 17:19:47 +00004550
Simon Atanasyan08450bd2013-04-20 08:15:03 +00004551 addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include");
Chandler Carrutha796f532011-11-05 20:17:13 +00004552}
4553
Evgeniy Stepanov65bc2b12015-11-09 21:10:54 +00004554static std::string DetectLibcxxIncludePath(StringRef base) {
4555 std::error_code EC;
4556 int MaxVersion = 0;
4557 std::string MaxVersionString = "";
4558 for (llvm::sys::fs::directory_iterator LI(base, EC), LE; !EC && LI != LE;
4559 LI = LI.increment(EC)) {
4560 StringRef VersionText = llvm::sys::path::filename(LI->path());
4561 int Version;
4562 if (VersionText[0] == 'v' &&
4563 !VersionText.slice(1, StringRef::npos).getAsInteger(10, Version)) {
4564 if (Version > MaxVersion) {
4565 MaxVersion = Version;
4566 MaxVersionString = VersionText;
4567 }
4568 }
4569 }
4570 return MaxVersion ? (base + "/" + MaxVersionString).str() : "";
4571}
4572
Chandler Carrutha796f532011-11-05 20:17:13 +00004573void Linux::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
4574 ArgStringList &CC1Args) const {
4575 if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
4576 DriverArgs.hasArg(options::OPT_nostdincxx))
4577 return;
4578
Chandler Carruthf4701732011-11-07 09:01:17 +00004579 // Check if libc++ has been enabled and provide its include paths if so.
4580 if (GetCXXStdlibType(DriverArgs) == ToolChain::CST_Libcxx) {
Chandler Carruth5a3d8982014-01-20 09:42:24 +00004581 const std::string LibCXXIncludePathCandidates[] = {
Evgeniy Stepanov65bc2b12015-11-09 21:10:54 +00004582 DetectLibcxxIncludePath(getDriver().Dir + "/../include/c++"),
Yaron Keren5439b642016-05-17 19:01:16 +00004583 // If this is a development, non-installed, clang, libcxx will
4584 // not be found at ../include/c++ but it likely to be found at
4585 // one of the following two locations:
4586 DetectLibcxxIncludePath(getDriver().SysRoot + "/usr/local/include/c++"),
4587 DetectLibcxxIncludePath(getDriver().SysRoot + "/usr/include/c++") };
Simon Atanasyan6f657c42014-05-08 19:32:46 +00004588 for (const auto &IncludePath : LibCXXIncludePathCandidates) {
Evgeniy Stepanov65bc2b12015-11-09 21:10:54 +00004589 if (IncludePath.empty() || !getVFS().exists(IncludePath))
Chandler Carruth5a3d8982014-01-20 09:42:24 +00004590 continue;
4591 // Add the first candidate that exists.
Simon Atanasyan6f657c42014-05-08 19:32:46 +00004592 addSystemInclude(DriverArgs, CC1Args, IncludePath);
Chandler Carruth5a3d8982014-01-20 09:42:24 +00004593 break;
4594 }
Chandler Carruthf4701732011-11-07 09:01:17 +00004595 return;
4596 }
4597
Chandler Carrutha1f1fd32012-01-25 08:04:13 +00004598 // We need a detected GCC installation on Linux to provide libstdc++'s
4599 // headers. We handled the libc++ case above.
4600 if (!GCCInstallation.isValid())
4601 return;
Chandler Carrutha796f532011-11-05 20:17:13 +00004602
Chandler Carruthf5d4df92011-11-06 10:31:01 +00004603 // By default, look for the C++ headers in an include directory adjacent to
4604 // the lib directory of the GCC installation. Note that this is expect to be
4605 // equivalent to '/usr/include/c++/X.Y' in almost all cases.
4606 StringRef LibDir = GCCInstallation.getParentLibPath();
4607 StringRef InstallDir = GCCInstallation.getInstallPath();
Evgeniy Stepanov763671e2012-09-03 09:05:50 +00004608 StringRef TripleStr = GCCInstallation.getTriple().str();
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00004609 const Multilib &Multilib = GCCInstallation.getMultilib();
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004610 const std::string GCCMultiarchTriple = getMultiarchTriple(
4611 getDriver(), GCCInstallation.getTriple(), getDriver().SysRoot);
Chandler Carruthc44f4d42014-08-27 08:41:41 +00004612 const std::string TargetMultiarchTriple =
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004613 getMultiarchTriple(getDriver(), getTriple(), getDriver().SysRoot);
Chandler Carruth1f2b2f82013-08-26 08:59:53 +00004614 const GCCVersion &Version = GCCInstallation.getVersion();
Evgeniy Stepanov763671e2012-09-03 09:05:50 +00004615
Chandler Carruthc44f4d42014-08-27 08:41:41 +00004616 // The primary search for libstdc++ supports multiarch variants.
Chandler Carruth8677d922013-10-29 08:53:03 +00004617 if (addLibStdCXXIncludePaths(LibDir.str() + "/../include",
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004618 "/c++/" + Version.Text, TripleStr,
4619 GCCMultiarchTriple, TargetMultiarchTriple,
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00004620 Multilib.includeSuffix(), DriverArgs, CC1Args))
Dmitri Gribenko15225ae2013-03-06 17:14:05 +00004621 return;
4622
Chandler Carruthc44f4d42014-08-27 08:41:41 +00004623 // Otherwise, fall back on a bunch of options which don't use multiarch
4624 // layouts for simplicity.
Chandler Carruth5a3d8982014-01-20 09:42:24 +00004625 const std::string LibStdCXXIncludePathCandidates[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004626 // Gentoo is weird and places its headers inside the GCC install,
4627 // so if the first attempt to find the headers fails, try these patterns.
Chandler Carruth81296fb2016-05-08 07:59:56 +00004628 InstallDir.str() + "/include/g++-v" + Version.Text,
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004629 InstallDir.str() + "/include/g++-v" + Version.MajorStr + "." +
4630 Version.MinorStr,
4631 InstallDir.str() + "/include/g++-v" + Version.MajorStr,
4632 // Android standalone toolchain has C++ headers in yet another place.
4633 LibDir.str() + "/../" + TripleStr.str() + "/include/c++/" + Version.Text,
4634 // Freescale SDK C++ headers are directly in <sysroot>/usr/include/c++,
4635 // without a subdirectory corresponding to the gcc version.
4636 LibDir.str() + "/../include/c++",
Evgeniy Stepanov763671e2012-09-03 09:05:50 +00004637 };
4638
Simon Atanasyan6f657c42014-05-08 19:32:46 +00004639 for (const auto &IncludePath : LibStdCXXIncludePathCandidates) {
Chandler Carruthc44f4d42014-08-27 08:41:41 +00004640 if (addLibStdCXXIncludePaths(IncludePath, /*Suffix*/ "", TripleStr,
4641 /*GCCMultiarchTriple*/ "",
4642 /*TargetMultiarchTriple*/ "",
4643 Multilib.includeSuffix(), DriverArgs, CC1Args))
Evgeniy Stepanov763671e2012-09-03 09:05:50 +00004644 break;
Chandler Carruthf5d4df92011-11-06 10:31:01 +00004645 }
Chandler Carrutha796f532011-11-05 20:17:13 +00004646}
4647
Artem Belevichfa11ab52015-11-17 22:28:46 +00004648void Linux::AddCudaIncludeArgs(const ArgList &DriverArgs,
4649 ArgStringList &CC1Args) const {
4650 if (DriverArgs.hasArg(options::OPT_nocudainc))
4651 return;
4652
Justin Lebar423019d2016-04-16 00:11:11 +00004653 if (!CudaInstallation.isValid()) {
4654 getDriver().Diag(diag::err_drv_no_cuda_installation);
4655 return;
Artem Belevich86017332015-11-17 22:28:55 +00004656 }
Justin Lebar423019d2016-04-16 00:11:11 +00004657
4658 addSystemInclude(DriverArgs, CC1Args, CudaInstallation.getIncludePath());
4659 CC1Args.push_back("-include");
4660 CC1Args.push_back("__clang_cuda_runtime_wrapper.h");
Artem Belevichfa11ab52015-11-17 22:28:46 +00004661}
4662
Andrey Turetskiy4798eb62016-06-16 10:36:09 +00004663void Linux::AddIAMCUIncludeArgs(const ArgList &DriverArgs,
4664 ArgStringList &CC1Args) const {
4665 if (GCCInstallation.isValid()) {
4666 CC1Args.push_back("-isystem");
4667 CC1Args.push_back(DriverArgs.MakeArgString(
4668 GCCInstallation.getParentLibPath() + "/../" +
4669 GCCInstallation.getTriple().str() + "/include"));
4670 }
4671}
4672
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004673bool Linux::isPIEDefault() const { return getSanitizerArgs().requiresPIE(); }
Peter Collingbourne54d770c2013-04-09 04:35:11 +00004674
Alexey Samsonov7f2a0d22015-06-19 21:36:47 +00004675SanitizerMask Linux::getSupportedSanitizers() const {
4676 const bool IsX86 = getTriple().getArch() == llvm::Triple::x86;
4677 const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64;
4678 const bool IsMIPS64 = getTriple().getArch() == llvm::Triple::mips64 ||
4679 getTriple().getArch() == llvm::Triple::mips64el;
Jay Foade967dd02015-06-25 10:35:19 +00004680 const bool IsPowerPC64 = getTriple().getArch() == llvm::Triple::ppc64 ||
4681 getTriple().getArch() == llvm::Triple::ppc64le;
Adhemerval Zanella76aee672015-07-30 20:50:39 +00004682 const bool IsAArch64 = getTriple().getArch() == llvm::Triple::aarch64 ||
4683 getTriple().getArch() == llvm::Triple::aarch64_be;
Alexey Samsonov7f2a0d22015-06-19 21:36:47 +00004684 SanitizerMask Res = ToolChain::getSupportedSanitizers();
4685 Res |= SanitizerKind::Address;
4686 Res |= SanitizerKind::KernelAddress;
4687 Res |= SanitizerKind::Vptr;
Evgeniy Stepanov299238a2015-09-24 17:22:46 +00004688 Res |= SanitizerKind::SafeStack;
Adhemerval Zanella76aee672015-07-30 20:50:39 +00004689 if (IsX86_64 || IsMIPS64 || IsAArch64)
Alexey Samsonov7f2a0d22015-06-19 21:36:47 +00004690 Res |= SanitizerKind::DataFlow;
Adhemerval Zanellabffb20d2015-10-05 19:16:42 +00004691 if (IsX86_64 || IsMIPS64 || IsAArch64)
Alexey Samsonov7f2a0d22015-06-19 21:36:47 +00004692 Res |= SanitizerKind::Leak;
Bill Schmidt4b8841a2015-12-08 22:48:02 +00004693 if (IsX86_64 || IsMIPS64 || IsAArch64 || IsPowerPC64)
Alexey Samsonov7f2a0d22015-06-19 21:36:47 +00004694 Res |= SanitizerKind::Thread;
Adhemerval Zanella567b9262015-09-16 15:11:21 +00004695 if (IsX86_64 || IsMIPS64 || IsPowerPC64 || IsAArch64)
Jay Foade967dd02015-06-25 10:35:19 +00004696 Res |= SanitizerKind::Memory;
Derek Bruening256c2e12016-04-21 21:32:04 +00004697 if (IsX86_64)
4698 Res |= SanitizerKind::Efficiency;
Alexey Samsonov7f2a0d22015-06-19 21:36:47 +00004699 if (IsX86 || IsX86_64) {
4700 Res |= SanitizerKind::Function;
Alexey Samsonov7f2a0d22015-06-19 21:36:47 +00004701 }
4702 return Res;
4703}
4704
Vedant Kumar5fb00e42016-07-27 23:01:55 +00004705void Linux::addProfileRTLibs(const llvm::opt::ArgList &Args,
Xinliang David Li170cd102015-10-27 05:15:35 +00004706 llvm::opt::ArgStringList &CmdArgs) const {
Vedant Kumar5fb00e42016-07-27 23:01:55 +00004707 if (!needsProfileRT(Args)) return;
Xinliang David Li170cd102015-10-27 05:15:35 +00004708
4709 // Add linker option -u__llvm_runtime_variable to cause runtime
4710 // initialization module to be linked in.
4711 if (!Args.hasArg(options::OPT_coverage))
4712 CmdArgs.push_back(Args.MakeArgString(
4713 Twine("-u", llvm::getInstrProfRuntimeHookVarName())));
Vedant Kumar5fb00e42016-07-27 23:01:55 +00004714 ToolChain::addProfileRTLibs(Args, CmdArgs);
Xinliang David Li170cd102015-10-27 05:15:35 +00004715}
4716
Daniel Dunbarcc912342009-05-02 18:28:39 +00004717/// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly.
4718
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004719DragonFly::DragonFly(const Driver &D, const llvm::Triple &Triple,
4720 const ArgList &Args)
4721 : Generic_ELF(D, Triple, Args) {
Daniel Dunbarcc912342009-05-02 18:28:39 +00004722
4723 // Path mangling to find libexec
Daniel Dunbar88979912010-08-01 22:29:51 +00004724 getProgramPaths().push_back(getDriver().getInstalledDir());
Benjamin Kramer51477bd2011-03-01 22:50:47 +00004725 if (getDriver().getInstalledDir() != getDriver().Dir)
Daniel Dunbar88979912010-08-01 22:29:51 +00004726 getProgramPaths().push_back(getDriver().Dir);
Daniel Dunbarcc912342009-05-02 18:28:39 +00004727
Daniel Dunbar083edf72009-12-21 18:54:17 +00004728 getFilePaths().push_back(getDriver().Dir + "/../lib");
Daniel Dunbarcc912342009-05-02 18:28:39 +00004729 getFilePaths().push_back("/usr/lib");
Dimitry Andricf59a2b32015-12-27 10:01:44 +00004730 getFilePaths().push_back("/usr/lib/gcc50");
Daniel Dunbarcc912342009-05-02 18:28:39 +00004731}
4732
Rafael Espindola7cf32212013-03-20 03:05:54 +00004733Tool *DragonFly::buildAssembler() const {
Douglas Katzman95354292015-06-23 20:42:09 +00004734 return new tools::dragonfly::Assembler(*this);
Rafael Espindola7cf32212013-03-20 03:05:54 +00004735}
4736
4737Tool *DragonFly::buildLinker() const {
Douglas Katzman95354292015-06-23 20:42:09 +00004738 return new tools::dragonfly::Linker(*this);
Daniel Dunbarcc912342009-05-02 18:28:39 +00004739}
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004740
Justin Lebar21e5d4f2016-01-14 21:41:27 +00004741/// CUDA toolchain. Our assembler is ptxas, and our "linker" is fatbinary,
4742/// which isn't properly a linker but nonetheless performs the step of stitching
4743/// together object files from the assembler into a single blob.
Artem Belevich0ff05cd2015-07-13 23:27:56 +00004744
4745CudaToolChain::CudaToolChain(const Driver &D, const llvm::Triple &Triple,
4746 const ArgList &Args)
Justin Lebar21e5d4f2016-01-14 21:41:27 +00004747 : Linux(D, Triple, Args) {
4748 if (CudaInstallation.isValid())
4749 getProgramPaths().push_back(CudaInstallation.getBinPath());
4750}
Artem Belevich0ff05cd2015-07-13 23:27:56 +00004751
4752void
4753CudaToolChain::addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
4754 llvm::opt::ArgStringList &CC1Args) const {
4755 Linux::addClangTargetOptions(DriverArgs, CC1Args);
4756 CC1Args.push_back("-fcuda-is-device");
Artem Belevich34f481a2015-11-17 22:28:50 +00004757
Justin Lebard3a44f62016-04-05 18:26:20 +00004758 if (DriverArgs.hasFlag(options::OPT_fcuda_flush_denormals_to_zero,
4759 options::OPT_fno_cuda_flush_denormals_to_zero, false))
4760 CC1Args.push_back("-fcuda-flush-denormals-to-zero");
4761
Justin Lebar91f6f072016-05-23 20:19:56 +00004762 if (DriverArgs.hasFlag(options::OPT_fcuda_approx_transcendentals,
4763 options::OPT_fno_cuda_approx_transcendentals, false))
4764 CC1Args.push_back("-fcuda-approx-transcendentals");
4765
Artem Belevich34f481a2015-11-17 22:28:50 +00004766 if (DriverArgs.hasArg(options::OPT_nocudalib))
4767 return;
4768
4769 std::string LibDeviceFile = CudaInstallation.getLibDeviceFile(
4770 DriverArgs.getLastArgValue(options::OPT_march_EQ));
4771 if (!LibDeviceFile.empty()) {
4772 CC1Args.push_back("-mlink-cuda-bitcode");
4773 CC1Args.push_back(DriverArgs.MakeArgString(LibDeviceFile));
4774
4775 // Libdevice in CUDA-7.0 requires PTX version that's more recent
4776 // than LLVM defaults to. Use PTX4.2 which is the PTX version that
4777 // came with CUDA-7.0.
4778 CC1Args.push_back("-target-feature");
4779 CC1Args.push_back("+ptx42");
4780 }
Artem Belevich0ff05cd2015-07-13 23:27:56 +00004781}
4782
Justin Lebarc43ad9e2016-07-07 18:17:52 +00004783void CudaToolChain::AddCudaIncludeArgs(const ArgList &DriverArgs,
4784 ArgStringList &CC1Args) const {
4785 // Check our CUDA version if we're going to include the CUDA headers.
4786 if (!DriverArgs.hasArg(options::OPT_nocudainc) &&
Justin Lebarf3997712016-07-07 18:24:28 +00004787 !DriverArgs.hasArg(options::OPT_no_cuda_version_check)) {
Justin Lebarc43ad9e2016-07-07 18:17:52 +00004788 StringRef Arch = DriverArgs.getLastArgValue(options::OPT_march_EQ);
4789 assert(!Arch.empty() && "Must have an explicit GPU arch.");
4790 CudaInstallation.CheckCudaVersionSupportsArch(StringToCudaArch(Arch));
4791 }
4792 Linux::AddCudaIncludeArgs(DriverArgs, CC1Args);
4793}
4794
Artem Belevich0ff05cd2015-07-13 23:27:56 +00004795llvm::opt::DerivedArgList *
4796CudaToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args,
4797 const char *BoundArch) const {
4798 DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
4799 const OptTable &Opts = getDriver().getOpts();
4800
4801 for (Arg *A : Args) {
4802 if (A->getOption().matches(options::OPT_Xarch__)) {
4803 // Skip this argument unless the architecture matches BoundArch
Justin Lebar21e5d4f2016-01-14 21:41:27 +00004804 if (!BoundArch || A->getValue(0) != StringRef(BoundArch))
Artem Belevich0ff05cd2015-07-13 23:27:56 +00004805 continue;
4806
4807 unsigned Index = Args.getBaseArgs().MakeIndex(A->getValue(1));
4808 unsigned Prev = Index;
4809 std::unique_ptr<Arg> XarchArg(Opts.ParseOneArg(Args, Index));
4810
4811 // If the argument parsing failed or more than one argument was
4812 // consumed, the -Xarch_ argument's parameter tried to consume
4813 // extra arguments. Emit an error and ignore.
4814 //
4815 // We also want to disallow any options which would alter the
4816 // driver behavior; that isn't going to work in our model. We
4817 // use isDriverOption() as an approximation, although things
4818 // like -O4 are going to slip through.
4819 if (!XarchArg || Index > Prev + 1) {
4820 getDriver().Diag(diag::err_drv_invalid_Xarch_argument_with_args)
4821 << A->getAsString(Args);
4822 continue;
4823 } else if (XarchArg->getOption().hasFlag(options::DriverOption)) {
4824 getDriver().Diag(diag::err_drv_invalid_Xarch_argument_isdriver)
4825 << A->getAsString(Args);
4826 continue;
4827 }
4828 XarchArg->setBaseArg(A);
4829 A = XarchArg.release();
4830 DAL->AddSynthesizedArg(A);
4831 }
4832 DAL->append(A);
4833 }
4834
Justin Lebar4db224e2016-06-15 23:46:11 +00004835 if (BoundArch) {
4836 DAL->eraseArg(options::OPT_march_EQ);
Justin Lebar21e5d4f2016-01-14 21:41:27 +00004837 DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_march_EQ), BoundArch);
Justin Lebar4db224e2016-06-15 23:46:11 +00004838 }
Artem Belevich0ff05cd2015-07-13 23:27:56 +00004839 return DAL;
4840}
4841
Justin Lebar21e5d4f2016-01-14 21:41:27 +00004842Tool *CudaToolChain::buildAssembler() const {
4843 return new tools::NVPTX::Assembler(*this);
4844}
4845
4846Tool *CudaToolChain::buildLinker() const {
4847 return new tools::NVPTX::Linker(*this);
4848}
4849
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004850/// XCore tool chain
Douglas Katzman54366072015-07-27 16:53:08 +00004851XCoreToolChain::XCoreToolChain(const Driver &D, const llvm::Triple &Triple,
4852 const ArgList &Args)
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004853 : ToolChain(D, Triple, Args) {
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004854 // ProgramPaths are found via 'PATH' environment variable.
4855}
4856
Douglas Katzman54366072015-07-27 16:53:08 +00004857Tool *XCoreToolChain::buildAssembler() const {
Douglas Katzman95354292015-06-23 20:42:09 +00004858 return new tools::XCore::Assembler(*this);
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004859}
4860
Douglas Katzman54366072015-07-27 16:53:08 +00004861Tool *XCoreToolChain::buildLinker() const {
4862 return new tools::XCore::Linker(*this);
4863}
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004864
Douglas Katzman54366072015-07-27 16:53:08 +00004865bool XCoreToolChain::isPICDefault() const { return false; }
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004866
Douglas Katzman54366072015-07-27 16:53:08 +00004867bool XCoreToolChain::isPIEDefault() const { return false; }
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004868
Douglas Katzman54366072015-07-27 16:53:08 +00004869bool XCoreToolChain::isPICDefaultForced() const { return false; }
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004870
Douglas Katzman54366072015-07-27 16:53:08 +00004871bool XCoreToolChain::SupportsProfiling() const { return false; }
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004872
Douglas Katzman54366072015-07-27 16:53:08 +00004873bool XCoreToolChain::hasBlocksRuntime() const { return false; }
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004874
Douglas Katzman54366072015-07-27 16:53:08 +00004875void XCoreToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
4876 ArgStringList &CC1Args) const {
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004877 if (DriverArgs.hasArg(options::OPT_nostdinc) ||
4878 DriverArgs.hasArg(options::OPT_nostdlibinc))
4879 return;
4880 if (const char *cl_include_dir = getenv("XCC_C_INCLUDE_PATH")) {
4881 SmallVector<StringRef, 4> Dirs;
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004882 const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'};
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004883 StringRef(cl_include_dir).split(Dirs, StringRef(EnvPathSeparatorStr));
4884 ArrayRef<StringRef> DirVec(Dirs);
4885 addSystemIncludes(DriverArgs, CC1Args, DirVec);
4886 }
4887}
4888
Douglas Katzman54366072015-07-27 16:53:08 +00004889void XCoreToolChain::addClangTargetOptions(const ArgList &DriverArgs,
4890 ArgStringList &CC1Args) const {
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004891 CC1Args.push_back("-nostdsysteminc");
4892}
4893
Douglas Katzman54366072015-07-27 16:53:08 +00004894void XCoreToolChain::AddClangCXXStdlibIncludeArgs(
4895 const ArgList &DriverArgs, ArgStringList &CC1Args) const {
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004896 if (DriverArgs.hasArg(options::OPT_nostdinc) ||
Robert Lyttonf9710b32014-08-01 13:11:46 +00004897 DriverArgs.hasArg(options::OPT_nostdlibinc) ||
4898 DriverArgs.hasArg(options::OPT_nostdincxx))
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004899 return;
4900 if (const char *cl_include_dir = getenv("XCC_CPLUS_INCLUDE_PATH")) {
4901 SmallVector<StringRef, 4> Dirs;
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004902 const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'};
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004903 StringRef(cl_include_dir).split(Dirs, StringRef(EnvPathSeparatorStr));
4904 ArrayRef<StringRef> DirVec(Dirs);
4905 addSystemIncludes(DriverArgs, CC1Args, DirVec);
4906 }
4907}
4908
Douglas Katzman54366072015-07-27 16:53:08 +00004909void XCoreToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
4910 ArgStringList &CmdArgs) const {
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004911 // We don't output any lib args. This is handled by xcc.
4912}
Douglas Katzman84a75642015-06-19 14:55:19 +00004913
Douglas Katzmand6e597c2015-09-17 19:56:40 +00004914MyriadToolChain::MyriadToolChain(const Driver &D, const llvm::Triple &Triple,
4915 const ArgList &Args)
Douglas Katzman5eddc232016-05-09 19:09:59 +00004916 : Generic_ELF(D, Triple, Args) {
Douglas Katzmand6e597c2015-09-17 19:56:40 +00004917 // If a target of 'sparc-myriad-elf' is specified to clang, it wants to use
4918 // 'sparc-myriad--elf' (note the unknown OS) as the canonical triple.
4919 // This won't work to find gcc. Instead we give the installation detector an
4920 // extra triple, which is preferable to further hacks of the logic that at
4921 // present is based solely on getArch(). In particular, it would be wrong to
4922 // choose the myriad installation when targeting a non-myriad sparc install.
4923 switch (Triple.getArch()) {
4924 default:
Eric Christopherefef8ef2015-12-07 22:43:05 +00004925 D.Diag(diag::err_target_unsupported_arch) << Triple.getArchName()
4926 << "myriad";
Douglas Katzmand6e597c2015-09-17 19:56:40 +00004927 case llvm::Triple::sparc:
4928 case llvm::Triple::sparcel:
4929 case llvm::Triple::shave:
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004930 GCCInstallation.init(Triple, Args, {"sparc-myriad-elf"});
Douglas Katzmand6e597c2015-09-17 19:56:40 +00004931 }
Douglas Katzman674a3122015-11-18 16:24:46 +00004932
4933 if (GCCInstallation.isValid()) {
4934 // The contents of LibDir are independent of the version of gcc.
Douglas Katzman87da5f42016-07-25 16:36:02 +00004935 // This contains libc, libg, libm, libstdc++, libssp.
4936 // The 'ma1x00' and 'nofpu' variants are irrelevant.
Douglas Katzman674a3122015-11-18 16:24:46 +00004937 SmallString<128> LibDir(GCCInstallation.getParentLibPath());
Douglas Katzman87da5f42016-07-25 16:36:02 +00004938 llvm::sys::path::append(LibDir, "../sparc-myriad-elf/lib");
Douglas Katzman674a3122015-11-18 16:24:46 +00004939 addPathIfExists(D, LibDir, getFilePaths());
4940
4941 // This directory contains crt{i,n,begin,end}.o as well as libgcc.
4942 // These files are tied to a particular version of gcc.
4943 SmallString<128> CompilerSupportDir(GCCInstallation.getInstallPath());
Douglas Katzman674a3122015-11-18 16:24:46 +00004944 addPathIfExists(D, CompilerSupportDir, getFilePaths());
4945 }
Douglas Katzmand6e597c2015-09-17 19:56:40 +00004946}
4947
Angel Garcia Gomez637d1e62015-10-20 13:23:58 +00004948MyriadToolChain::~MyriadToolChain() {}
Douglas Katzmand6e597c2015-09-17 19:56:40 +00004949
Douglas Katzmanb1278f32015-09-17 21:20:16 +00004950void MyriadToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
4951 ArgStringList &CC1Args) const {
4952 if (!DriverArgs.hasArg(options::OPT_nostdinc))
4953 addSystemInclude(DriverArgs, CC1Args, getDriver().SysRoot + "/include");
4954}
4955
Eric Christopherefef8ef2015-12-07 22:43:05 +00004956void MyriadToolChain::AddClangCXXStdlibIncludeArgs(
4957 const ArgList &DriverArgs, ArgStringList &CC1Args) const {
James Y Knighta6c9ee72015-10-16 18:46:26 +00004958 if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
4959 DriverArgs.hasArg(options::OPT_nostdincxx))
4960 return;
4961
4962 // Only libstdc++, for now.
4963 StringRef LibDir = GCCInstallation.getParentLibPath();
4964 const GCCVersion &Version = GCCInstallation.getVersion();
4965 StringRef TripleStr = GCCInstallation.getTriple().str();
4966 const Multilib &Multilib = GCCInstallation.getMultilib();
4967
Eric Christopherefef8ef2015-12-07 22:43:05 +00004968 addLibStdCXXIncludePaths(
4969 LibDir.str() + "/../" + TripleStr.str() + "/include/c++/" + Version.Text,
4970 "", TripleStr, "", "", Multilib.includeSuffix(), DriverArgs, CC1Args);
James Y Knighta6c9ee72015-10-16 18:46:26 +00004971}
4972
Douglas Katzmand6e597c2015-09-17 19:56:40 +00004973// MyriadToolChain handles several triples:
4974// {shave,sparc{,el}}-myriad-{rtems,unknown}-elf
4975Tool *MyriadToolChain::SelectTool(const JobAction &JA) const {
4976 // The inherited method works fine if not targeting the SHAVE.
4977 if (!isShaveCompilation(getTriple()))
4978 return ToolChain::SelectTool(JA);
Douglas Katzman84a75642015-06-19 14:55:19 +00004979 switch (JA.getKind()) {
Douglas Katzman9dc4c622015-11-20 04:58:12 +00004980 case Action::PreprocessJobClass:
Douglas Katzman84a75642015-06-19 14:55:19 +00004981 case Action::CompileJobClass:
4982 if (!Compiler)
Douglas Katzman95354292015-06-23 20:42:09 +00004983 Compiler.reset(new tools::SHAVE::Compiler(*this));
Douglas Katzman84a75642015-06-19 14:55:19 +00004984 return Compiler.get();
4985 case Action::AssembleJobClass:
4986 if (!Assembler)
Douglas Katzman95354292015-06-23 20:42:09 +00004987 Assembler.reset(new tools::SHAVE::Assembler(*this));
Douglas Katzman84a75642015-06-19 14:55:19 +00004988 return Assembler.get();
4989 default:
4990 return ToolChain::getTool(JA.getKind());
4991 }
4992}
4993
Douglas Katzmand6e597c2015-09-17 19:56:40 +00004994Tool *MyriadToolChain::buildLinker() const {
4995 return new tools::Myriad::Linker(*this);
Douglas Katzman84a75642015-06-19 14:55:19 +00004996}
Dan Gohmanc2853072015-09-03 22:51:53 +00004997
Dan Gohman52816862015-12-16 23:30:41 +00004998WebAssembly::WebAssembly(const Driver &D, const llvm::Triple &Triple,
4999 const llvm::opt::ArgList &Args)
5000 : ToolChain(D, Triple, Args) {
Dan Gohman57b62c52016-02-22 19:26:15 +00005001
5002 assert(Triple.isArch32Bit() != Triple.isArch64Bit());
5003 getFilePaths().push_back(
5004 getDriver().SysRoot + "/lib" + (Triple.isArch32Bit() ? "32" : "64"));
5005
Dan Gohman52816862015-12-16 23:30:41 +00005006 // Use LLD by default.
5007 DefaultLinker = "lld";
5008}
5009
Dan Gohmanc2853072015-09-03 22:51:53 +00005010bool WebAssembly::IsMathErrnoDefault() const { return false; }
5011
5012bool WebAssembly::IsObjCNonFragileABIDefault() const { return true; }
5013
5014bool WebAssembly::UseObjCMixedDispatch() const { return true; }
5015
5016bool WebAssembly::isPICDefault() const { return false; }
5017
5018bool WebAssembly::isPIEDefault() const { return false; }
5019
5020bool WebAssembly::isPICDefaultForced() const { return false; }
5021
5022bool WebAssembly::IsIntegratedAssemblerDefault() const { return true; }
5023
5024// TODO: Support Objective C stuff.
5025bool WebAssembly::SupportsObjCGC() const { return false; }
5026
5027bool WebAssembly::hasBlocksRuntime() const { return false; }
5028
5029// TODO: Support profiling.
5030bool WebAssembly::SupportsProfiling() const { return false; }
5031
Dan Gohman52816862015-12-16 23:30:41 +00005032bool WebAssembly::HasNativeLLVMSupport() const { return true; }
5033
Dan Gohmanc2853072015-09-03 22:51:53 +00005034void WebAssembly::addClangTargetOptions(const ArgList &DriverArgs,
5035 ArgStringList &CC1Args) const {
5036 if (DriverArgs.hasFlag(options::OPT_fuse_init_array,
5037 options::OPT_fno_use_init_array, true))
5038 CC1Args.push_back("-fuse-init-array");
5039}
Filipe Cabecinhasc888e192015-10-14 12:25:43 +00005040
Dan Gohman6ad8f612016-01-14 16:00:13 +00005041ToolChain::RuntimeLibType WebAssembly::GetDefaultRuntimeLibType() const {
5042 return ToolChain::RLT_CompilerRT;
5043}
5044
5045ToolChain::CXXStdlibType WebAssembly::GetCXXStdlibType(const ArgList &Args) const {
5046 return ToolChain::CST_Libcxx;
5047}
5048
5049void WebAssembly::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
5050 ArgStringList &CC1Args) const {
5051 if (!DriverArgs.hasArg(options::OPT_nostdinc))
5052 addSystemInclude(DriverArgs, CC1Args, getDriver().SysRoot + "/include");
5053}
5054
5055void WebAssembly::AddClangCXXStdlibIncludeArgs(
5056 const llvm::opt::ArgList &DriverArgs,
5057 llvm::opt::ArgStringList &CC1Args) const {
5058 if (!DriverArgs.hasArg(options::OPT_nostdlibinc) &&
5059 !DriverArgs.hasArg(options::OPT_nostdincxx))
5060 addSystemInclude(DriverArgs, CC1Args,
5061 getDriver().SysRoot + "/include/c++/v1");
5062}
5063
Dan Gohman52816862015-12-16 23:30:41 +00005064Tool *WebAssembly::buildLinker() const {
5065 return new tools::wasm::Linker(*this);
5066}
5067
Filipe Cabecinhasc888e192015-10-14 12:25:43 +00005068PS4CPU::PS4CPU(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
5069 : Generic_ELF(D, Triple, Args) {
5070 if (Args.hasArg(options::OPT_static))
5071 D.Diag(diag::err_drv_unsupported_opt_for_target) << "-static" << "PS4";
5072
Paul Robinson9d613612016-05-16 17:22:25 +00005073 // Determine where to find the PS4 libraries. We use SCE_ORBIS_SDK_DIR
Filipe Cabecinhasc888e192015-10-14 12:25:43 +00005074 // if it exists; otherwise use the driver's installation path, which
5075 // should be <SDK_DIR>/host_tools/bin.
5076
5077 SmallString<512> PS4SDKDir;
Paul Robinson9d613612016-05-16 17:22:25 +00005078 if (const char *EnvValue = getenv("SCE_ORBIS_SDK_DIR")) {
Filipe Cabecinhasc888e192015-10-14 12:25:43 +00005079 if (!llvm::sys::fs::exists(EnvValue))
5080 getDriver().Diag(clang::diag::warn_drv_ps4_sdk_dir) << EnvValue;
5081 PS4SDKDir = EnvValue;
5082 } else {
5083 PS4SDKDir = getDriver().Dir;
5084 llvm::sys::path::append(PS4SDKDir, "/../../");
Eric Christopherefef8ef2015-12-07 22:43:05 +00005085 }
Filipe Cabecinhasc888e192015-10-14 12:25:43 +00005086
Eric Christopherefef8ef2015-12-07 22:43:05 +00005087 // By default, the driver won't report a warning if it can't find
Filipe Cabecinhasc888e192015-10-14 12:25:43 +00005088 // PS4's include or lib directories. This behavior could be changed if
Eric Christopherefef8ef2015-12-07 22:43:05 +00005089 // -Weverything or -Winvalid-or-nonexistent-directory options are passed.
Filipe Cabecinhasc888e192015-10-14 12:25:43 +00005090 // If -isysroot was passed, use that as the SDK base path.
5091 std::string PrefixDir;
5092 if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
5093 PrefixDir = A->getValue();
5094 if (!llvm::sys::fs::exists(PrefixDir))
5095 getDriver().Diag(clang::diag::warn_missing_sysroot) << PrefixDir;
5096 } else
5097 PrefixDir = PS4SDKDir.str();
5098
5099 SmallString<512> PS4SDKIncludeDir(PrefixDir);
5100 llvm::sys::path::append(PS4SDKIncludeDir, "target/include");
5101 if (!Args.hasArg(options::OPT_nostdinc) &&
5102 !Args.hasArg(options::OPT_nostdlibinc) &&
5103 !Args.hasArg(options::OPT_isysroot) &&
5104 !Args.hasArg(options::OPT__sysroot_EQ) &&
5105 !llvm::sys::fs::exists(PS4SDKIncludeDir)) {
5106 getDriver().Diag(clang::diag::warn_drv_unable_to_find_directory_expected)
5107 << "PS4 system headers" << PS4SDKIncludeDir;
5108 }
5109
5110 SmallString<512> PS4SDKLibDir(PS4SDKDir);
5111 llvm::sys::path::append(PS4SDKLibDir, "target/lib");
5112 if (!Args.hasArg(options::OPT_nostdlib) &&
5113 !Args.hasArg(options::OPT_nodefaultlibs) &&
5114 !Args.hasArg(options::OPT__sysroot_EQ) && !Args.hasArg(options::OPT_E) &&
5115 !Args.hasArg(options::OPT_c) && !Args.hasArg(options::OPT_S) &&
5116 !Args.hasArg(options::OPT_emit_ast) &&
5117 !llvm::sys::fs::exists(PS4SDKLibDir)) {
5118 getDriver().Diag(clang::diag::warn_drv_unable_to_find_directory_expected)
5119 << "PS4 system libraries" << PS4SDKLibDir;
5120 return;
5121 }
5122 getFilePaths().push_back(PS4SDKLibDir.str());
5123}
5124
5125Tool *PS4CPU::buildAssembler() const {
5126 return new tools::PS4cpu::Assemble(*this);
5127}
5128
5129Tool *PS4CPU::buildLinker() const { return new tools::PS4cpu::Link(*this); }
5130
5131bool PS4CPU::isPICDefault() const { return true; }
5132
5133bool PS4CPU::HasNativeLLVMSupport() const { return true; }
5134
5135SanitizerMask PS4CPU::getSupportedSanitizers() const {
5136 SanitizerMask Res = ToolChain::getSupportedSanitizers();
5137 Res |= SanitizerKind::Address;
5138 Res |= SanitizerKind::Vptr;
5139 return Res;
5140}