blob: b4a0c031416ae662b734dfddae8eb78497c3226d [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
Chad Rosierd3a0f952011-09-20 20:44:06 +0000179std::string Darwin::ComputeEffectiveClangTriple(const ArgList &Args,
180 types::ID InputType) const {
181 llvm::Triple Triple(ComputeLLVMTriple(Args, InputType));
Daniel Dunbar82eb4ce2010-08-23 22:35:37 +0000182
183 // If the target isn't initialized (e.g., an unknown Darwin platform, return
184 // the default triple).
185 if (!isTargetInitialized())
186 return Triple.getTriple();
NAKAMURA Takumi8b73b3e2011-06-03 03:49:51 +0000187
Tim Northover157d9112014-01-16 08:48:16 +0000188 SmallString<16> Str;
Tim Northover6f3ff222015-10-30 16:30:27 +0000189 if (isTargetWatchOSBased())
190 Str += "watchos";
191 else if (isTargetTvOSBased())
192 Str += "tvos";
193 else if (isTargetIOSBased())
194 Str += "ios";
195 else
196 Str += "macosx";
Tim Northover157d9112014-01-16 08:48:16 +0000197 Str += getTargetVersion().getAsString();
198 Triple.setOSName(Str);
Daniel Dunbar82eb4ce2010-08-23 22:35:37 +0000199
200 return Triple.getTriple();
201}
202
David Blaikie68e081d2011-12-20 02:48:34 +0000203void Generic_ELF::anchor() {}
204
Tim Northover157d9112014-01-16 08:48:16 +0000205Tool *MachO::getTool(Action::ActionClass AC) const {
Rafael Espindola260e28d2013-03-18 20:48:54 +0000206 switch (AC) {
Rafael Espindolac8e3a012013-03-18 18:50:01 +0000207 case Action::LipoJobClass:
Rafael Espindola7cf32212013-03-20 03:05:54 +0000208 if (!Lipo)
209 Lipo.reset(new tools::darwin::Lipo(*this));
210 return Lipo.get();
Rafael Espindolac8e3a012013-03-18 18:50:01 +0000211 case Action::DsymutilJobClass:
Rafael Espindola7cf32212013-03-20 03:05:54 +0000212 if (!Dsymutil)
213 Dsymutil.reset(new tools::darwin::Dsymutil(*this));
214 return Dsymutil.get();
Ben Langmuir9b9a8d32014-02-06 18:53:25 +0000215 case Action::VerifyDebugInfoJobClass:
Rafael Espindola7cf32212013-03-20 03:05:54 +0000216 if (!VerifyDebug)
217 VerifyDebug.reset(new tools::darwin::VerifyDebug(*this));
218 return VerifyDebug.get();
Rafael Espindolad15a8912013-03-19 00:36:57 +0000219 default:
Rafael Espindola7cf32212013-03-20 03:05:54 +0000220 return ToolChain::getTool(AC);
Daniel Dunbar03e0a4f2009-03-20 00:57:52 +0000221 }
Daniel Dunbar03e0a4f2009-03-20 00:57:52 +0000222}
223
Douglas Katzman95354292015-06-23 20:42:09 +0000224Tool *MachO::buildLinker() const { return new tools::darwin::Linker(*this); }
Rafael Espindola7cf32212013-03-20 03:05:54 +0000225
Tim Northover157d9112014-01-16 08:48:16 +0000226Tool *MachO::buildAssembler() const {
Douglas Katzman95354292015-06-23 20:42:09 +0000227 return new tools::darwin::Assembler(*this);
Rafael Espindola7cf32212013-03-20 03:05:54 +0000228}
Daniel Dunbar26d482a2009-09-18 08:15:03 +0000229
Douglas Katzman95354292015-06-23 20:42:09 +0000230DarwinClang::DarwinClang(const Driver &D, const llvm::Triple &Triple,
Rafael Espindola84b588b2013-03-18 18:10:27 +0000231 const ArgList &Args)
Douglas Katzman95354292015-06-23 20:42:09 +0000232 : Darwin(D, Triple, Args) {}
Daniel Dunbar6276f992009-09-18 08:15:13 +0000233
Tim Northover336f1892014-03-29 13:16:12 +0000234void DarwinClang::addClangWarningOptions(ArgStringList &CC1Args) const {
Tim Northover6f3ff222015-10-30 16:30:27 +0000235 // For modern targets, promote certain warnings to errors.
236 if (isTargetWatchOSBased() || getTriple().isArch64Bit()) {
Tim Northover336f1892014-03-29 13:16:12 +0000237 // Always enable -Wdeprecated-objc-isa-usage and promote it
238 // to an error.
239 CC1Args.push_back("-Wdeprecated-objc-isa-usage");
240 CC1Args.push_back("-Werror=deprecated-objc-isa-usage");
241
Tim Northover6f3ff222015-10-30 16:30:27 +0000242 // For iOS and watchOS, also error about implicit function declarations,
243 // as that can impact calling conventions.
244 if (!isTargetMacOS())
245 CC1Args.push_back("-Werror=implicit-function-declaration");
Tim Northover336f1892014-03-29 13:16:12 +0000246 }
247}
248
Tim Northover157d9112014-01-16 08:48:16 +0000249/// \brief Determine whether Objective-C automated reference counting is
250/// enabled.
251static bool isObjCAutoRefCount(const ArgList &Args) {
252 return Args.hasFlag(options::OPT_fobjc_arc, options::OPT_fno_objc_arc, false);
253}
254
John McCall31168b02011-06-15 23:02:42 +0000255void DarwinClang::AddLinkARCArgs(const ArgList &Args,
256 ArgStringList &CmdArgs) const {
Tim Northover157d9112014-01-16 08:48:16 +0000257 // Avoid linking compatibility stubs on i386 mac.
258 if (isTargetMacOS() && getArch() == llvm::Triple::x86)
259 return;
260
261 ObjCRuntime runtime = getDefaultObjCRuntime(/*nonfragile*/ true);
262
263 if ((runtime.hasNativeARC() || !isObjCAutoRefCount(Args)) &&
264 runtime.hasSubscripting())
265 return;
Eric Christopher551ef452011-08-23 17:56:55 +0000266
267 CmdArgs.push_back("-force_load");
Rafael Espindola358256c2013-06-26 02:13:00 +0000268 SmallString<128> P(getDriver().ClangExecutable);
269 llvm::sys::path::remove_filename(P); // 'clang'
270 llvm::sys::path::remove_filename(P); // 'bin'
Benjamin Kramer17381a02013-06-28 16:25:46 +0000271 llvm::sys::path::append(P, "lib", "arc", "libarclite_");
John McCall31168b02011-06-15 23:02:42 +0000272 // Mash in the platform.
Tim Northover6f3ff222015-10-30 16:30:27 +0000273 if (isTargetWatchOSSimulator())
274 P += "watchsimulator";
275 else if (isTargetWatchOS())
276 P += "watchos";
277 else if (isTargetTvOSSimulator())
278 P += "appletvsimulator";
279 else if (isTargetTvOS())
280 P += "appletvos";
281 else if (isTargetIOSSimulator())
Rafael Espindola358256c2013-06-26 02:13:00 +0000282 P += "iphonesimulator";
Argyrios Kyrtzidis058b4512011-10-18 17:40:15 +0000283 else if (isTargetIPhoneOS())
Rafael Espindola358256c2013-06-26 02:13:00 +0000284 P += "iphoneos";
John McCall31168b02011-06-15 23:02:42 +0000285 else
Rafael Espindola358256c2013-06-26 02:13:00 +0000286 P += "macosx";
287 P += ".a";
John McCall31168b02011-06-15 23:02:42 +0000288
Rafael Espindola358256c2013-06-26 02:13:00 +0000289 CmdArgs.push_back(Args.MakeArgString(P));
John McCall31168b02011-06-15 23:02:42 +0000290}
291
Tim Northover157d9112014-01-16 08:48:16 +0000292void MachO::AddLinkRuntimeLib(const ArgList &Args, ArgStringList &CmdArgs,
Kuba Brecka2735a0252014-10-31 00:08:57 +0000293 StringRef DarwinLibName, bool AlwaysLink,
Kuba Brecka9ff912d2014-11-04 17:35:17 +0000294 bool IsEmbedded, bool AddRPath) const {
295 SmallString<128> Dir(getDriver().ResourceDir);
296 llvm::sys::path::append(Dir, "lib", IsEmbedded ? "macho_embedded" : "darwin");
297
298 SmallString<128> P(Dir);
299 llvm::sys::path::append(P, DarwinLibName);
Eric Christopher551ef452011-08-23 17:56:55 +0000300
Eric Christopherc235d0c62011-06-22 17:41:40 +0000301 // For now, allow missing resource libraries to support developers who may
Alexey Samsonov8368b372012-11-21 14:17:42 +0000302 // not have compiler-rt checked out or integrated into their build (unless
303 // we explicitly force linking with this library).
Benjamin Kramerd45b2052015-10-07 15:48:01 +0000304 if (AlwaysLink || getVFS().exists(P))
Yaron Keren92e1b622015-03-18 10:17:07 +0000305 CmdArgs.push_back(Args.MakeArgString(P));
Kuba Brecka9ff912d2014-11-04 17:35:17 +0000306
307 // Adding the rpaths might negatively interact when other rpaths are involved,
308 // so we should make sure we add the rpaths last, after all user-specified
309 // rpaths. This is currently true from this place, but we need to be
310 // careful if this function is ever called before user's rpaths are emitted.
311 if (AddRPath) {
312 assert(DarwinLibName.endswith(".dylib") && "must be a dynamic library");
313
314 // Add @executable_path to rpath to support having the dylib copied with
315 // the executable.
316 CmdArgs.push_back("-rpath");
317 CmdArgs.push_back("@executable_path");
318
319 // Add the path to the resource dir to rpath to support using the dylib
320 // from the default location without copying.
321 CmdArgs.push_back("-rpath");
Yaron Keren92e1b622015-03-18 10:17:07 +0000322 CmdArgs.push_back(Args.MakeArgString(Dir));
Kuba Brecka9ff912d2014-11-04 17:35:17 +0000323 }
Eric Christopherc235d0c62011-06-22 17:41:40 +0000324}
325
Chris Bienemane60e7c22016-04-29 22:28:34 +0000326StringRef Darwin::getPlatformFamily() const {
327 switch (TargetPlatform) {
328 case DarwinPlatformKind::MacOS:
329 return "MacOSX";
330 case DarwinPlatformKind::IPhoneOS:
331 case DarwinPlatformKind::IPhoneOSSimulator:
332 return "iPhone";
333 case DarwinPlatformKind::TvOS:
334 case DarwinPlatformKind::TvOSSimulator:
335 return "AppleTV";
336 case DarwinPlatformKind::WatchOS:
337 case DarwinPlatformKind::WatchOSSimulator:
338 return "Watch";
339 }
340 llvm_unreachable("Unsupported platform");
341}
342
343StringRef Darwin::getSDKName(StringRef isysroot) {
344 // Assume SDK has path: SOME_PATH/SDKs/PlatformXX.YY.sdk
345 llvm::sys::path::const_iterator SDKDir;
346 auto BeginSDK = llvm::sys::path::begin(isysroot);
347 auto EndSDK = llvm::sys::path::end(isysroot);
348 for (auto IT = BeginSDK; IT != EndSDK; ++IT) {
349 StringRef SDK = *IT;
350 if (SDK.endswith(".sdk"))
351 return SDK.slice(0, SDK.size() - 4);
352 }
353 return "";
354}
355
Anna Zakse67b4022016-02-02 02:04:48 +0000356StringRef Darwin::getOSLibraryNameSuffix() const {
357 switch(TargetPlatform) {
358 case DarwinPlatformKind::MacOS:
359 return "osx";
360 case DarwinPlatformKind::IPhoneOS:
361 return "ios";
362 case DarwinPlatformKind::IPhoneOSSimulator:
363 return "iossim";
364 case DarwinPlatformKind::TvOS:
365 return "tvos";
366 case DarwinPlatformKind::TvOSSimulator:
367 return "tvossim";
368 case DarwinPlatformKind::WatchOS:
369 return "watchos";
370 case DarwinPlatformKind::WatchOSSimulator:
371 return "watchossim";
372 }
373 llvm_unreachable("Unsupported platform");
374}
375
Vedant Kumar5fb00e42016-07-27 23:01:55 +0000376void Darwin::addProfileRTLibs(const ArgList &Args,
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000377 ArgStringList &CmdArgs) const {
Vedant Kumar5fb00e42016-07-27 23:01:55 +0000378 if (!needsProfileRT(Args)) return;
Justin Bognerc7701242015-05-12 05:44:36 +0000379
Vedant Kumar5fb00e42016-07-27 23:01:55 +0000380 AddLinkRuntimeLib(Args, CmdArgs, (Twine("libclang_rt.profile_") +
381 getOSLibraryNameSuffix() + ".a").str(),
382 /*AlwaysLink*/ true);
Justin Bognerc7701242015-05-12 05:44:36 +0000383}
384
Alexey Samsonov498f3c32015-03-23 23:14:05 +0000385void DarwinClang::AddLinkSanitizerLibArgs(const ArgList &Args,
386 ArgStringList &CmdArgs,
387 StringRef Sanitizer) const {
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000388 AddLinkRuntimeLib(
389 Args, CmdArgs,
Anna Zakse67b4022016-02-02 02:04:48 +0000390 (Twine("libclang_rt.") + Sanitizer + "_" +
391 getOSLibraryNameSuffix() + "_dynamic.dylib").str(),
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000392 /*AlwaysLink*/ true, /*IsEmbedded*/ false,
393 /*AddRPath*/ true);
Alexey Samsonov498f3c32015-03-23 23:14:05 +0000394}
395
Jonas Hahnfeldd196fa52016-07-27 08:15:54 +0000396ToolChain::RuntimeLibType DarwinClang::GetRuntimeLibType(
397 const ArgList &Args) const {
398 if (Arg* A = Args.getLastArg(options::OPT_rtlib_EQ)) {
399 StringRef Value = A->getValue();
400 if (Value != "compiler-rt")
401 getDriver().Diag(diag::err_drv_unsupported_rtlib_for_platform)
402 << Value << "darwin";
403 }
404
405 return ToolChain::RLT_CompilerRT;
406}
407
Vedant Kumar5fb00e42016-07-27 23:01:55 +0000408void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args,
Daniel Dunbar6276f992009-09-18 08:15:13 +0000409 ArgStringList &CmdArgs) const {
Jonas Hahnfeldd196fa52016-07-27 08:15:54 +0000410 // Call once to ensure diagnostic is printed if wrong value was specified
411 GetRuntimeLibType(Args);
Daniel Dunbarf4916cd2011-12-07 23:03:15 +0000412
Daniel Dunbar7cde09a2010-01-22 03:38:14 +0000413 // Darwin doesn't support real static executables, don't link any runtime
414 // libraries with -static.
Daniel Dunbarbd847cc2012-10-15 22:23:53 +0000415 if (Args.hasArg(options::OPT_static) ||
416 Args.hasArg(options::OPT_fapple_kext) ||
417 Args.hasArg(options::OPT_mkernel))
Daniel Dunbar6276f992009-09-18 08:15:13 +0000418 return;
Daniel Dunbar6276f992009-09-18 08:15:13 +0000419
420 // Reject -static-libgcc for now, we can deal with this when and if someone
421 // cares. This is useful in situations where someone wants to statically link
422 // something like libstdc++, and needs its runtime support routines.
423 if (const Arg *A = Args.getLastArg(options::OPT_static_libgcc)) {
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000424 getDriver().Diag(diag::err_drv_unsupported_opt) << A->getAsString(Args);
Daniel Dunbar6276f992009-09-18 08:15:13 +0000425 return;
426 }
427
Peter Collingbourne32701642013-11-01 18:16:25 +0000428 const SanitizerArgs &Sanitize = getSanitizerArgs();
Alexey Samsonov7f2a0d22015-06-19 21:36:47 +0000429 if (Sanitize.needsAsanRt())
430 AddLinkSanitizerLibArgs(Args, CmdArgs, "asan");
431 if (Sanitize.needsUbsanRt())
432 AddLinkSanitizerLibArgs(Args, CmdArgs, "ubsan");
Kuba Brecka85e01c02015-11-06 15:09:20 +0000433 if (Sanitize.needsTsanRt())
434 AddLinkSanitizerLibArgs(Args, CmdArgs, "tsan");
Peter Collingbournedc134532016-01-16 00:31:22 +0000435 if (Sanitize.needsStatsRt()) {
436 StringRef OS = isTargetMacOS() ? "osx" : "iossim";
437 AddLinkRuntimeLib(Args, CmdArgs,
438 (Twine("libclang_rt.stats_client_") + OS + ".a").str(),
439 /*AlwaysLink=*/true);
440 AddLinkSanitizerLibArgs(Args, CmdArgs, "stats");
441 }
Derek Bruening256c2e12016-04-21 21:32:04 +0000442 if (Sanitize.needsEsanRt())
443 AddLinkSanitizerLibArgs(Args, CmdArgs, "esan");
Daniel Dunbar1d6469f2011-12-01 23:40:18 +0000444
Daniel Dunbar7cde09a2010-01-22 03:38:14 +0000445 // Otherwise link libSystem, then the dynamic runtime library, and finally any
446 // target specific static runtime library.
Daniel Dunbar6276f992009-09-18 08:15:13 +0000447 CmdArgs.push_back("-lSystem");
Daniel Dunbar7cde09a2010-01-22 03:38:14 +0000448
449 // Select the dynamic runtime library and the target specific static library.
Tim Northover6f3ff222015-10-30 16:30:27 +0000450 if (isTargetWatchOSBased()) {
451 // We currently always need a static runtime library for watchOS.
452 AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.watchos.a");
453 } else if (isTargetTvOSBased()) {
454 // We currently always need a static runtime library for tvOS.
455 AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.tvos.a");
456 } else if (isTargetIOSBased()) {
Daniel Dunbar2f31fb92011-04-30 04:25:16 +0000457 // If we are compiling as iOS / simulator, don't attempt to link libgcc_s.1,
458 // it never went into the SDK.
Bob Wilson102be442011-10-07 17:54:41 +0000459 // Linking against libgcc_s.1 isn't needed for iOS 5.0+
Tim Northovera2ee4332014-03-29 15:09:45 +0000460 if (isIPhoneOSVersionLT(5, 0) && !isTargetIOSSimulator() &&
Tim Northover40956e62014-07-23 12:32:58 +0000461 getTriple().getArch() != llvm::Triple::aarch64)
Bob Wilson102be442011-10-07 17:54:41 +0000462 CmdArgs.push_back("-lgcc_s.1");
Daniel Dunbar7cde09a2010-01-22 03:38:14 +0000463
Daniel Dunbard1076382011-04-18 23:48:36 +0000464 // We currently always need a static runtime library for iOS.
Eric Christopherc235d0c62011-06-22 17:41:40 +0000465 AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.ios.a");
Daniel Dunbar7cde09a2010-01-22 03:38:14 +0000466 } else {
Tim Northover9c7e0352013-12-12 11:55:52 +0000467 assert(isTargetMacOS() && "unexpected non MacOS platform");
Daniel Dunbar7cde09a2010-01-22 03:38:14 +0000468 // The dynamic runtime library was merged with libSystem for 10.6 and
469 // beyond; only 10.4 and 10.5 need an additional runtime library.
Daniel Dunbar6d23b2f2010-01-27 00:57:03 +0000470 if (isMacosxVersionLT(10, 5))
Daniel Dunbar7cde09a2010-01-22 03:38:14 +0000471 CmdArgs.push_back("-lgcc_s.10.4");
Daniel Dunbar6d23b2f2010-01-27 00:57:03 +0000472 else if (isMacosxVersionLT(10, 6))
Daniel Dunbar7cde09a2010-01-22 03:38:14 +0000473 CmdArgs.push_back("-lgcc_s.10.5");
474
Daniel Dunbarda4f6b52010-09-22 00:03:52 +0000475 // For OS X, we thought we would only need a static runtime library when
Chris Lattner57540c52011-04-15 05:22:18 +0000476 // targeting 10.4, to provide versions of the static functions which were
Daniel Dunbarda4f6b52010-09-22 00:03:52 +0000477 // omitted from 10.4.dylib.
478 //
479 // Unfortunately, that turned out to not be true, because Darwin system
480 // headers can still use eprintf on i386, and it is not exported from
481 // libSystem. Therefore, we still must provide a runtime library just for
482 // the tiny tiny handful of projects that *might* use that symbol.
483 if (isMacosxVersionLT(10, 5)) {
Eric Christopherc235d0c62011-06-22 17:41:40 +0000484 AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.10.4.a");
Daniel Dunbarda4f6b52010-09-22 00:03:52 +0000485 } else {
486 if (getTriple().getArch() == llvm::Triple::x86)
Eric Christopherc235d0c62011-06-22 17:41:40 +0000487 AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.eprintf.a");
488 AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.osx.a");
Daniel Dunbarda4f6b52010-09-22 00:03:52 +0000489 }
Daniel Dunbar7cde09a2010-01-22 03:38:14 +0000490 }
Daniel Dunbar6276f992009-09-18 08:15:13 +0000491}
492
Daniel Dunbar354e96d2010-07-19 17:11:36 +0000493void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
Daniel Dunbar083edf72009-12-21 18:54:17 +0000494 const OptTable &Opts = getDriver().getOpts();
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000495
Daniel Dunbar455a0492012-08-17 18:43:50 +0000496 // Support allowing the SDKROOT environment variable used by xcrun and other
497 // Xcode tools to define the default sysroot, by making it the default for
498 // isysroot.
Chad Rosier6c2b11c2012-12-19 23:41:50 +0000499 if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
500 // Warn if the path does not exist.
Benjamin Kramerd45b2052015-10-07 15:48:01 +0000501 if (!getVFS().exists(A->getValue()))
Chad Rosier6c2b11c2012-12-19 23:41:50 +0000502 getDriver().Diag(clang::diag::warn_missing_sysroot) << A->getValue();
503 } else {
Daniel Dunbar455a0492012-08-17 18:43:50 +0000504 if (char *env = ::getenv("SDKROOT")) {
Daniel Dunbarb2543042013-01-15 20:33:56 +0000505 // We only use this value as the default if it is an absolute path,
506 // exists, and it is not the root path.
Benjamin Kramerd45b2052015-10-07 15:48:01 +0000507 if (llvm::sys::path::is_absolute(env) && getVFS().exists(env) &&
Daniel Dunbarb2543042013-01-15 20:33:56 +0000508 StringRef(env) != "/") {
Daniel Dunbar455a0492012-08-17 18:43:50 +0000509 Args.append(Args.MakeSeparateArg(
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000510 nullptr, Opts.getOption(options::OPT_isysroot), env));
Daniel Dunbar455a0492012-08-17 18:43:50 +0000511 }
512 }
513 }
514
Daniel Dunbar3b8e50d2010-01-27 00:56:25 +0000515 Arg *OSXVersion = Args.getLastArg(options::OPT_mmacosx_version_min_EQ);
Daniel Dunbar9aaeb642011-04-30 04:15:58 +0000516 Arg *iOSVersion = Args.getLastArg(options::OPT_miphoneos_version_min_EQ);
Tim Northover6f3ff222015-10-30 16:30:27 +0000517 Arg *TvOSVersion = Args.getLastArg(options::OPT_mtvos_version_min_EQ);
518 Arg *WatchOSVersion = Args.getLastArg(options::OPT_mwatchos_version_min_EQ);
Eli Friedman027e9c32012-01-11 02:41:15 +0000519
Tim Northover6f3ff222015-10-30 16:30:27 +0000520 if (OSXVersion && (iOSVersion || TvOSVersion || WatchOSVersion)) {
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000521 getDriver().Diag(diag::err_drv_argument_not_allowed_with)
Tim Northover6f3ff222015-10-30 16:30:27 +0000522 << OSXVersion->getAsString(Args)
523 << (iOSVersion ? iOSVersion :
524 TvOSVersion ? TvOSVersion : WatchOSVersion)->getAsString(Args);
525 iOSVersion = TvOSVersion = WatchOSVersion = nullptr;
526 } else if (iOSVersion && (TvOSVersion || WatchOSVersion)) {
527 getDriver().Diag(diag::err_drv_argument_not_allowed_with)
528 << iOSVersion->getAsString(Args)
529 << (TvOSVersion ? TvOSVersion : WatchOSVersion)->getAsString(Args);
530 TvOSVersion = WatchOSVersion = nullptr;
531 } else if (TvOSVersion && WatchOSVersion) {
532 getDriver().Diag(diag::err_drv_argument_not_allowed_with)
533 << TvOSVersion->getAsString(Args)
534 << WatchOSVersion->getAsString(Args);
535 WatchOSVersion = nullptr;
536 } else if (!OSXVersion && !iOSVersion && !TvOSVersion && !WatchOSVersion) {
Chad Rosier64707fe2011-08-31 20:56:25 +0000537 // If no deployment target was specified on the command line, check for
Daniel Dunbard54669d2010-01-26 01:45:19 +0000538 // environment defines.
Alexey Samsonov905c8022015-06-18 21:46:05 +0000539 std::string OSXTarget;
540 std::string iOSTarget;
Tim Northover6f3ff222015-10-30 16:30:27 +0000541 std::string TvOSTarget;
542 std::string WatchOSTarget;
543
Chad Rosier64707fe2011-08-31 20:56:25 +0000544 if (char *env = ::getenv("MACOSX_DEPLOYMENT_TARGET"))
545 OSXTarget = env;
546 if (char *env = ::getenv("IPHONEOS_DEPLOYMENT_TARGET"))
547 iOSTarget = env;
Tim Northover6f3ff222015-10-30 16:30:27 +0000548 if (char *env = ::getenv("TVOS_DEPLOYMENT_TARGET"))
549 TvOSTarget = env;
550 if (char *env = ::getenv("WATCHOS_DEPLOYMENT_TARGET"))
551 WatchOSTarget = env;
Daniel Dunbarb5023e92009-04-10 21:00:07 +0000552
Steven Wu7a1372c2015-06-25 01:59:35 +0000553 // If there is no command-line argument to specify the Target version and
554 // no environment variable defined, see if we can set the default based
555 // on -isysroot.
Tim Northover6f3ff222015-10-30 16:30:27 +0000556 if (OSXTarget.empty() && iOSTarget.empty() && WatchOSTarget.empty() &&
Frederic Riss3ad83bd2016-01-12 23:47:59 +0000557 TvOSTarget.empty() && Args.hasArg(options::OPT_isysroot)) {
Chad Rosier64707fe2011-08-31 20:56:25 +0000558 if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
Richard Smithbd55daf2012-11-01 04:30:05 +0000559 StringRef isysroot = A->getValue();
Chris Bienemane60e7c22016-04-29 22:28:34 +0000560 StringRef SDK = getSDKName(isysroot);
561 if (SDK.size() > 0) {
Steven Wu7a1372c2015-06-25 01:59:35 +0000562 // Slice the version number out.
563 // Version number is between the first and the last number.
564 size_t StartVer = SDK.find_first_of("0123456789");
565 size_t EndVer = SDK.find_last_of("0123456789");
566 if (StartVer != StringRef::npos && EndVer > StartVer) {
567 StringRef Version = SDK.slice(StartVer, EndVer + 1);
568 if (SDK.startswith("iPhoneOS") ||
569 SDK.startswith("iPhoneSimulator"))
570 iOSTarget = Version;
571 else if (SDK.startswith("MacOSX"))
572 OSXTarget = Version;
Tim Northover6f3ff222015-10-30 16:30:27 +0000573 else if (SDK.startswith("WatchOS") ||
574 SDK.startswith("WatchSimulator"))
575 WatchOSTarget = Version;
576 else if (SDK.startswith("AppleTVOS") ||
577 SDK.startswith("AppleTVSimulator"))
578 TvOSTarget = Version;
Steven Wu7a1372c2015-06-25 01:59:35 +0000579 }
580 }
Chad Rosier64707fe2011-08-31 20:56:25 +0000581 }
582 }
Daniel Dunbard54669d2010-01-26 01:45:19 +0000583
Alexey Samsonovfd0bb3a2015-06-18 00:36:38 +0000584 // If no OSX or iOS target has been specified, try to guess platform
Alexey Samsonov905c8022015-06-18 21:46:05 +0000585 // from arch name and compute the version from the triple.
Tim Northover6f3ff222015-10-30 16:30:27 +0000586 if (OSXTarget.empty() && iOSTarget.empty() && TvOSTarget.empty() &&
587 WatchOSTarget.empty()) {
Alexey Samsonovfd0bb3a2015-06-18 00:36:38 +0000588 StringRef MachOArchName = getMachOArchName(Args);
Alexey Samsonov905c8022015-06-18 21:46:05 +0000589 unsigned Major, Minor, Micro;
Alexey Samsonovfd0bb3a2015-06-18 00:36:38 +0000590 if (MachOArchName == "armv7" || MachOArchName == "armv7s" ||
Alexey Samsonov905c8022015-06-18 21:46:05 +0000591 MachOArchName == "arm64") {
592 getTriple().getiOSVersion(Major, Minor, Micro);
593 llvm::raw_string_ostream(iOSTarget) << Major << '.' << Minor << '.'
594 << Micro;
Tim Northover6f3ff222015-10-30 16:30:27 +0000595 } else if (MachOArchName == "armv7k") {
596 getTriple().getWatchOSVersion(Major, Minor, Micro);
597 llvm::raw_string_ostream(WatchOSTarget) << Major << '.' << Minor << '.'
598 << Micro;
Alexey Samsonov905c8022015-06-18 21:46:05 +0000599 } else if (MachOArchName != "armv6m" && MachOArchName != "armv7m" &&
600 MachOArchName != "armv7em") {
601 if (!getTriple().getMacOSXVersion(Major, Minor, Micro)) {
602 getDriver().Diag(diag::err_drv_invalid_darwin_version)
603 << getTriple().getOSName();
604 }
605 llvm::raw_string_ostream(OSXTarget) << Major << '.' << Minor << '.'
606 << Micro;
607 }
Alexey Samsonovfd0bb3a2015-06-18 00:36:38 +0000608 }
Chad Rosierfe6fd362011-09-28 00:46:32 +0000609
Tim Northover6f3ff222015-10-30 16:30:27 +0000610 // Do not allow conflicts with the watchOS target.
611 if (!WatchOSTarget.empty() && (!iOSTarget.empty() || !TvOSTarget.empty())) {
612 getDriver().Diag(diag::err_drv_conflicting_deployment_targets)
613 << "WATCHOS_DEPLOYMENT_TARGET"
614 << (!iOSTarget.empty() ? "IPHONEOS_DEPLOYMENT_TARGET" :
615 "TVOS_DEPLOYMENT_TARGET");
616 }
617
618 // Do not allow conflicts with the tvOS target.
619 if (!TvOSTarget.empty() && !iOSTarget.empty()) {
620 getDriver().Diag(diag::err_drv_conflicting_deployment_targets)
621 << "TVOS_DEPLOYMENT_TARGET"
622 << "IPHONEOS_DEPLOYMENT_TARGET";
623 }
624
Daniel Dunbar9aaeb642011-04-30 04:15:58 +0000625 // Allow conflicts among OSX and iOS for historical reasons, but choose the
626 // default platform.
Tim Northover6f3ff222015-10-30 16:30:27 +0000627 if (!OSXTarget.empty() && (!iOSTarget.empty() ||
628 !WatchOSTarget.empty() ||
629 !TvOSTarget.empty())) {
Daniel Dunbarffa70e82010-02-02 17:31:12 +0000630 if (getTriple().getArch() == llvm::Triple::arm ||
Tim Northover573cbee2014-05-24 12:52:07 +0000631 getTriple().getArch() == llvm::Triple::aarch64 ||
Daniel Dunbarffa70e82010-02-02 17:31:12 +0000632 getTriple().getArch() == llvm::Triple::thumb)
Chad Rosier64707fe2011-08-31 20:56:25 +0000633 OSXTarget = "";
Daniel Dunbarffa70e82010-02-02 17:31:12 +0000634 else
Tim Northover6f3ff222015-10-30 16:30:27 +0000635 iOSTarget = WatchOSTarget = TvOSTarget = "";
Daniel Dunbarffa70e82010-02-02 17:31:12 +0000636 }
Daniel Dunbar65969842010-01-29 17:02:25 +0000637
Chad Rosier64707fe2011-08-31 20:56:25 +0000638 if (!OSXTarget.empty()) {
Michael J. Spencerfc790902012-10-19 22:36:40 +0000639 const Option O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
Craig Topper92fc2df2014-05-17 16:56:41 +0000640 OSXVersion = Args.MakeJoinedArg(nullptr, O, OSXTarget);
Daniel Dunbar354e96d2010-07-19 17:11:36 +0000641 Args.append(OSXVersion);
Chad Rosier64707fe2011-08-31 20:56:25 +0000642 } else if (!iOSTarget.empty()) {
Michael J. Spencerfc790902012-10-19 22:36:40 +0000643 const Option O = Opts.getOption(options::OPT_miphoneos_version_min_EQ);
Craig Topper92fc2df2014-05-17 16:56:41 +0000644 iOSVersion = Args.MakeJoinedArg(nullptr, O, iOSTarget);
Daniel Dunbar9aaeb642011-04-30 04:15:58 +0000645 Args.append(iOSVersion);
Tim Northover6f3ff222015-10-30 16:30:27 +0000646 } else if (!TvOSTarget.empty()) {
647 const Option O = Opts.getOption(options::OPT_mtvos_version_min_EQ);
648 TvOSVersion = Args.MakeJoinedArg(nullptr, O, TvOSTarget);
649 Args.append(TvOSVersion);
650 } else if (!WatchOSTarget.empty()) {
651 const Option O = Opts.getOption(options::OPT_mwatchos_version_min_EQ);
652 WatchOSVersion = Args.MakeJoinedArg(nullptr, O, WatchOSTarget);
653 Args.append(WatchOSVersion);
Daniel Dunbar84e727f2009-09-04 18:35:21 +0000654 }
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000655 }
Mike Stump11289f42009-09-09 15:08:12 +0000656
Tim Northover9c7e0352013-12-12 11:55:52 +0000657 DarwinPlatformKind Platform;
658 if (OSXVersion)
659 Platform = MacOS;
660 else if (iOSVersion)
661 Platform = IPhoneOS;
Tim Northover6f3ff222015-10-30 16:30:27 +0000662 else if (TvOSVersion)
663 Platform = TvOS;
664 else if (WatchOSVersion)
665 Platform = WatchOS;
Tim Northover9c7e0352013-12-12 11:55:52 +0000666 else
Tim Northover157d9112014-01-16 08:48:16 +0000667 llvm_unreachable("Unable to infer Darwin variant");
Tim Northover9c7e0352013-12-12 11:55:52 +0000668
Daniel Dunbar3b8e50d2010-01-27 00:56:25 +0000669 // Set the tool chain target information.
670 unsigned Major, Minor, Micro;
671 bool HadExtra;
Tim Northover9c7e0352013-12-12 11:55:52 +0000672 if (Platform == MacOS) {
Tim Northover6f3ff222015-10-30 16:30:27 +0000673 assert((!iOSVersion && !TvOSVersion && !WatchOSVersion) &&
674 "Unknown target platform!");
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000675 if (!Driver::GetReleaseVersion(OSXVersion->getValue(), Major, Minor, Micro,
676 HadExtra) ||
677 HadExtra || Major != 10 || Minor >= 100 || Micro >= 100)
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000678 getDriver().Diag(diag::err_drv_invalid_version_number)
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000679 << OSXVersion->getAsString(Args);
Bob Wilson7f294b52014-10-10 23:10:10 +0000680 } else if (Platform == IPhoneOS) {
681 assert(iOSVersion && "Unknown target platform!");
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000682 if (!Driver::GetReleaseVersion(iOSVersion->getValue(), Major, Minor, Micro,
683 HadExtra) ||
Bob Wilson4cf27c42016-07-18 20:29:14 +0000684 HadExtra || Major >= 100 || Minor >= 100 || Micro >= 100)
Eli Friedman027e9c32012-01-11 02:41:15 +0000685 getDriver().Diag(diag::err_drv_invalid_version_number)
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000686 << iOSVersion->getAsString(Args);
Tim Northover6f3ff222015-10-30 16:30:27 +0000687 } else if (Platform == TvOS) {
688 if (!Driver::GetReleaseVersion(TvOSVersion->getValue(), Major, Minor,
689 Micro, HadExtra) || HadExtra ||
Bob Wilson4cf27c42016-07-18 20:29:14 +0000690 Major >= 100 || Minor >= 100 || Micro >= 100)
Tim Northover6f3ff222015-10-30 16:30:27 +0000691 getDriver().Diag(diag::err_drv_invalid_version_number)
692 << TvOSVersion->getAsString(Args);
693 } else if (Platform == WatchOS) {
694 if (!Driver::GetReleaseVersion(WatchOSVersion->getValue(), Major, Minor,
695 Micro, HadExtra) || HadExtra ||
696 Major >= 10 || Minor >= 100 || Micro >= 100)
697 getDriver().Diag(diag::err_drv_invalid_version_number)
698 << WatchOSVersion->getAsString(Args);
Tim Northover157d9112014-01-16 08:48:16 +0000699 } else
700 llvm_unreachable("unknown kind of Darwin platform");
Daniel Dunbar9aaeb642011-04-30 04:15:58 +0000701
Bob Wilson7f294b52014-10-10 23:10:10 +0000702 // Recognize iOS targets with an x86 architecture as the iOS simulator.
Daniel Dunbarb1189432011-04-30 04:18:16 +0000703 if (iOSVersion && (getTriple().getArch() == llvm::Triple::x86 ||
704 getTriple().getArch() == llvm::Triple::x86_64))
Tim Northover9c7e0352013-12-12 11:55:52 +0000705 Platform = IPhoneOSSimulator;
Tim Northover6f3ff222015-10-30 16:30:27 +0000706 if (TvOSVersion && (getTriple().getArch() == llvm::Triple::x86 ||
707 getTriple().getArch() == llvm::Triple::x86_64))
708 Platform = TvOSSimulator;
709 if (WatchOSVersion && (getTriple().getArch() == llvm::Triple::x86 ||
710 getTriple().getArch() == llvm::Triple::x86_64))
711 Platform = WatchOSSimulator;
Daniel Dunbarb1189432011-04-30 04:18:16 +0000712
Tim Northover9c7e0352013-12-12 11:55:52 +0000713 setTarget(Platform, Major, Minor, Micro);
Chris Bienemane60e7c22016-04-29 22:28:34 +0000714
715 if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
716 StringRef SDK = getSDKName(A->getValue());
717 if (SDK.size() > 0) {
718 size_t StartVer = SDK.find_first_of("0123456789");
719 StringRef SDKName = SDK.slice(0, StartVer);
720 if (!SDKName.startswith(getPlatformFamily()))
721 getDriver().Diag(diag::warn_incompatible_sysroot)
722 << SDKName << getPlatformFamily();
723 }
724 }
Daniel Dunbarb2b8a912010-07-19 17:11:33 +0000725}
726
Daniel Dunbar3f7796f2010-09-17 01:20:05 +0000727void DarwinClang::AddCXXStdlibLibArgs(const ArgList &Args,
Daniel Dunbar8fa86b12010-09-17 01:16:06 +0000728 ArgStringList &CmdArgs) const {
729 CXXStdlibType Type = GetCXXStdlibType(Args);
730
731 switch (Type) {
732 case ToolChain::CST_Libcxx:
733 CmdArgs.push_back("-lc++");
734 break;
735
Hans Wennborgdcfba332015-10-06 23:40:43 +0000736 case ToolChain::CST_Libstdcxx:
Daniel Dunbar8fa86b12010-09-17 01:16:06 +0000737 // Unfortunately, -lstdc++ doesn't always exist in the standard search path;
738 // it was previously found in the gcc lib dir. However, for all the Darwin
739 // platforms we care about it was -lstdc++.6, so we search for that
740 // explicitly if we can't see an obvious -lstdc++ candidate.
741
742 // Check in the sysroot first.
743 if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
Rafael Espindola358256c2013-06-26 02:13:00 +0000744 SmallString<128> P(A->getValue());
Benjamin Kramer17381a02013-06-28 16:25:46 +0000745 llvm::sys::path::append(P, "usr", "lib", "libstdc++.dylib");
Daniel Dunbar8fa86b12010-09-17 01:16:06 +0000746
Benjamin Kramerd45b2052015-10-07 15:48:01 +0000747 if (!getVFS().exists(P)) {
Rafael Espindola358256c2013-06-26 02:13:00 +0000748 llvm::sys::path::remove_filename(P);
749 llvm::sys::path::append(P, "libstdc++.6.dylib");
Benjamin Kramerd45b2052015-10-07 15:48:01 +0000750 if (getVFS().exists(P)) {
Yaron Keren92e1b622015-03-18 10:17:07 +0000751 CmdArgs.push_back(Args.MakeArgString(P));
Daniel Dunbar8fa86b12010-09-17 01:16:06 +0000752 return;
753 }
754 }
755 }
756
757 // Otherwise, look in the root.
Bob Wilson1a9ad0f2011-11-11 07:47:04 +0000758 // FIXME: This should be removed someday when we don't have to care about
759 // 10.6 and earlier, where /usr/lib/libstdc++.dylib does not exist.
Benjamin Kramerd45b2052015-10-07 15:48:01 +0000760 if (!getVFS().exists("/usr/lib/libstdc++.dylib") &&
761 getVFS().exists("/usr/lib/libstdc++.6.dylib")) {
Daniel Dunbar8fa86b12010-09-17 01:16:06 +0000762 CmdArgs.push_back("/usr/lib/libstdc++.6.dylib");
763 return;
764 }
765
766 // Otherwise, let the linker search.
767 CmdArgs.push_back("-lstdc++");
768 break;
769 }
Daniel Dunbar8fa86b12010-09-17 01:16:06 +0000770}
771
Shantonu Senafeb03b2010-09-17 18:39:08 +0000772void DarwinClang::AddCCKextLibArgs(const ArgList &Args,
773 ArgStringList &CmdArgs) const {
Shantonu Senafeb03b2010-09-17 18:39:08 +0000774 // For Darwin platforms, use the compiler-rt-based support library
775 // instead of the gcc-provided one (which is also incidentally
776 // only present in the gcc lib dir, which makes it hard to find).
777
Rafael Espindola358256c2013-06-26 02:13:00 +0000778 SmallString<128> P(getDriver().ResourceDir);
Benjamin Kramer17381a02013-06-28 16:25:46 +0000779 llvm::sys::path::append(P, "lib", "darwin");
Daniel Dunbarbd847cc2012-10-15 22:23:53 +0000780
781 // Use the newer cc_kext for iOS ARM after 6.0.
Tim Northover6f3ff222015-10-30 16:30:27 +0000782 if (isTargetWatchOS()) {
783 llvm::sys::path::append(P, "libclang_rt.cc_kext_watchos.a");
784 } else if (isTargetTvOS()) {
785 llvm::sys::path::append(P, "libclang_rt.cc_kext_tvos.a");
786 } else if (isTargetIPhoneOS()) {
Chris Bieneman25bc0de2015-09-23 22:52:35 +0000787 llvm::sys::path::append(P, "libclang_rt.cc_kext_ios.a");
Daniel Dunbarbd847cc2012-10-15 22:23:53 +0000788 } else {
Chris Bieneman25bc0de2015-09-23 22:52:35 +0000789 llvm::sys::path::append(P, "libclang_rt.cc_kext.a");
Daniel Dunbarbd847cc2012-10-15 22:23:53 +0000790 }
NAKAMURA Takumi8b73b3e2011-06-03 03:49:51 +0000791
Shantonu Senafeb03b2010-09-17 18:39:08 +0000792 // For now, allow missing resource libraries to support developers who may
793 // not have compiler-rt checked out or integrated into their build.
Benjamin Kramerd45b2052015-10-07 15:48:01 +0000794 if (getVFS().exists(P))
Yaron Keren92e1b622015-03-18 10:17:07 +0000795 CmdArgs.push_back(Args.MakeArgString(P));
Shantonu Senafeb03b2010-09-17 18:39:08 +0000796}
797
Tim Northover157d9112014-01-16 08:48:16 +0000798DerivedArgList *MachO::TranslateArgs(const DerivedArgList &Args,
799 const char *BoundArch) const {
Daniel Dunbarb2b8a912010-07-19 17:11:33 +0000800 DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
801 const OptTable &Opts = getDriver().getOpts();
802
803 // FIXME: We really want to get out of the tool chain level argument
804 // translation business, as it makes the driver functionality much
805 // more opaque. For now, we follow gcc closely solely for the
806 // purpose of easily achieving feature parity & testability. Once we
807 // have something that works, we should reevaluate each translation
808 // and try to push it down into tool specific logic.
Daniel Dunbar3b8e50d2010-01-27 00:56:25 +0000809
Simon Atanasyan6f657c42014-05-08 19:32:46 +0000810 for (Arg *A : Args) {
Daniel Dunbaraabb0b12009-03-25 06:12:34 +0000811 if (A->getOption().matches(options::OPT_Xarch__)) {
Daniel Dunbar471c4f82011-06-21 00:20:17 +0000812 // Skip this argument unless the architecture matches either the toolchain
813 // triple arch, or the arch being bound.
Rafael Espindola35ca7d92012-10-07 04:44:33 +0000814 llvm::Triple::ArchType XarchArch =
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000815 tools::darwin::getArchTypeForMachOArchName(A->getValue(0));
816 if (!(XarchArch == getArch() ||
817 (BoundArch &&
818 XarchArch ==
819 tools::darwin::getArchTypeForMachOArchName(BoundArch))))
Daniel Dunbaraabb0b12009-03-25 06:12:34 +0000820 continue;
821
Daniel Dunbar1094bb12011-02-19 05:33:51 +0000822 Arg *OriginalArg = A;
Richard Smithbd55daf2012-11-01 04:30:05 +0000823 unsigned Index = Args.getBaseArgs().MakeIndex(A->getValue(1));
Daniel Dunbar3f1a1ff2010-06-14 21:23:08 +0000824 unsigned Prev = Index;
Nico Webera04d5f82014-05-11 17:27:13 +0000825 std::unique_ptr<Arg> XarchArg(Opts.ParseOneArg(Args, Index));
Mike Stump11289f42009-09-09 15:08:12 +0000826
Daniel Dunbaraabb0b12009-03-25 06:12:34 +0000827 // If the argument parsing failed or more than one argument was
828 // consumed, the -Xarch_ argument's parameter tried to consume
829 // extra arguments. Emit an error and ignore.
830 //
831 // We also want to disallow any options which would alter the
832 // driver behavior; that isn't going to work in our model. We
833 // use isDriverOption() as an approximation, although things
834 // like -O4 are going to slip through.
Daniel Dunbar5a784c82011-04-21 17:41:34 +0000835 if (!XarchArg || Index > Prev + 1) {
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000836 getDriver().Diag(diag::err_drv_invalid_Xarch_argument_with_args)
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000837 << A->getAsString(Args);
Daniel Dunbar6914a982011-04-21 17:32:21 +0000838 continue;
Michael J. Spencer66e2b202012-10-19 22:37:06 +0000839 } else if (XarchArg->getOption().hasFlag(options::DriverOption)) {
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000840 getDriver().Diag(diag::err_drv_invalid_Xarch_argument_isdriver)
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000841 << A->getAsString(Args);
Daniel Dunbaraabb0b12009-03-25 06:12:34 +0000842 continue;
843 }
844
Daniel Dunbar53b406f2009-03-29 22:29:05 +0000845 XarchArg->setBaseArg(A);
Daniel Dunbar3f1a1ff2010-06-14 21:23:08 +0000846
Nico Webera04d5f82014-05-11 17:27:13 +0000847 A = XarchArg.release();
Daniel Dunbar3f1a1ff2010-06-14 21:23:08 +0000848 DAL->AddSynthesizedArg(A);
Daniel Dunbar1094bb12011-02-19 05:33:51 +0000849
850 // Linker input arguments require custom handling. The problem is that we
851 // have already constructed the phase actions, so we can not treat them as
852 // "input arguments".
Michael J. Spencer66e2b202012-10-19 22:37:06 +0000853 if (A->getOption().hasFlag(options::LinkerInput)) {
Daniel Dunbar1094bb12011-02-19 05:33:51 +0000854 // Convert the argument into individual Zlinker_input_args.
Douglas Katzman6bbffc42015-06-25 18:51:37 +0000855 for (const char *Value : A->getValues()) {
856 DAL->AddSeparateArg(
857 OriginalArg, Opts.getOption(options::OPT_Zlinker_input), Value);
Daniel Dunbar1094bb12011-02-19 05:33:51 +0000858 }
859 continue;
860 }
Mike Stump11289f42009-09-09 15:08:12 +0000861 }
Daniel Dunbaraabb0b12009-03-25 06:12:34 +0000862
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000863 // Sob. These is strictly gcc compatible for the time being. Apple
864 // gcc translates options twice, which means that self-expanding
865 // options add duplicates.
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000866 switch ((options::ID)A->getOption().getID()) {
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000867 default:
868 DAL->append(A);
869 break;
870
871 case options::OPT_mkernel:
872 case options::OPT_fapple_kext:
873 DAL->append(A);
Daniel Dunbar2d6e9ee2010-06-14 20:20:41 +0000874 DAL->AddFlagArg(A, Opts.getOption(options::OPT_static));
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000875 break;
Mike Stump11289f42009-09-09 15:08:12 +0000876
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000877 case options::OPT_dependency_file:
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000878 DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue());
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000879 break;
880
881 case options::OPT_gfull:
Daniel Dunbar2d6e9ee2010-06-14 20:20:41 +0000882 DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag));
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000883 DAL->AddFlagArg(
884 A, Opts.getOption(options::OPT_fno_eliminate_unused_debug_symbols));
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000885 break;
886
887 case options::OPT_gused:
Daniel Dunbar2d6e9ee2010-06-14 20:20:41 +0000888 DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag));
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000889 DAL->AddFlagArg(
890 A, Opts.getOption(options::OPT_feliminate_unused_debug_symbols));
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000891 break;
892
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000893 case options::OPT_shared:
Daniel Dunbar2d6e9ee2010-06-14 20:20:41 +0000894 DAL->AddFlagArg(A, Opts.getOption(options::OPT_dynamiclib));
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000895 break;
896
897 case options::OPT_fconstant_cfstrings:
Daniel Dunbar2d6e9ee2010-06-14 20:20:41 +0000898 DAL->AddFlagArg(A, Opts.getOption(options::OPT_mconstant_cfstrings));
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000899 break;
900
901 case options::OPT_fno_constant_cfstrings:
Daniel Dunbar2d6e9ee2010-06-14 20:20:41 +0000902 DAL->AddFlagArg(A, Opts.getOption(options::OPT_mno_constant_cfstrings));
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000903 break;
904
905 case options::OPT_Wnonportable_cfstrings:
Daniel Dunbar2d6e9ee2010-06-14 20:20:41 +0000906 DAL->AddFlagArg(A,
907 Opts.getOption(options::OPT_mwarn_nonportable_cfstrings));
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000908 break;
909
910 case options::OPT_Wno_nonportable_cfstrings:
Douglas Katzmana67e50c2015-06-26 15:47:46 +0000911 DAL->AddFlagArg(
912 A, Opts.getOption(options::OPT_mno_warn_nonportable_cfstrings));
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000913 break;
914
915 case options::OPT_fpascal_strings:
Daniel Dunbar2d6e9ee2010-06-14 20:20:41 +0000916 DAL->AddFlagArg(A, Opts.getOption(options::OPT_mpascal_strings));
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000917 break;
918
919 case options::OPT_fno_pascal_strings:
Daniel Dunbar2d6e9ee2010-06-14 20:20:41 +0000920 DAL->AddFlagArg(A, Opts.getOption(options::OPT_mno_pascal_strings));
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000921 break;
922 }
Daniel Dunbaraabb0b12009-03-25 06:12:34 +0000923 }
924
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000925 if (getTriple().getArch() == llvm::Triple::x86 ||
926 getTriple().getArch() == llvm::Triple::x86_64)
Daniel Dunbarfffd1812009-11-19 04:00:53 +0000927 if (!Args.hasArgNoClaim(options::OPT_mtune_EQ))
Craig Topper92fc2df2014-05-17 16:56:41 +0000928 DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_mtune_EQ),
929 "core2");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000930
931 // Add the arch options based on the particular spelling of -arch, to match
Chad Rosier7c5d9082012-04-27 14:58:16 +0000932 // how the driver driver works.
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000933 if (BoundArch) {
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000934 StringRef Name = BoundArch;
Michael J. Spencerfc790902012-10-19 22:36:40 +0000935 const Option MCpu = Opts.getOption(options::OPT_mcpu_EQ);
936 const Option MArch = Opts.getOption(options::OPT_march_EQ);
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000937
938 // This code must be kept in sync with LLVM's getArchTypeForDarwinArch,
939 // which defines the list of which architectures we accept.
940 if (Name == "ppc")
941 ;
942 else if (Name == "ppc601")
Craig Topper92fc2df2014-05-17 16:56:41 +0000943 DAL->AddJoinedArg(nullptr, MCpu, "601");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000944 else if (Name == "ppc603")
Craig Topper92fc2df2014-05-17 16:56:41 +0000945 DAL->AddJoinedArg(nullptr, MCpu, "603");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000946 else if (Name == "ppc604")
Craig Topper92fc2df2014-05-17 16:56:41 +0000947 DAL->AddJoinedArg(nullptr, MCpu, "604");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000948 else if (Name == "ppc604e")
Craig Topper92fc2df2014-05-17 16:56:41 +0000949 DAL->AddJoinedArg(nullptr, MCpu, "604e");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000950 else if (Name == "ppc750")
Craig Topper92fc2df2014-05-17 16:56:41 +0000951 DAL->AddJoinedArg(nullptr, MCpu, "750");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000952 else if (Name == "ppc7400")
Craig Topper92fc2df2014-05-17 16:56:41 +0000953 DAL->AddJoinedArg(nullptr, MCpu, "7400");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000954 else if (Name == "ppc7450")
Craig Topper92fc2df2014-05-17 16:56:41 +0000955 DAL->AddJoinedArg(nullptr, MCpu, "7450");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000956 else if (Name == "ppc970")
Craig Topper92fc2df2014-05-17 16:56:41 +0000957 DAL->AddJoinedArg(nullptr, MCpu, "970");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000958
Bill Schmidt778d3872013-07-26 01:36:11 +0000959 else if (Name == "ppc64" || Name == "ppc64le")
Craig Topper92fc2df2014-05-17 16:56:41 +0000960 DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64));
Daniel Dunbar0af75a12009-03-25 06:58:31 +0000961
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000962 else if (Name == "i386")
963 ;
964 else if (Name == "i486")
Craig Topper92fc2df2014-05-17 16:56:41 +0000965 DAL->AddJoinedArg(nullptr, MArch, "i486");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000966 else if (Name == "i586")
Craig Topper92fc2df2014-05-17 16:56:41 +0000967 DAL->AddJoinedArg(nullptr, MArch, "i586");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000968 else if (Name == "i686")
Craig Topper92fc2df2014-05-17 16:56:41 +0000969 DAL->AddJoinedArg(nullptr, MArch, "i686");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000970 else if (Name == "pentium")
Craig Topper92fc2df2014-05-17 16:56:41 +0000971 DAL->AddJoinedArg(nullptr, MArch, "pentium");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000972 else if (Name == "pentium2")
Craig Topper92fc2df2014-05-17 16:56:41 +0000973 DAL->AddJoinedArg(nullptr, MArch, "pentium2");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000974 else if (Name == "pentpro")
Craig Topper92fc2df2014-05-17 16:56:41 +0000975 DAL->AddJoinedArg(nullptr, MArch, "pentiumpro");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000976 else if (Name == "pentIIm3")
Craig Topper92fc2df2014-05-17 16:56:41 +0000977 DAL->AddJoinedArg(nullptr, MArch, "pentium2");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000978
979 else if (Name == "x86_64")
Craig Topper92fc2df2014-05-17 16:56:41 +0000980 DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64));
Jim Grosbach82eee262013-11-16 00:53:35 +0000981 else if (Name == "x86_64h") {
Craig Topper92fc2df2014-05-17 16:56:41 +0000982 DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64));
983 DAL->AddJoinedArg(nullptr, MArch, "x86_64h");
Jim Grosbach82eee262013-11-16 00:53:35 +0000984 }
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000985
986 else if (Name == "arm")
Craig Topper92fc2df2014-05-17 16:56:41 +0000987 DAL->AddJoinedArg(nullptr, MArch, "armv4t");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000988 else if (Name == "armv4t")
Craig Topper92fc2df2014-05-17 16:56:41 +0000989 DAL->AddJoinedArg(nullptr, MArch, "armv4t");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000990 else if (Name == "armv5")
Craig Topper92fc2df2014-05-17 16:56:41 +0000991 DAL->AddJoinedArg(nullptr, MArch, "armv5tej");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000992 else if (Name == "xscale")
Craig Topper92fc2df2014-05-17 16:56:41 +0000993 DAL->AddJoinedArg(nullptr, MArch, "xscale");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000994 else if (Name == "armv6")
Craig Topper92fc2df2014-05-17 16:56:41 +0000995 DAL->AddJoinedArg(nullptr, MArch, "armv6k");
Bob Wilson743bf672013-03-04 22:37:49 +0000996 else if (Name == "armv6m")
Craig Topper92fc2df2014-05-17 16:56:41 +0000997 DAL->AddJoinedArg(nullptr, MArch, "armv6m");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +0000998 else if (Name == "armv7")
Craig Topper92fc2df2014-05-17 16:56:41 +0000999 DAL->AddJoinedArg(nullptr, MArch, "armv7a");
Bob Wilson743bf672013-03-04 22:37:49 +00001000 else if (Name == "armv7em")
Craig Topper92fc2df2014-05-17 16:56:41 +00001001 DAL->AddJoinedArg(nullptr, MArch, "armv7em");
Bob Wilsond7cf1042012-09-29 23:52:50 +00001002 else if (Name == "armv7k")
Craig Topper92fc2df2014-05-17 16:56:41 +00001003 DAL->AddJoinedArg(nullptr, MArch, "armv7k");
Bob Wilson743bf672013-03-04 22:37:49 +00001004 else if (Name == "armv7m")
Craig Topper92fc2df2014-05-17 16:56:41 +00001005 DAL->AddJoinedArg(nullptr, MArch, "armv7m");
Bob Wilsond7cf1042012-09-29 23:52:50 +00001006 else if (Name == "armv7s")
Craig Topper92fc2df2014-05-17 16:56:41 +00001007 DAL->AddJoinedArg(nullptr, MArch, "armv7s");
Daniel Dunbar3c7b9ca2009-09-09 22:33:15 +00001008 }
Daniel Dunbar0af75a12009-03-25 06:58:31 +00001009
Tim Northover157d9112014-01-16 08:48:16 +00001010 return DAL;
1011}
1012
Vedant Kumar5fb00e42016-07-27 23:01:55 +00001013void MachO::AddLinkRuntimeLibArgs(const ArgList &Args,
Douglas Katzmanf08fadf2015-06-04 14:40:44 +00001014 ArgStringList &CmdArgs) const {
Tim Northover157d9112014-01-16 08:48:16 +00001015 // Embedded targets are simple at the moment, not supporting sanitizers and
1016 // with different libraries for each member of the product { static, PIC } x
1017 // { hard-float, soft-float }
1018 llvm::SmallString<32> CompilerRT = StringRef("libclang_rt.");
Vedant Kumar5fb00e42016-07-27 23:01:55 +00001019 CompilerRT +=
1020 (tools::arm::getARMFloatABI(*this, Args) == tools::arm::FloatABI::Hard)
1021 ? "hard"
1022 : "soft";
Tim Northover157d9112014-01-16 08:48:16 +00001023 CompilerRT += Args.hasArg(options::OPT_fPIC) ? "_pic.a" : "_static.a";
1024
1025 AddLinkRuntimeLib(Args, CmdArgs, CompilerRT, false, true);
1026}
1027
Tim Northover157d9112014-01-16 08:48:16 +00001028DerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args,
1029 const char *BoundArch) const {
1030 // First get the generic Apple args, before moving onto Darwin-specific ones.
1031 DerivedArgList *DAL = MachO::TranslateArgs(Args, BoundArch);
Tim Northoverb534ce42016-02-12 22:30:42 +00001032 const OptTable &Opts = getDriver().getOpts();
Tim Northover157d9112014-01-16 08:48:16 +00001033
Bob Wilsonf8cf1612014-02-21 00:20:07 +00001034 // If no architecture is bound, none of the translations here are relevant.
1035 if (!BoundArch)
1036 return DAL;
1037
Daniel Dunbar354e96d2010-07-19 17:11:36 +00001038 // Add an explicit version min argument for the deployment target. We do this
1039 // after argument translation because -Xarch_ arguments may add a version min
1040 // argument.
Bob Wilsonf8cf1612014-02-21 00:20:07 +00001041 AddDeploymentTarget(*DAL);
Daniel Dunbar354e96d2010-07-19 17:11:36 +00001042
Daniel Dunbarbd847cc2012-10-15 22:23:53 +00001043 // For iOS 6, undo the translation to add -static for -mkernel/-fapple-kext.
1044 // FIXME: It would be far better to avoid inserting those -static arguments,
1045 // but we can't check the deployment target in the translation code until
1046 // it is set here.
Tim Northover6f3ff222015-10-30 16:30:27 +00001047 if (isTargetWatchOSBased() ||
1048 (isTargetIOSBased() && !isIPhoneOSVersionLT(6, 0))) {
1049 for (ArgList::iterator it = DAL->begin(), ie = DAL->end(); it != ie; ) {
Daniel Dunbarbd847cc2012-10-15 22:23:53 +00001050 Arg *A = *it;
1051 ++it;
1052 if (A->getOption().getID() != options::OPT_mkernel &&
1053 A->getOption().getID() != options::OPT_fapple_kext)
1054 continue;
1055 assert(it != ie && "unexpected argument translation");
1056 A = *it;
1057 assert(A->getOption().getID() == options::OPT_static &&
1058 "missing expected -static argument");
1059 it = DAL->getArgs().erase(it);
1060 }
1061 }
1062
Tim Northoverb534ce42016-02-12 22:30:42 +00001063 if (!Args.getLastArg(options::OPT_stdlib_EQ) &&
Tim Northover3a098c12016-02-15 16:38:10 +00001064 GetCXXStdlibType(Args) == ToolChain::CST_Libcxx)
Tim Northoverb534ce42016-02-12 22:30:42 +00001065 DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_stdlib_EQ),
1066 "libc++");
1067
Bob Wilson102be442011-10-07 17:54:41 +00001068 // Validate the C++ standard library choice.
1069 CXXStdlibType Type = GetCXXStdlibType(*DAL);
1070 if (Type == ToolChain::CST_Libcxx) {
John McCall5fb5df92012-06-20 06:18:46 +00001071 // Check whether the target provides libc++.
1072 StringRef where;
1073
Alp Tokerf6a24ce2013-12-05 16:25:25 +00001074 // Complain about targeting iOS < 5.0 in any way.
Tim Northover9c7e0352013-12-12 11:55:52 +00001075 if (isTargetIOSBased() && isIPhoneOSVersionLT(5, 0))
Bob Wilson5ad5a952012-11-09 01:59:30 +00001076 where = "iOS 5.0";
John McCall5fb5df92012-06-20 06:18:46 +00001077
1078 if (where != StringRef()) {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00001079 getDriver().Diag(clang::diag::err_drv_invalid_libcxx_deployment) << where;
Bob Wilson102be442011-10-07 17:54:41 +00001080 }
1081 }
1082
Daniel Dunbaraabb0b12009-03-25 06:12:34 +00001083 return DAL;
Mike Stump11289f42009-09-09 15:08:12 +00001084}
Daniel Dunbar03e0a4f2009-03-20 00:57:52 +00001085
Tim Northover157d9112014-01-16 08:48:16 +00001086bool MachO::IsUnwindTablesDefault() const {
Rafael Espindolae8bd4e52012-10-07 03:23:40 +00001087 return getArch() == llvm::Triple::x86_64;
Daniel Dunbar03e0a4f2009-03-20 00:57:52 +00001088}
1089
Tim Northover157d9112014-01-16 08:48:16 +00001090bool MachO::UseDwarfDebugFlags() const {
Daniel Dunbar24c7f5e2009-12-18 02:43:17 +00001091 if (const char *S = ::getenv("RC_DEBUG_OPTIONS"))
1092 return S[0] != '\0';
1093 return false;
1094}
1095
Tim Northovere931f9f2015-10-30 16:30:41 +00001096bool Darwin::UseSjLjExceptions(const ArgList &Args) const {
Daniel Dunbar3241d402010-02-10 18:49:11 +00001097 // Darwin uses SjLj exceptions on ARM.
Tim Northovere931f9f2015-10-30 16:30:41 +00001098 if (getTriple().getArch() != llvm::Triple::arm &&
1099 getTriple().getArch() != llvm::Triple::thumb)
1100 return false;
1101
Tim Northoverc741b042015-11-17 18:27:27 +00001102 // Only watchOS uses the new DWARF/Compact unwinding method.
Tim Northoverd88ecb32016-01-27 19:32:40 +00001103 llvm::Triple Triple(ComputeLLVMTriple(Args));
Tim Northover4c9ac7d2016-01-27 22:14:02 +00001104 return !Triple.isWatchABI();
Daniel Dunbar3241d402010-02-10 18:49:11 +00001105}
1106
Steven Wu574b0f22016-03-01 01:07:58 +00001107bool Darwin::SupportsEmbeddedBitcode() const {
1108 assert(TargetInitialized && "Target not initialized!");
1109 if (isTargetIPhoneOS() && isIPhoneOSVersionLT(6, 0))
1110 return false;
1111 return true;
1112}
1113
Douglas Katzmana67e50c2015-06-26 15:47:46 +00001114bool MachO::isPICDefault() const { return true; }
Daniel Dunbar03e0a4f2009-03-20 00:57:52 +00001115
Douglas Katzmana67e50c2015-06-26 15:47:46 +00001116bool MachO::isPIEDefault() const { return false; }
Peter Collingbourne54d770c2013-04-09 04:35:11 +00001117
Tim Northover157d9112014-01-16 08:48:16 +00001118bool MachO::isPICDefaultForced() const {
Tim Northovera2ee4332014-03-29 15:09:45 +00001119 return (getArch() == llvm::Triple::x86_64 ||
Tim Northover573cbee2014-05-24 12:52:07 +00001120 getArch() == llvm::Triple::aarch64);
Daniel Dunbar03e0a4f2009-03-20 00:57:52 +00001121}
1122
Tim Northover157d9112014-01-16 08:48:16 +00001123bool MachO::SupportsProfiling() const {
Daniel Dunbar733b0f82011-03-01 18:49:30 +00001124 // Profiling instrumentation is only supported on x86.
Rafael Espindola35ca7d92012-10-07 04:44:33 +00001125 return getArch() == llvm::Triple::x86 || getArch() == llvm::Triple::x86_64;
Daniel Dunbar733b0f82011-03-01 18:49:30 +00001126}
1127
Douglas Katzmanf08fadf2015-06-04 14:40:44 +00001128void Darwin::addMinVersionArgs(const ArgList &Args,
1129 ArgStringList &CmdArgs) const {
Tim Northover157d9112014-01-16 08:48:16 +00001130 VersionTuple TargetVersion = getTargetVersion();
1131
Tim Northover6f3ff222015-10-30 16:30:27 +00001132 if (isTargetWatchOS())
1133 CmdArgs.push_back("-watchos_version_min");
1134 else if (isTargetWatchOSSimulator())
1135 CmdArgs.push_back("-watchos_simulator_version_min");
1136 else if (isTargetTvOS())
1137 CmdArgs.push_back("-tvos_version_min");
1138 else if (isTargetTvOSSimulator())
1139 CmdArgs.push_back("-tvos_simulator_version_min");
1140 else if (isTargetIOSSimulator())
Tim Northover157d9112014-01-16 08:48:16 +00001141 CmdArgs.push_back("-ios_simulator_version_min");
Bob Wilson5cfc55e2014-02-01 21:06:21 +00001142 else if (isTargetIOSBased())
Tim Northover157d9112014-01-16 08:48:16 +00001143 CmdArgs.push_back("-iphoneos_version_min");
1144 else {
1145 assert(isTargetMacOS() && "unexpected target");
1146 CmdArgs.push_back("-macosx_version_min");
1147 }
1148
1149 CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString()));
1150}
1151
Douglas Katzmanf08fadf2015-06-04 14:40:44 +00001152void Darwin::addStartObjectFileArgs(const ArgList &Args,
1153 ArgStringList &CmdArgs) const {
Tim Northover157d9112014-01-16 08:48:16 +00001154 // Derived from startfile spec.
1155 if (Args.hasArg(options::OPT_dynamiclib)) {
1156 // Derived from darwin_dylib1 spec.
Tim Northover6f3ff222015-10-30 16:30:27 +00001157 if (isTargetWatchOSBased()) {
1158 ; // watchOS does not need dylib1.o.
1159 } else if (isTargetIOSSimulator()) {
Bob Wilson74b6cd12014-01-21 00:17:10 +00001160 ; // iOS simulator does not need dylib1.o.
Tim Northover157d9112014-01-16 08:48:16 +00001161 } else if (isTargetIPhoneOS()) {
1162 if (isIPhoneOSVersionLT(3, 1))
1163 CmdArgs.push_back("-ldylib1.o");
1164 } else {
1165 if (isMacosxVersionLT(10, 5))
1166 CmdArgs.push_back("-ldylib1.o");
1167 else if (isMacosxVersionLT(10, 6))
1168 CmdArgs.push_back("-ldylib1.10.5.o");
1169 }
1170 } else {
1171 if (Args.hasArg(options::OPT_bundle)) {
1172 if (!Args.hasArg(options::OPT_static)) {
1173 // Derived from darwin_bundle1 spec.
Tim Northover6f3ff222015-10-30 16:30:27 +00001174 if (isTargetWatchOSBased()) {
1175 ; // watchOS does not need bundle1.o.
1176 } else if (isTargetIOSSimulator()) {
Bob Wilson74b6cd12014-01-21 00:17:10 +00001177 ; // iOS simulator does not need bundle1.o.
Tim Northover157d9112014-01-16 08:48:16 +00001178 } else if (isTargetIPhoneOS()) {
1179 if (isIPhoneOSVersionLT(3, 1))
1180 CmdArgs.push_back("-lbundle1.o");
1181 } else {
1182 if (isMacosxVersionLT(10, 6))
1183 CmdArgs.push_back("-lbundle1.o");
1184 }
1185 }
1186 } else {
1187 if (Args.hasArg(options::OPT_pg) && SupportsProfiling()) {
1188 if (Args.hasArg(options::OPT_static) ||
1189 Args.hasArg(options::OPT_object) ||
1190 Args.hasArg(options::OPT_preload)) {
1191 CmdArgs.push_back("-lgcrt0.o");
1192 } else {
1193 CmdArgs.push_back("-lgcrt1.o");
1194
1195 // darwin_crt2 spec is empty.
1196 }
1197 // By default on OS X 10.8 and later, we don't link with a crt1.o
1198 // file and the linker knows to use _main as the entry point. But,
1199 // when compiling with -pg, we need to link with the gcrt1.o file,
1200 // so pass the -no_new_main option to tell the linker to use the
1201 // "start" symbol as the entry point.
1202 if (isTargetMacOS() && !isMacosxVersionLT(10, 8))
1203 CmdArgs.push_back("-no_new_main");
1204 } else {
1205 if (Args.hasArg(options::OPT_static) ||
1206 Args.hasArg(options::OPT_object) ||
1207 Args.hasArg(options::OPT_preload)) {
1208 CmdArgs.push_back("-lcrt0.o");
1209 } else {
1210 // Derived from darwin_crt1 spec.
Tim Northover6f3ff222015-10-30 16:30:27 +00001211 if (isTargetWatchOSBased()) {
1212 ; // watchOS does not need crt1.o.
1213 } else if (isTargetIOSSimulator()) {
Bob Wilson74b6cd12014-01-21 00:17:10 +00001214 ; // iOS simulator does not need crt1.o.
Tim Northover157d9112014-01-16 08:48:16 +00001215 } else if (isTargetIPhoneOS()) {
Tim Northover40956e62014-07-23 12:32:58 +00001216 if (getArch() == llvm::Triple::aarch64)
Tim Northovera2ee4332014-03-29 15:09:45 +00001217 ; // iOS does not need any crt1 files for arm64
1218 else if (isIPhoneOSVersionLT(3, 1))
Tim Northover157d9112014-01-16 08:48:16 +00001219 CmdArgs.push_back("-lcrt1.o");
1220 else if (isIPhoneOSVersionLT(6, 0))
1221 CmdArgs.push_back("-lcrt1.3.1.o");
1222 } else {
1223 if (isMacosxVersionLT(10, 5))
1224 CmdArgs.push_back("-lcrt1.o");
1225 else if (isMacosxVersionLT(10, 6))
1226 CmdArgs.push_back("-lcrt1.10.5.o");
1227 else if (isMacosxVersionLT(10, 8))
1228 CmdArgs.push_back("-lcrt1.10.6.o");
1229
1230 // darwin_crt2 spec is empty.
1231 }
1232 }
1233 }
1234 }
1235 }
1236
1237 if (!isTargetIPhoneOS() && Args.hasArg(options::OPT_shared_libgcc) &&
Tim Northover6f3ff222015-10-30 16:30:27 +00001238 !isTargetWatchOS() &&
Tim Northover157d9112014-01-16 08:48:16 +00001239 isMacosxVersionLT(10, 5)) {
1240 const char *Str = Args.MakeArgString(GetFilePath("crt3.o"));
1241 CmdArgs.push_back(Str);
1242 }
1243}
1244
Douglas Katzmana67e50c2015-06-26 15:47:46 +00001245bool Darwin::SupportsObjCGC() const { return isTargetMacOS(); }
Daniel Dunbar16334e12010-04-10 16:20:23 +00001246
John McCall3deb1ad2012-08-21 02:47:43 +00001247void Darwin::CheckObjCARC() const {
Tim Northover6f3ff222015-10-30 16:30:27 +00001248 if (isTargetIOSBased() || isTargetWatchOSBased() ||
1249 (isTargetMacOS() && !isMacosxVersionLT(10, 6)))
John McCall3deb1ad2012-08-21 02:47:43 +00001250 return;
John McCall93207072012-08-27 01:56:21 +00001251 getDriver().Diag(diag::err_arc_unsupported_on_toolchain);
Argyrios Kyrtzidis3dbeb552012-02-29 03:43:52 +00001252}
1253
Alexey Samsonov7f2a0d22015-06-19 21:36:47 +00001254SanitizerMask Darwin::getSupportedSanitizers() const {
Devin Coughlinfcfa38c2016-03-20 18:24:33 +00001255 const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64;
Alexey Samsonov7f2a0d22015-06-19 21:36:47 +00001256 SanitizerMask Res = ToolChain::getSupportedSanitizers();
Anna Zakse67b4022016-02-02 02:04:48 +00001257 Res |= SanitizerKind::Address;
Alexey Samsonov1d4cff22015-06-25 00:58:02 +00001258 if (isTargetMacOS()) {
1259 if (!isMacosxVersionLT(10, 9))
1260 Res |= SanitizerKind::Vptr;
Alexey Samsonov7f2a0d22015-06-19 21:36:47 +00001261 Res |= SanitizerKind::SafeStack;
Devin Coughlinfcfa38c2016-03-20 18:24:33 +00001262 if (IsX86_64)
1263 Res |= SanitizerKind::Thread;
1264 } else if (isTargetIOSSimulator() || isTargetTvOSSimulator()) {
1265 if (IsX86_64)
1266 Res |= SanitizerKind::Thread;
Alexey Samsonov1d4cff22015-06-25 00:58:02 +00001267 }
Alexey Samsonov7f2a0d22015-06-19 21:36:47 +00001268 return Res;
1269}
1270
Daniel Dunbar59e5e882009-03-20 00:20:03 +00001271/// Generic_GCC - A tool chain using the 'gcc' command to perform
1272/// all subcommands; this relies on gcc translating the majority of
1273/// command line options.
1274
Chandler Carruth4c90fba2011-11-06 23:39:34 +00001275/// \brief Parse a GCCVersion object out of a string of text.
1276///
1277/// This is the primary means of forming GCCVersion objects.
1278/*static*/
1279Generic_GCC::GCCVersion Linux::GCCVersion::Parse(StringRef VersionText) {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00001280 const GCCVersion BadVersion = {VersionText.str(), -1, -1, -1, "", "", ""};
Chandler Carruth4c90fba2011-11-06 23:39:34 +00001281 std::pair<StringRef, StringRef> First = VersionText.split('.');
1282 std::pair<StringRef, StringRef> Second = First.second.split('.');
1283
Douglas Katzmana67e50c2015-06-26 15:47:46 +00001284 GCCVersion GoodVersion = {VersionText.str(), -1, -1, -1, "", "", ""};
1285 if (First.first.getAsInteger(10, GoodVersion.Major) || GoodVersion.Major < 0)
Chandler Carruth4c90fba2011-11-06 23:39:34 +00001286 return BadVersion;
Chandler Carruth1f2b2f82013-08-26 08:59:53 +00001287 GoodVersion.MajorStr = First.first.str();
Bryan Chand346ae62016-06-17 16:47:14 +00001288 if (First.second.empty())
1289 return GoodVersion;
Douglas Katzmana67e50c2015-06-26 15:47:46 +00001290 if (Second.first.getAsInteger(10, GoodVersion.Minor) || GoodVersion.Minor < 0)
Chandler Carruth4c90fba2011-11-06 23:39:34 +00001291 return BadVersion;
Chandler Carruth1f2b2f82013-08-26 08:59:53 +00001292 GoodVersion.MinorStr = Second.first.str();
Chandler Carruth4c90fba2011-11-06 23:39:34 +00001293
1294 // First look for a number prefix and parse that if present. Otherwise just
1295 // stash the entire patch string in the suffix, and leave the number
1296 // unspecified. This covers versions strings such as:
Bryan Chand346ae62016-06-17 16:47:14 +00001297 // 5 (handled above)
Chandler Carruth4c90fba2011-11-06 23:39:34 +00001298 // 4.4
1299 // 4.4.0
1300 // 4.4.x
1301 // 4.4.2-rc4
1302 // 4.4.x-patched
1303 // And retains any patch number it finds.
1304 StringRef PatchText = GoodVersion.PatchSuffix = Second.second.str();
1305 if (!PatchText.empty()) {
Will Dietza38608b2013-01-10 22:20:02 +00001306 if (size_t EndNumber = PatchText.find_first_not_of("0123456789")) {
Chandler Carruth4c90fba2011-11-06 23:39:34 +00001307 // Try to parse the number and any suffix.
1308 if (PatchText.slice(0, EndNumber).getAsInteger(10, GoodVersion.Patch) ||
1309 GoodVersion.Patch < 0)
1310 return BadVersion;
Chandler Carruth1f2b2f82013-08-26 08:59:53 +00001311 GoodVersion.PatchSuffix = PatchText.substr(EndNumber);
Chandler Carruth4c90fba2011-11-06 23:39:34 +00001312 }
1313 }
1314
1315 return GoodVersion;
1316}
1317
1318/// \brief Less-than for GCCVersion, implementing a Strict Weak Ordering.
Benjamin Kramer604e8482013-08-09 17:17:48 +00001319bool Generic_GCC::GCCVersion::isOlderThan(int RHSMajor, int RHSMinor,
1320 int RHSPatch,
1321 StringRef RHSPatchSuffix) const {
1322 if (Major != RHSMajor)
1323 return Major < RHSMajor;
1324 if (Minor != RHSMinor)
1325 return Minor < RHSMinor;
1326 if (Patch != RHSPatch) {
Chandler Carruth5193dfc2012-12-29 12:01:08 +00001327 // Note that versions without a specified patch sort higher than those with
1328 // a patch.
Benjamin Kramer604e8482013-08-09 17:17:48 +00001329 if (RHSPatch == -1)
Chandler Carruth5193dfc2012-12-29 12:01:08 +00001330 return true;
1331 if (Patch == -1)
1332 return false;
Chandler Carruth4c90fba2011-11-06 23:39:34 +00001333
Chandler Carruth5193dfc2012-12-29 12:01:08 +00001334 // Otherwise just sort on the patch itself.
Benjamin Kramer604e8482013-08-09 17:17:48 +00001335 return Patch < RHSPatch;
Chandler Carruth5193dfc2012-12-29 12:01:08 +00001336 }
Benjamin Kramer604e8482013-08-09 17:17:48 +00001337 if (PatchSuffix != RHSPatchSuffix) {
Chandler Carruth5193dfc2012-12-29 12:01:08 +00001338 // Sort empty suffixes higher.
Benjamin Kramer604e8482013-08-09 17:17:48 +00001339 if (RHSPatchSuffix.empty())
Chandler Carruth5193dfc2012-12-29 12:01:08 +00001340 return true;
1341 if (PatchSuffix.empty())
Chandler Carruth19e8bea2012-12-29 13:00:47 +00001342 return false;
Chandler Carruth4c90fba2011-11-06 23:39:34 +00001343
Chandler Carruth5193dfc2012-12-29 12:01:08 +00001344 // Provide a lexicographic sort to make this a total ordering.
Benjamin Kramer604e8482013-08-09 17:17:48 +00001345 return PatchSuffix < RHSPatchSuffix;
Chandler Carruth5193dfc2012-12-29 12:01:08 +00001346 }
1347
1348 // The versions are equal.
Chandler Carruth4c90fba2011-11-06 23:39:34 +00001349 return false;
1350}
1351
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00001352static llvm::StringRef getGCCToolchainDir(const ArgList &Args) {
Rafael Espindola1af7c212012-02-19 01:38:32 +00001353 const Arg *A = Args.getLastArg(options::OPT_gcc_toolchain);
1354 if (A)
Richard Smithbd55daf2012-11-01 04:30:05 +00001355 return A->getValue();
Rafael Espindola1af7c212012-02-19 01:38:32 +00001356 return GCC_INSTALL_PREFIX;
1357}
1358
Roman Divacky326d9982013-12-06 18:32:18 +00001359/// \brief Initialize a GCCInstallationDetector from the driver.
Chandler Carruth4c90fba2011-11-06 23:39:34 +00001360///
1361/// This performs all of the autodetection and sets up the various paths.
Gabor Greif8a45d572012-04-17 11:16:26 +00001362/// Once constructed, a GCCInstallationDetector is essentially immutable.
Chandler Carruth866faab2012-01-25 07:21:38 +00001363///
1364/// FIXME: We shouldn't need an explicit TargetTriple parameter here, and
1365/// should instead pull the target out of the driver. This is currently
1366/// necessary because the driver doesn't store the final version of the target
1367/// triple.
Douglas Katzmana67e50c2015-06-26 15:47:46 +00001368void Generic_GCC::GCCInstallationDetector::init(
Benjamin Kramerd45b2052015-10-07 15:48:01 +00001369 const llvm::Triple &TargetTriple, const ArgList &Args,
Douglas Katzman8c39e6a2015-09-18 15:23:16 +00001370 ArrayRef<std::string> ExtraTripleAliases) {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00001371 llvm::Triple BiarchVariantTriple = TargetTriple.isArch32Bit()
1372 ? TargetTriple.get64BitArchVariant()
1373 : TargetTriple.get32BitArchVariant();
Chandler Carruth4c90fba2011-11-06 23:39:34 +00001374 // The library directories which may contain GCC installations.
Chandler Carruthb427c562013-06-22 11:35:51 +00001375 SmallVector<StringRef, 4> CandidateLibDirs, CandidateBiarchLibDirs;
Chandler Carruth4c90fba2011-11-06 23:39:34 +00001376 // The compatible GCC triples for this particular architecture.
Hans Wennborg90aa63f2014-08-11 18:09:28 +00001377 SmallVector<StringRef, 16> CandidateTripleAliases;
1378 SmallVector<StringRef, 16> CandidateBiarchTripleAliases;
Chandler Carruthb427c562013-06-22 11:35:51 +00001379 CollectLibDirsAndTriples(TargetTriple, BiarchVariantTriple, CandidateLibDirs,
1380 CandidateTripleAliases, CandidateBiarchLibDirs,
1381 CandidateBiarchTripleAliases);
Chandler Carruth4c90fba2011-11-06 23:39:34 +00001382
1383 // Compute the set of prefixes for our search.
1384 SmallVector<std::string, 8> Prefixes(D.PrefixDirs.begin(),
1385 D.PrefixDirs.end());
Rafael Espindolac29af942012-02-03 01:01:20 +00001386
Rafael Espindola1af7c212012-02-19 01:38:32 +00001387 StringRef GCCToolchainDir = getGCCToolchainDir(Args);
1388 if (GCCToolchainDir != "") {
1389 if (GCCToolchainDir.back() == '/')
1390 GCCToolchainDir = GCCToolchainDir.drop_back(); // remove the /
Rafael Espindolac29af942012-02-03 01:01:20 +00001391
Rafael Espindola1af7c212012-02-19 01:38:32 +00001392 Prefixes.push_back(GCCToolchainDir);
Rafael Espindolac29af942012-02-03 01:01:20 +00001393 } else {
Rafael Espindola0f4b04e2013-08-28 23:17:47 +00001394 // If we have a SysRoot, try that first.
1395 if (!D.SysRoot.empty()) {
1396 Prefixes.push_back(D.SysRoot);
1397 Prefixes.push_back(D.SysRoot + "/usr");
1398 }
1399
1400 // Then look for gcc installed alongside clang.
Rafael Espindolac29af942012-02-03 01:01:20 +00001401 Prefixes.push_back(D.InstalledDir + "/..");
Rafael Espindola0f4b04e2013-08-28 23:17:47 +00001402
Rafael Espindola2edca412016-05-09 13:03:10 +00001403 // Then look for distribution supplied gcc installations.
1404 if (D.SysRoot.empty()) {
1405 // Look for RHEL devtoolsets.
1406 Prefixes.push_back("/opt/rh/devtoolset-4/root/usr");
1407 Prefixes.push_back("/opt/rh/devtoolset-3/root/usr");
1408 Prefixes.push_back("/opt/rh/devtoolset-2/root/usr");
1409 Prefixes.push_back("/opt/rh/devtoolset-1.1/root/usr");
1410 Prefixes.push_back("/opt/rh/devtoolset-1.0/root/usr");
1411 // And finally in /usr.
Rafael Espindola0f4b04e2013-08-28 23:17:47 +00001412 Prefixes.push_back("/usr");
Rafael Espindola2edca412016-05-09 13:03:10 +00001413 }
Rafael Espindolac29af942012-02-03 01:01:20 +00001414 }
Chandler Carruth4c90fba2011-11-06 23:39:34 +00001415
1416 // Loop over the various components which exist and select the best GCC
1417 // installation available. GCC installs are ranked by version number.
1418 Version = GCCVersion::Parse("0.0.0");
Douglas Katzman6bbffc42015-06-25 18:51:37 +00001419 for (const std::string &Prefix : Prefixes) {
Benjamin Kramerd45b2052015-10-07 15:48:01 +00001420 if (!D.getVFS().exists(Prefix))
Chandler Carruth4c90fba2011-11-06 23:39:34 +00001421 continue;
Benjamin Kramer72e64312015-09-24 14:48:49 +00001422 for (StringRef Suffix : CandidateLibDirs) {
Douglas Katzman6bbffc42015-06-25 18:51:37 +00001423 const std::string LibDir = Prefix + Suffix.str();
Benjamin Kramerd45b2052015-10-07 15:48:01 +00001424 if (!D.getVFS().exists(LibDir))
Chandler Carruth4c90fba2011-11-06 23:39:34 +00001425 continue;
Benjamin Kramer72e64312015-09-24 14:48:49 +00001426 for (StringRef Candidate : ExtraTripleAliases) // Try these first.
Douglas Katzmand6e597c2015-09-17 19:56:40 +00001427 ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, Candidate);
Benjamin Kramer72e64312015-09-24 14:48:49 +00001428 for (StringRef Candidate : CandidateTripleAliases)
Douglas Katzman6bbffc42015-06-25 18:51:37 +00001429 ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, Candidate);
Chandler Carruth866faab2012-01-25 07:21:38 +00001430 }
Benjamin Kramer72e64312015-09-24 14:48:49 +00001431 for (StringRef Suffix : CandidateBiarchLibDirs) {
Douglas Katzman6bbffc42015-06-25 18:51:37 +00001432 const std::string LibDir = Prefix + Suffix.str();
Benjamin Kramerd45b2052015-10-07 15:48:01 +00001433 if (!D.getVFS().exists(LibDir))
Chandler Carruth866faab2012-01-25 07:21:38 +00001434 continue;
Benjamin Kramer72e64312015-09-24 14:48:49 +00001435 for (StringRef Candidate : CandidateBiarchTripleAliases)
Douglas Katzman6bbffc42015-06-25 18:51:37 +00001436 ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, Candidate,
Chandler Carruthb427c562013-06-22 11:35:51 +00001437 /*NeedsBiarchSuffix=*/ true);
Chandler Carruth4c90fba2011-11-06 23:39:34 +00001438 }
1439 }
1440}
1441
Chandler Carruth0ae39aa2013-07-30 17:57:09 +00001442void Generic_GCC::GCCInstallationDetector::print(raw_ostream &OS) const {
Simon Atanasyan6f657c42014-05-08 19:32:46 +00001443 for (const auto &InstallPath : CandidateGCCInstallPaths)
1444 OS << "Found candidate GCC installation: " << InstallPath << "\n";
Chandler Carruth0ae39aa2013-07-30 17:57:09 +00001445
Yunzhong Gaoe3f902c2014-02-19 19:06:58 +00001446 if (!GCCInstallPath.empty())
1447 OS << "Selected GCC installation: " << GCCInstallPath << "\n";
1448
Simon Atanasyan6f657c42014-05-08 19:32:46 +00001449 for (const auto &Multilib : Multilibs)
1450 OS << "Candidate multilib: " << Multilib << "\n";
Yunzhong Gaoe3f902c2014-02-19 19:06:58 +00001451
1452 if (Multilibs.size() != 0 || !SelectedMultilib.isDefault())
1453 OS << "Selected multilib: " << SelectedMultilib << "\n";
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00001454}
1455
1456bool Generic_GCC::GCCInstallationDetector::getBiarchSibling(Multilib &M) const {
1457 if (BiarchSibling.hasValue()) {
1458 M = BiarchSibling.getValue();
1459 return true;
1460 }
1461 return false;
Chandler Carruth0ae39aa2013-07-30 17:57:09 +00001462}
1463
Chandler Carruth4c90fba2011-11-06 23:39:34 +00001464/*static*/ void Generic_GCC::GCCInstallationDetector::CollectLibDirsAndTriples(
Chandler Carruthb427c562013-06-22 11:35:51 +00001465 const llvm::Triple &TargetTriple, const llvm::Triple &BiarchTriple,
Chandler Carruth866faab2012-01-25 07:21:38 +00001466 SmallVectorImpl<StringRef> &LibDirs,
1467 SmallVectorImpl<StringRef> &TripleAliases,
Chandler Carruthb427c562013-06-22 11:35:51 +00001468 SmallVectorImpl<StringRef> &BiarchLibDirs,
1469 SmallVectorImpl<StringRef> &BiarchTripleAliases) {
Chandler Carruth866faab2012-01-25 07:21:38 +00001470 // Declare a bunch of static data sets that we'll select between below. These
1471 // are specifically designed to always refer to string literals to avoid any
1472 // lifetime or initialization issues.
Douglas Katzmana67e50c2015-06-26 15:47:46 +00001473 static const char *const AArch64LibDirs[] = {"/lib64", "/lib"};
1474 static const char *const AArch64Triples[] = {
1475 "aarch64-none-linux-gnu", "aarch64-linux-gnu", "aarch64-linux-android",
1476 "aarch64-redhat-linux"};
1477 static const char *const AArch64beLibDirs[] = {"/lib"};
1478 static const char *const AArch64beTriples[] = {"aarch64_be-none-linux-gnu",
1479 "aarch64_be-linux-gnu"};
Tim Northover9bb857a2013-01-31 12:13:10 +00001480
Douglas Katzmana67e50c2015-06-26 15:47:46 +00001481 static const char *const ARMLibDirs[] = {"/lib"};
1482 static const char *const ARMTriples[] = {"arm-linux-gnueabi",
1483 "arm-linux-androideabi"};
1484 static const char *const ARMHFTriples[] = {"arm-linux-gnueabihf",
1485 "armv7hl-redhat-linux-gnueabi"};
1486 static const char *const ARMebLibDirs[] = {"/lib"};
1487 static const char *const ARMebTriples[] = {"armeb-linux-gnueabi",
1488 "armeb-linux-androideabi"};
1489 static const char *const ARMebHFTriples[] = {
1490 "armeb-linux-gnueabihf", "armebv7hl-redhat-linux-gnueabi"};
Chandler Carruth866faab2012-01-25 07:21:38 +00001491
Douglas Katzmana67e50c2015-06-26 15:47:46 +00001492 static const char *const X86_64LibDirs[] = {"/lib64", "/lib"};
Chandler Carruth866faab2012-01-25 07:21:38 +00001493 static const char *const X86_64Triples[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00001494 "x86_64-linux-gnu", "x86_64-unknown-linux-gnu",
1495 "x86_64-pc-linux-gnu", "x86_64-redhat-linux6E",
1496 "x86_64-redhat-linux", "x86_64-suse-linux",
1497 "x86_64-manbo-linux-gnu", "x86_64-linux-gnu",
1498 "x86_64-slackware-linux", "x86_64-linux-android",
1499 "x86_64-unknown-linux"};
1500 static const char *const X32LibDirs[] = {"/libx32"};
1501 static const char *const X86LibDirs[] = {"/lib32", "/lib"};
Chandler Carruth866faab2012-01-25 07:21:38 +00001502 static const char *const X86Triples[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00001503 "i686-linux-gnu", "i686-pc-linux-gnu", "i486-linux-gnu",
1504 "i386-linux-gnu", "i386-redhat-linux6E", "i686-redhat-linux",
1505 "i586-redhat-linux", "i386-redhat-linux", "i586-suse-linux",
1506 "i486-slackware-linux", "i686-montavista-linux", "i686-linux-android",
1507 "i586-linux-gnu"};
Chandler Carruth866faab2012-01-25 07:21:38 +00001508
Douglas Katzmana67e50c2015-06-26 15:47:46 +00001509 static const char *const MIPSLibDirs[] = {"/lib"};
Vasileios Kalintirisc744e122015-11-12 15:26:54 +00001510 static const char *const MIPSTriples[] = {"mips-linux-gnu", "mips-mti-linux",
1511 "mips-mti-linux-gnu",
1512 "mips-img-linux-gnu"};
Douglas Katzmana67e50c2015-06-26 15:47:46 +00001513 static const char *const MIPSELLibDirs[] = {"/lib"};
Simon Atanasyan603018a2016-07-19 07:09:48 +00001514 static const char *const MIPSELTriples[] = {"mipsel-linux-gnu",
1515 "mips-img-linux-gnu"};
Chandler Carruth866faab2012-01-25 07:21:38 +00001516
Douglas Katzmana67e50c2015-06-26 15:47:46 +00001517 static const char *const MIPS64LibDirs[] = {"/lib64", "/lib"};
1518 static const char *const MIPS64Triples[] = {
1519 "mips64-linux-gnu", "mips-mti-linux-gnu", "mips-img-linux-gnu",
1520 "mips64-linux-gnuabi64"};
1521 static const char *const MIPS64ELLibDirs[] = {"/lib64", "/lib"};
1522 static const char *const MIPS64ELTriples[] = {
1523 "mips64el-linux-gnu", "mips-mti-linux-gnu", "mips-img-linux-gnu",
Simon Atanasyan603018a2016-07-19 07:09:48 +00001524 "mips64el-linux-gnuabi64"};
1525
1526 static const char *const MIPSELAndroidLibDirs[] = {"/lib", "/libr2",
1527 "/libr6"};
1528 static const char *const MIPSELAndroidTriples[] = {"mipsel-linux-android"};
1529 static const char *const MIPS64ELAndroidLibDirs[] = {"/lib64", "/lib",
1530 "/libr2", "/libr6"};
1531 static const char *const MIPS64ELAndroidTriples[] = {
1532 "mips64el-linux-android"};
Simon Atanasyan9bb634d2012-04-26 19:57:02 +00001533
Douglas Katzmana67e50c2015-06-26 15:47:46 +00001534 static const char *const PPCLibDirs[] = {"/lib32", "/lib"};
Chandler Carruth866faab2012-01-25 07:21:38 +00001535 static const char *const PPCTriples[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00001536 "powerpc-linux-gnu", "powerpc-unknown-linux-gnu", "powerpc-linux-gnuspe",
1537 "powerpc-suse-linux", "powerpc-montavista-linuxspe"};
1538 static const char *const PPC64LibDirs[] = {"/lib64", "/lib"};
1539 static const char *const PPC64Triples[] = {
1540 "powerpc64-linux-gnu", "powerpc64-unknown-linux-gnu",
1541 "powerpc64-suse-linux", "ppc64-redhat-linux"};
1542 static const char *const PPC64LELibDirs[] = {"/lib64", "/lib"};
1543 static const char *const PPC64LETriples[] = {
1544 "powerpc64le-linux-gnu", "powerpc64le-unknown-linux-gnu",
1545 "powerpc64le-suse-linux", "ppc64le-redhat-linux"};
Chandler Carruth866faab2012-01-25 07:21:38 +00001546
Douglas Katzmana67e50c2015-06-26 15:47:46 +00001547 static const char *const SPARCv8LibDirs[] = {"/lib32", "/lib"};
1548 static const char *const SPARCv8Triples[] = {"sparc-linux-gnu",
1549 "sparcv8-linux-gnu"};
1550 static const char *const SPARCv9LibDirs[] = {"/lib64", "/lib"};
1551 static const char *const SPARCv9Triples[] = {"sparc64-linux-gnu",
1552 "sparcv9-linux-gnu"};
Jakob Stoklund Olesenb3f938e2014-01-10 06:53:02 +00001553
Douglas Katzmana67e50c2015-06-26 15:47:46 +00001554 static const char *const SystemZLibDirs[] = {"/lib64", "/lib"};
Ulrich Weigand47445072013-05-06 16:26:41 +00001555 static const char *const SystemZTriples[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00001556 "s390x-linux-gnu", "s390x-unknown-linux-gnu", "s390x-ibm-linux-gnu",
1557 "s390x-suse-linux", "s390x-redhat-linux"};
Ulrich Weigand47445072013-05-06 16:26:41 +00001558
Rafael Espindolac53c5b12015-08-31 19:17:51 +00001559 // Solaris.
1560 static const char *const SolarisSPARCLibDirs[] = {"/gcc"};
1561 static const char *const SolarisSPARCTriples[] = {"sparc-sun-solaris2.11",
1562 "i386-pc-solaris2.11"};
1563
Benjamin Kramer6ec434e2014-10-18 10:43:51 +00001564 using std::begin;
1565 using std::end;
1566
Rafael Espindolac53c5b12015-08-31 19:17:51 +00001567 if (TargetTriple.getOS() == llvm::Triple::Solaris) {
1568 LibDirs.append(begin(SolarisSPARCLibDirs), end(SolarisSPARCLibDirs));
1569 TripleAliases.append(begin(SolarisSPARCTriples), end(SolarisSPARCTriples));
Rafael Espindolac53c5b12015-08-31 19:17:51 +00001570 return;
1571 }
1572
Chandler Carruth866faab2012-01-25 07:21:38 +00001573 switch (TargetTriple.getArch()) {
Tim Northover9bb857a2013-01-31 12:13:10 +00001574 case llvm::Triple::aarch64:
Benjamin Kramer6ec434e2014-10-18 10:43:51 +00001575 LibDirs.append(begin(AArch64LibDirs), end(AArch64LibDirs));
1576 TripleAliases.append(begin(AArch64Triples), end(AArch64Triples));
1577 BiarchLibDirs.append(begin(AArch64LibDirs), end(AArch64LibDirs));
1578 BiarchTripleAliases.append(begin(AArch64Triples), end(AArch64Triples));
Tim Northover9bb857a2013-01-31 12:13:10 +00001579 break;
Christian Pirkera74c7912014-03-14 12:15:45 +00001580 case llvm::Triple::aarch64_be:
Benjamin Kramer6ec434e2014-10-18 10:43:51 +00001581 LibDirs.append(begin(AArch64beLibDirs), end(AArch64beLibDirs));
1582 TripleAliases.append(begin(AArch64beTriples), end(AArch64beTriples));
1583 BiarchLibDirs.append(begin(AArch64beLibDirs), end(AArch64beLibDirs));
1584 BiarchTripleAliases.append(begin(AArch64beTriples), end(AArch64beTriples));
Christian Pirkera74c7912014-03-14 12:15:45 +00001585 break;
Chandler Carruth866faab2012-01-25 07:21:38 +00001586 case llvm::Triple::arm:
1587 case llvm::Triple::thumb:
Benjamin Kramer6ec434e2014-10-18 10:43:51 +00001588 LibDirs.append(begin(ARMLibDirs), end(ARMLibDirs));
Jiangning Liu61b06cb2012-07-31 08:06:29 +00001589 if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF) {
Benjamin Kramer6ec434e2014-10-18 10:43:51 +00001590 TripleAliases.append(begin(ARMHFTriples), end(ARMHFTriples));
Jiangning Liu61b06cb2012-07-31 08:06:29 +00001591 } else {
Benjamin Kramer6ec434e2014-10-18 10:43:51 +00001592 TripleAliases.append(begin(ARMTriples), end(ARMTriples));
Jiangning Liu61b06cb2012-07-31 08:06:29 +00001593 }
Chandler Carruth866faab2012-01-25 07:21:38 +00001594 break;
Christian Pirkerf01cd6f2014-03-28 14:40:46 +00001595 case llvm::Triple::armeb:
1596 case llvm::Triple::thumbeb:
Benjamin Kramer6ec434e2014-10-18 10:43:51 +00001597 LibDirs.append(begin(ARMebLibDirs), end(ARMebLibDirs));
Christian Pirkerf01cd6f2014-03-28 14:40:46 +00001598 if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF) {
Benjamin Kramer6ec434e2014-10-18 10:43:51 +00001599 TripleAliases.append(begin(ARMebHFTriples), end(ARMebHFTriples));
Christian Pirkerf01cd6f2014-03-28 14:40:46 +00001600 } else {
Benjamin Kramer6ec434e2014-10-18 10:43:51 +00001601 TripleAliases.append(begin(ARMebTriples), end(ARMebTriples));
Christian Pirkerf01cd6f2014-03-28 14:40:46 +00001602 }
1603 break;
Chandler Carruth866faab2012-01-25 07:21:38 +00001604 case llvm::Triple::x86_64:
Benjamin Kramer6ec434e2014-10-18 10:43:51 +00001605 LibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs));
1606 TripleAliases.append(begin(X86_64Triples), end(X86_64Triples));
1607 // x32 is always available when x86_64 is available, so adding it as
1608 // secondary arch with x86_64 triples
Zinovy Nis1db95732014-07-10 15:27:19 +00001609 if (TargetTriple.getEnvironment() == llvm::Triple::GNUX32) {
Benjamin Kramer6ec434e2014-10-18 10:43:51 +00001610 BiarchLibDirs.append(begin(X32LibDirs), end(X32LibDirs));
1611 BiarchTripleAliases.append(begin(X86_64Triples), end(X86_64Triples));
Zinovy Nis1db95732014-07-10 15:27:19 +00001612 } else {
Benjamin Kramer6ec434e2014-10-18 10:43:51 +00001613 BiarchLibDirs.append(begin(X86LibDirs), end(X86LibDirs));
1614 BiarchTripleAliases.append(begin(X86Triples), end(X86Triples));
Zinovy Nis1db95732014-07-10 15:27:19 +00001615 }
Chandler Carruth866faab2012-01-25 07:21:38 +00001616 break;
1617 case llvm::Triple::x86:
Benjamin Kramer6ec434e2014-10-18 10:43:51 +00001618 LibDirs.append(begin(X86LibDirs), end(X86LibDirs));
Andrey Turetskiy4798eb62016-06-16 10:36:09 +00001619 // MCU toolchain is 32 bit only and its triple alias is TargetTriple
1620 // itself, which will be appended below.
1621 if (!TargetTriple.isOSIAMCU()) {
1622 TripleAliases.append(begin(X86Triples), end(X86Triples));
1623 BiarchLibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs));
1624 BiarchTripleAliases.append(begin(X86_64Triples), end(X86_64Triples));
1625 }
Chandler Carruth866faab2012-01-25 07:21:38 +00001626 break;
1627 case llvm::Triple::mips:
Benjamin Kramer6ec434e2014-10-18 10:43:51 +00001628 LibDirs.append(begin(MIPSLibDirs), end(MIPSLibDirs));
1629 TripleAliases.append(begin(MIPSTriples), end(MIPSTriples));
1630 BiarchLibDirs.append(begin(MIPS64LibDirs), end(MIPS64LibDirs));
1631 BiarchTripleAliases.append(begin(MIPS64Triples), end(MIPS64Triples));
Chandler Carruth866faab2012-01-25 07:21:38 +00001632 break;
1633 case llvm::Triple::mipsel:
Simon Atanasyan603018a2016-07-19 07:09:48 +00001634 if (TargetTriple.isAndroid()) {
1635 LibDirs.append(begin(MIPSELAndroidLibDirs), end(MIPSELAndroidLibDirs));
1636 TripleAliases.append(begin(MIPSELAndroidTriples),
1637 end(MIPSELAndroidTriples));
1638 BiarchLibDirs.append(begin(MIPS64ELAndroidLibDirs),
1639 end(MIPS64ELAndroidLibDirs));
1640 BiarchTripleAliases.append(begin(MIPS64ELAndroidTriples),
1641 end(MIPS64ELAndroidTriples));
1642
1643 } else {
1644 LibDirs.append(begin(MIPSELLibDirs), end(MIPSELLibDirs));
1645 TripleAliases.append(begin(MIPSELTriples), end(MIPSELTriples));
1646 TripleAliases.append(begin(MIPSTriples), end(MIPSTriples));
1647 BiarchLibDirs.append(begin(MIPS64ELLibDirs), end(MIPS64ELLibDirs));
1648 BiarchTripleAliases.append(begin(MIPS64ELTriples), end(MIPS64ELTriples));
1649 }
Simon Atanasyan9bb634d2012-04-26 19:57:02 +00001650 break;
1651 case llvm::Triple::mips64:
Benjamin Kramer6ec434e2014-10-18 10:43:51 +00001652 LibDirs.append(begin(MIPS64LibDirs), end(MIPS64LibDirs));
1653 TripleAliases.append(begin(MIPS64Triples), end(MIPS64Triples));
1654 BiarchLibDirs.append(begin(MIPSLibDirs), end(MIPSLibDirs));
1655 BiarchTripleAliases.append(begin(MIPSTriples), end(MIPSTriples));
Simon Atanasyan9bb634d2012-04-26 19:57:02 +00001656 break;
1657 case llvm::Triple::mips64el:
Simon Atanasyan603018a2016-07-19 07:09:48 +00001658 if (TargetTriple.isAndroid()) {
1659 LibDirs.append(begin(MIPS64ELAndroidLibDirs),
1660 end(MIPS64ELAndroidLibDirs));
1661 TripleAliases.append(begin(MIPS64ELAndroidTriples),
1662 end(MIPS64ELAndroidTriples));
1663 BiarchLibDirs.append(begin(MIPSELAndroidLibDirs),
1664 end(MIPSELAndroidLibDirs));
1665 BiarchTripleAliases.append(begin(MIPSELAndroidTriples),
1666 end(MIPSELAndroidTriples));
1667
1668 } else {
1669 LibDirs.append(begin(MIPS64ELLibDirs), end(MIPS64ELLibDirs));
1670 TripleAliases.append(begin(MIPS64ELTriples), end(MIPS64ELTriples));
1671 BiarchLibDirs.append(begin(MIPSELLibDirs), end(MIPSELLibDirs));
1672 BiarchTripleAliases.append(begin(MIPSELTriples), end(MIPSELTriples));
1673 BiarchTripleAliases.append(begin(MIPSTriples), end(MIPSTriples));
1674 }
Chandler Carruth866faab2012-01-25 07:21:38 +00001675 break;
1676 case llvm::Triple::ppc:
Benjamin Kramer6ec434e2014-10-18 10:43:51 +00001677 LibDirs.append(begin(PPCLibDirs), end(PPCLibDirs));
1678 TripleAliases.append(begin(PPCTriples), end(PPCTriples));
1679 BiarchLibDirs.append(begin(PPC64LibDirs), end(PPC64LibDirs));
1680 BiarchTripleAliases.append(begin(PPC64Triples), end(PPC64Triples));
Chandler Carruth866faab2012-01-25 07:21:38 +00001681 break;
1682 case llvm::Triple::ppc64:
Benjamin Kramer6ec434e2014-10-18 10:43:51 +00001683 LibDirs.append(begin(PPC64LibDirs), end(PPC64LibDirs));
1684 TripleAliases.append(begin(PPC64Triples), end(PPC64Triples));
1685 BiarchLibDirs.append(begin(PPCLibDirs), end(PPCLibDirs));
1686 BiarchTripleAliases.append(begin(PPCTriples), end(PPCTriples));
Chandler Carruth866faab2012-01-25 07:21:38 +00001687 break;
Bill Schmidt778d3872013-07-26 01:36:11 +00001688 case llvm::Triple::ppc64le:
Benjamin Kramer6ec434e2014-10-18 10:43:51 +00001689 LibDirs.append(begin(PPC64LELibDirs), end(PPC64LELibDirs));
1690 TripleAliases.append(begin(PPC64LETriples), end(PPC64LETriples));
Bill Schmidt778d3872013-07-26 01:36:11 +00001691 break;
Jakob Stoklund Olesenb3f938e2014-01-10 06:53:02 +00001692 case llvm::Triple::sparc:
Douglas Katzmanb76a3df2015-09-02 13:33:42 +00001693 case llvm::Triple::sparcel:
Benjamin Kramer6ec434e2014-10-18 10:43:51 +00001694 LibDirs.append(begin(SPARCv8LibDirs), end(SPARCv8LibDirs));
1695 TripleAliases.append(begin(SPARCv8Triples), end(SPARCv8Triples));
1696 BiarchLibDirs.append(begin(SPARCv9LibDirs), end(SPARCv9LibDirs));
1697 BiarchTripleAliases.append(begin(SPARCv9Triples), end(SPARCv9Triples));
Jakob Stoklund Olesenb3f938e2014-01-10 06:53:02 +00001698 break;
1699 case llvm::Triple::sparcv9:
Benjamin Kramer6ec434e2014-10-18 10:43:51 +00001700 LibDirs.append(begin(SPARCv9LibDirs), end(SPARCv9LibDirs));
1701 TripleAliases.append(begin(SPARCv9Triples), end(SPARCv9Triples));
1702 BiarchLibDirs.append(begin(SPARCv8LibDirs), end(SPARCv8LibDirs));
1703 BiarchTripleAliases.append(begin(SPARCv8Triples), end(SPARCv8Triples));
Jakob Stoklund Olesenb3f938e2014-01-10 06:53:02 +00001704 break;
Ulrich Weigand47445072013-05-06 16:26:41 +00001705 case llvm::Triple::systemz:
Benjamin Kramer6ec434e2014-10-18 10:43:51 +00001706 LibDirs.append(begin(SystemZLibDirs), end(SystemZLibDirs));
1707 TripleAliases.append(begin(SystemZTriples), end(SystemZTriples));
Ulrich Weigand47445072013-05-06 16:26:41 +00001708 break;
Chandler Carruth866faab2012-01-25 07:21:38 +00001709 default:
1710 // By default, just rely on the standard lib directories and the original
1711 // triple.
1712 break;
Chandler Carruth4c90fba2011-11-06 23:39:34 +00001713 }
Chandler Carruth866faab2012-01-25 07:21:38 +00001714
1715 // Always append the drivers target triple to the end, in case it doesn't
1716 // match any of our aliases.
1717 TripleAliases.push_back(TargetTriple.str());
1718
1719 // Also include the multiarch variant if it's different.
Chandler Carruthb427c562013-06-22 11:35:51 +00001720 if (TargetTriple.str() != BiarchTriple.str())
1721 BiarchTripleAliases.push_back(BiarchTriple.str());
Chandler Carruth4c90fba2011-11-06 23:39:34 +00001722}
1723
Justin Lebarc43ad9e2016-07-07 18:17:52 +00001724// Parses the contents of version.txt in an CUDA installation. It should
1725// contain one line of the from e.g. "CUDA Version 7.5.2".
1726static CudaVersion ParseCudaVersionFile(llvm::StringRef V) {
1727 if (!V.startswith("CUDA Version "))
1728 return CudaVersion::UNKNOWN;
1729 V = V.substr(strlen("CUDA Version "));
1730 int Major = -1, Minor = -1;
1731 auto First = V.split('.');
1732 auto Second = First.second.split('.');
1733 if (!First.first.getAsInteger(10, Major) ||
1734 !Second.first.getAsInteger(10, Minor))
1735 return CudaVersion::UNKNOWN;
1736
1737 if (Major == 7 && Minor == 0) {
1738 // This doesn't appear to ever happen -- version.txt doesn't exist in the
1739 // CUDA 7 installs I've seen. But no harm in checking.
1740 return CudaVersion::CUDA_70;
1741 }
1742 if (Major == 7 && Minor == 5)
1743 return CudaVersion::CUDA_75;
1744 if (Major == 8 && Minor == 0)
1745 return CudaVersion::CUDA_80;
1746 return CudaVersion::UNKNOWN;
1747}
1748
Artem Belevich98607b62015-09-23 21:49:39 +00001749// \brief -- try common CUDA installation paths looking for files we need for
1750// CUDA compilation.
Benjamin Kramerd45b2052015-10-07 15:48:01 +00001751void Generic_GCC::CudaInstallationDetector::init(
1752 const llvm::Triple &TargetTriple, const llvm::opt::ArgList &Args) {
NAKAMURA Takumi0c8decd2015-09-24 03:15:44 +00001753 SmallVector<std::string, 4> CudaPathCandidates;
Artem Belevich98607b62015-09-23 21:49:39 +00001754
1755 if (Args.hasArg(options::OPT_cuda_path_EQ))
1756 CudaPathCandidates.push_back(
1757 Args.getLastArgValue(options::OPT_cuda_path_EQ));
1758 else {
1759 CudaPathCandidates.push_back(D.SysRoot + "/usr/local/cuda");
Justin Lebaref1aaac2016-07-06 21:21:14 +00001760 // FIXME: Uncomment this once we can compile the cuda 8 headers.
1761 // CudaPathCandidates.push_back(D.SysRoot + "/usr/local/cuda-8.0");
Artem Belevich86017332015-11-17 22:28:55 +00001762 CudaPathCandidates.push_back(D.SysRoot + "/usr/local/cuda-7.5");
Artem Belevich98607b62015-09-23 21:49:39 +00001763 CudaPathCandidates.push_back(D.SysRoot + "/usr/local/cuda-7.0");
1764 }
1765
Benjamin Kramere8b76412015-09-24 14:48:37 +00001766 for (const auto &CudaPath : CudaPathCandidates) {
Benjamin Kramerd45b2052015-10-07 15:48:01 +00001767 if (CudaPath.empty() || !D.getVFS().exists(CudaPath))
Artem Belevich98607b62015-09-23 21:49:39 +00001768 continue;
1769
Justin Lebar710c1312016-07-06 21:21:43 +00001770 InstallPath = CudaPath;
1771 BinPath = CudaPath + "/bin";
1772 IncludePath = InstallPath + "/include";
1773 LibDevicePath = InstallPath + "/nvvm/libdevice";
1774 LibPath = InstallPath + (TargetTriple.isArch64Bit() ? "/lib64" : "/lib");
Artem Belevich98607b62015-09-23 21:49:39 +00001775
Justin Lebar710c1312016-07-06 21:21:43 +00001776 auto &FS = D.getVFS();
1777 if (!(FS.exists(IncludePath) && FS.exists(BinPath) && FS.exists(LibPath) &&
1778 FS.exists(LibDevicePath)))
Artem Belevich98607b62015-09-23 21:49:39 +00001779 continue;
1780
Artem Belevich34f481a2015-11-17 22:28:50 +00001781 std::error_code EC;
Justin Lebar710c1312016-07-06 21:21:43 +00001782 for (llvm::sys::fs::directory_iterator LI(LibDevicePath, EC), LE;
Artem Belevich34f481a2015-11-17 22:28:50 +00001783 !EC && LI != LE; LI = LI.increment(EC)) {
1784 StringRef FilePath = LI->path();
1785 StringRef FileName = llvm::sys::path::filename(FilePath);
1786 // Process all bitcode filenames that look like libdevice.compute_XX.YY.bc
1787 const StringRef LibDeviceName = "libdevice.";
1788 if (!(FileName.startswith(LibDeviceName) && FileName.endswith(".bc")))
1789 continue;
1790 StringRef GpuArch = FileName.slice(
1791 LibDeviceName.size(), FileName.find('.', LibDeviceName.size()));
Justin Lebar710c1312016-07-06 21:21:43 +00001792 LibDeviceMap[GpuArch] = FilePath.str();
Artem Belevich34f481a2015-11-17 22:28:50 +00001793 // Insert map entries for specifc devices with this compute capability.
1794 if (GpuArch == "compute_20") {
Justin Lebar710c1312016-07-06 21:21:43 +00001795 LibDeviceMap["sm_20"] = FilePath;
1796 LibDeviceMap["sm_21"] = FilePath;
Artem Belevich34f481a2015-11-17 22:28:50 +00001797 } else if (GpuArch == "compute_30") {
Justin Lebar710c1312016-07-06 21:21:43 +00001798 LibDeviceMap["sm_30"] = FilePath;
1799 LibDeviceMap["sm_32"] = FilePath;
Artem Belevich34f481a2015-11-17 22:28:50 +00001800 } else if (GpuArch == "compute_35") {
Justin Lebar710c1312016-07-06 21:21:43 +00001801 LibDeviceMap["sm_35"] = FilePath;
1802 LibDeviceMap["sm_37"] = FilePath;
Artem Belevichffa5fc52016-05-19 17:47:47 +00001803 } else if (GpuArch == "compute_50") {
Justin Lebar710c1312016-07-06 21:21:43 +00001804 LibDeviceMap["sm_50"] = FilePath;
1805 LibDeviceMap["sm_52"] = FilePath;
1806 LibDeviceMap["sm_53"] = FilePath;
1807 LibDeviceMap["sm_60"] = FilePath;
1808 LibDeviceMap["sm_61"] = FilePath;
1809 LibDeviceMap["sm_62"] = FilePath;
Artem Belevich34f481a2015-11-17 22:28:50 +00001810 }
1811 }
1812
Justin Lebarc43ad9e2016-07-07 18:17:52 +00001813 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> VersionFile =
1814 FS.getBufferForFile(InstallPath + "/version.txt");
1815 if (!VersionFile) {
1816 // CUDA 7.0 doesn't have a version.txt, so guess that's our version if
1817 // version.txt isn't present.
1818 Version = CudaVersion::CUDA_70;
1819 } else {
1820 Version = ParseCudaVersionFile((*VersionFile)->getBuffer());
1821 }
1822
Artem Belevich98607b62015-09-23 21:49:39 +00001823 IsValid = true;
1824 break;
1825 }
1826}
1827
Justin Lebarc43ad9e2016-07-07 18:17:52 +00001828void Generic_GCC::CudaInstallationDetector::CheckCudaVersionSupportsArch(
1829 CudaArch Arch) const {
1830 if (Arch == CudaArch::UNKNOWN || Version == CudaVersion::UNKNOWN ||
1831 ArchsWithVersionTooLowErrors.count(Arch) > 0)
1832 return;
1833
1834 auto RequiredVersion = MinVersionForCudaArch(Arch);
1835 if (Version < RequiredVersion) {
1836 ArchsWithVersionTooLowErrors.insert(Arch);
1837 D.Diag(diag::err_drv_cuda_version_too_low)
1838 << InstallPath << CudaArchToString(Arch) << CudaVersionToString(Version)
1839 << CudaVersionToString(RequiredVersion);
1840 }
1841}
1842
Artem Belevich98607b62015-09-23 21:49:39 +00001843void Generic_GCC::CudaInstallationDetector::print(raw_ostream &OS) const {
1844 if (isValid())
Justin Lebarc43ad9e2016-07-07 18:17:52 +00001845 OS << "Found CUDA installation: " << InstallPath << ", version "
1846 << CudaVersionToString(Version) << "\n";
Artem Belevich98607b62015-09-23 21:49:39 +00001847}
1848
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00001849namespace {
1850// Filter to remove Multilibs that don't exist as a suffix to Path
Benjamin Kramerac75baa2015-03-22 15:56:12 +00001851class FilterNonExistent {
Andrey Turetskiy4798eb62016-06-16 10:36:09 +00001852 StringRef Base, File;
Benjamin Kramerc5862f02015-10-09 13:03:18 +00001853 vfs::FileSystem &VFS;
Benjamin Kramerac75baa2015-03-22 15:56:12 +00001854
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00001855public:
Andrey Turetskiy4798eb62016-06-16 10:36:09 +00001856 FilterNonExistent(StringRef Base, StringRef File, vfs::FileSystem &VFS)
1857 : Base(Base), File(File), VFS(VFS) {}
Benjamin Kramerac75baa2015-03-22 15:56:12 +00001858 bool operator()(const Multilib &M) {
Andrey Turetskiy4798eb62016-06-16 10:36:09 +00001859 return !VFS.exists(Base + M.gccSuffix() + File);
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00001860 }
1861};
1862} // end anonymous namespace
1863
1864static void addMultilibFlag(bool Enabled, const char *const Flag,
1865 std::vector<std::string> &Flags) {
1866 if (Enabled)
1867 Flags.push_back(std::string("+") + Flag);
1868 else
1869 Flags.push_back(std::string("-") + Flag);
1870}
1871
Chih-Hung Hsiehb4d3bf72016-06-01 20:48:46 +00001872static bool isArmOrThumbArch(llvm::Triple::ArchType Arch) {
1873 return Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb;
1874}
1875
Simon Atanasyan08450bd2013-04-20 08:15:03 +00001876static bool isMipsArch(llvm::Triple::ArchType Arch) {
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00001877 return Arch == llvm::Triple::mips || Arch == llvm::Triple::mipsel ||
1878 Arch == llvm::Triple::mips64 || Arch == llvm::Triple::mips64el;
1879}
1880
1881static bool isMips32(llvm::Triple::ArchType Arch) {
1882 return Arch == llvm::Triple::mips || Arch == llvm::Triple::mipsel;
1883}
1884
1885static bool isMips64(llvm::Triple::ArchType Arch) {
1886 return Arch == llvm::Triple::mips64 || Arch == llvm::Triple::mips64el;
1887}
1888
1889static bool isMipsEL(llvm::Triple::ArchType Arch) {
1890 return Arch == llvm::Triple::mipsel || Arch == llvm::Triple::mips64el;
1891}
1892
Simon Atanasyan08450bd2013-04-20 08:15:03 +00001893static bool isMips16(const ArgList &Args) {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00001894 Arg *A = Args.getLastArg(options::OPT_mips16, options::OPT_mno_mips16);
Simon Atanasyan08450bd2013-04-20 08:15:03 +00001895 return A && A->getOption().matches(options::OPT_mips16);
1896}
1897
1898static bool isMicroMips(const ArgList &Args) {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00001899 Arg *A = Args.getLastArg(options::OPT_mmicromips, options::OPT_mno_micromips);
Simon Atanasyan08450bd2013-04-20 08:15:03 +00001900 return A && A->getOption().matches(options::OPT_mmicromips);
1901}
1902
Benjamin Kramere003ca22015-10-28 13:54:16 +00001903namespace {
Simon Atanasyan60280b42014-05-12 07:37:51 +00001904struct DetectedMultilibs {
1905 /// The set of multilibs that the detected installation supports.
1906 MultilibSet Multilibs;
1907
1908 /// The primary multilib appropriate for the given flags.
1909 Multilib SelectedMultilib;
1910
1911 /// On Biarch systems, this corresponds to the default multilib when
1912 /// targeting the non-default multilib. Otherwise, it is empty.
1913 llvm::Optional<Multilib> BiarchSibling;
1914};
Benjamin Kramere003ca22015-10-28 13:54:16 +00001915} // end anonymous namespace
Simon Atanasyan60280b42014-05-12 07:37:51 +00001916
Simon Atanasyan1b0542e2014-07-30 09:15:10 +00001917static Multilib makeMultilib(StringRef commonSuffix) {
1918 return Multilib(commonSuffix, commonSuffix, commonSuffix);
1919}
1920
Simon Atanasyanb4abcc52016-06-22 20:00:50 +00001921static bool findMipsCsMultilibs(const Multilib::flags_list &Flags,
1922 FilterNonExistent &NonExistent,
1923 DetectedMultilibs &Result) {
1924 // Check for Code Sourcery toolchain multilibs
1925 MultilibSet CSMipsMultilibs;
1926 {
1927 auto MArchMips16 = makeMultilib("/mips16").flag("+m32").flag("+mips16");
Simon Atanasyanee1accf2013-09-28 13:45:11 +00001928
Simon Atanasyanb4abcc52016-06-22 20:00:50 +00001929 auto MArchMicroMips =
1930 makeMultilib("/micromips").flag("+m32").flag("+mmicromips");
Jonathan Roelofs3fa96d82014-02-12 01:36:51 +00001931
Simon Atanasyanb4abcc52016-06-22 20:00:50 +00001932 auto MArchDefault = makeMultilib("").flag("-mips16").flag("-mmicromips");
1933
1934 auto UCLibc = makeMultilib("/uclibc").flag("+muclibc");
1935
1936 auto SoftFloat = makeMultilib("/soft-float").flag("+msoft-float");
1937
1938 auto Nan2008 = makeMultilib("/nan2008").flag("+mnan=2008");
1939
1940 auto DefaultFloat =
1941 makeMultilib("").flag("-msoft-float").flag("-mnan=2008");
1942
1943 auto BigEndian = makeMultilib("").flag("+EB").flag("-EL");
1944
1945 auto LittleEndian = makeMultilib("/el").flag("+EL").flag("-EB");
1946
1947 // Note that this one's osSuffix is ""
1948 auto MAbi64 = makeMultilib("")
1949 .gccSuffix("/64")
1950 .includeSuffix("/64")
1951 .flag("+mabi=n64")
1952 .flag("-mabi=n32")
1953 .flag("-m32");
1954
1955 CSMipsMultilibs =
1956 MultilibSet()
1957 .Either(MArchMips16, MArchMicroMips, MArchDefault)
1958 .Maybe(UCLibc)
1959 .Either(SoftFloat, Nan2008, DefaultFloat)
1960 .FilterOut("/micromips/nan2008")
1961 .FilterOut("/mips16/nan2008")
1962 .Either(BigEndian, LittleEndian)
1963 .Maybe(MAbi64)
1964 .FilterOut("/mips16.*/64")
1965 .FilterOut("/micromips.*/64")
1966 .FilterOut(NonExistent)
1967 .setIncludeDirsCallback([](const Multilib &M) {
1968 std::vector<std::string> Dirs({"/include"});
1969 if (StringRef(M.includeSuffix()).startswith("/uclibc"))
1970 Dirs.push_back(
1971 "/../../../../mips-linux-gnu/libc/uclibc/usr/include");
1972 else
1973 Dirs.push_back("/../../../../mips-linux-gnu/libc/usr/include");
1974 return Dirs;
1975 });
1976 }
1977
1978 MultilibSet DebianMipsMultilibs;
1979 {
1980 Multilib MAbiN32 =
1981 Multilib().gccSuffix("/n32").includeSuffix("/n32").flag("+mabi=n32");
1982
1983 Multilib M64 = Multilib()
1984 .gccSuffix("/64")
1985 .includeSuffix("/64")
1986 .flag("+m64")
1987 .flag("-m32")
1988 .flag("-mabi=n32");
1989
1990 Multilib M32 = Multilib().flag("-m64").flag("+m32").flag("-mabi=n32");
1991
1992 DebianMipsMultilibs =
1993 MultilibSet().Either(M32, M64, MAbiN32).FilterOut(NonExistent);
1994 }
1995
1996 // Sort candidates. Toolchain that best meets the directories tree goes first.
1997 // Then select the first toolchains matches command line flags.
1998 MultilibSet *Candidates[] = {&CSMipsMultilibs, &DebianMipsMultilibs};
1999 if (CSMipsMultilibs.size() < DebianMipsMultilibs.size())
2000 std::iter_swap(Candidates, Candidates + 1);
2001 for (const MultilibSet *Candidate : Candidates) {
2002 if (Candidate->select(Flags, Result.SelectedMultilib)) {
2003 if (Candidate == &DebianMipsMultilibs)
2004 Result.BiarchSibling = Multilib();
2005 Result.Multilibs = *Candidate;
2006 return true;
2007 }
2008 }
2009 return false;
2010}
2011
Simon Atanasyan603018a2016-07-19 07:09:48 +00002012static bool findMipsAndroidMultilibs(vfs::FileSystem &VFS, StringRef Path,
2013 const Multilib::flags_list &Flags,
Simon Atanasyanb4abcc52016-06-22 20:00:50 +00002014 FilterNonExistent &NonExistent,
2015 DetectedMultilibs &Result) {
2016
2017 MultilibSet AndroidMipsMultilibs =
2018 MultilibSet()
2019 .Maybe(Multilib("/mips-r2").flag("+march=mips32r2"))
2020 .Maybe(Multilib("/mips-r6").flag("+march=mips32r6"))
2021 .FilterOut(NonExistent);
2022
Simon Atanasyan603018a2016-07-19 07:09:48 +00002023 MultilibSet AndroidMipselMultilibs =
2024 MultilibSet()
2025 .Either(Multilib().flag("+march=mips32"),
2026 Multilib("/mips-r2", "", "/mips-r2").flag("+march=mips32r2"),
2027 Multilib("/mips-r6", "", "/mips-r6").flag("+march=mips32r6"))
2028 .FilterOut(NonExistent);
2029
2030 MultilibSet AndroidMips64elMultilibs =
2031 MultilibSet()
2032 .Either(
2033 Multilib().flag("+march=mips64r6"),
2034 Multilib("/32/mips-r1", "", "/mips-r1").flag("+march=mips32"),
2035 Multilib("/32/mips-r2", "", "/mips-r2").flag("+march=mips32r2"),
2036 Multilib("/32/mips-r6", "", "/mips-r6").flag("+march=mips32r6"))
2037 .FilterOut(NonExistent);
2038
2039 MultilibSet *MS = &AndroidMipsMultilibs;
2040 if (VFS.exists(Path + "/mips-r6"))
2041 MS = &AndroidMipselMultilibs;
2042 else if (VFS.exists(Path + "/32"))
2043 MS = &AndroidMips64elMultilibs;
2044 if (MS->select(Flags, Result.SelectedMultilib)) {
2045 Result.Multilibs = *MS;
Simon Atanasyanb4abcc52016-06-22 20:00:50 +00002046 return true;
2047 }
2048 return false;
2049}
2050
2051static bool findMipsMuslMultilibs(const Multilib::flags_list &Flags,
2052 FilterNonExistent &NonExistent,
2053 DetectedMultilibs &Result) {
2054 // Musl toolchain multilibs
2055 MultilibSet MuslMipsMultilibs;
2056 {
2057 auto MArchMipsR2 = makeMultilib("")
2058 .osSuffix("/mips-r2-hard-musl")
2059 .flag("+EB")
2060 .flag("-EL")
2061 .flag("+march=mips32r2");
2062
2063 auto MArchMipselR2 = makeMultilib("/mipsel-r2-hard-musl")
2064 .flag("-EB")
2065 .flag("+EL")
2066 .flag("+march=mips32r2");
2067
2068 MuslMipsMultilibs = MultilibSet().Either(MArchMipsR2, MArchMipselR2);
2069
2070 // Specify the callback that computes the include directories.
2071 MuslMipsMultilibs.setIncludeDirsCallback([](const Multilib &M) {
2072 return std::vector<std::string>(
2073 {"/../sysroot" + M.osSuffix() + "/usr/include"});
2074 });
2075 }
2076 if (MuslMipsMultilibs.select(Flags, Result.SelectedMultilib)) {
2077 Result.Multilibs = MuslMipsMultilibs;
2078 return true;
2079 }
2080 return false;
2081}
2082
2083static bool findMipsMtiMultilibs(const Multilib::flags_list &Flags,
2084 FilterNonExistent &NonExistent,
2085 DetectedMultilibs &Result) {
2086 // CodeScape MTI toolchain v1.2 and early.
Simon Atanasyancf7ac672016-05-22 15:27:58 +00002087 MultilibSet MtiMipsMultilibsV1;
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002088 {
Simon Atanasyan1b0542e2014-07-30 09:15:10 +00002089 auto MArchMips32 = makeMultilib("/mips32")
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002090 .flag("+m32")
2091 .flag("-m64")
2092 .flag("-mmicromips")
2093 .flag("+march=mips32");
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002094
Simon Atanasyan1b0542e2014-07-30 09:15:10 +00002095 auto MArchMicroMips = makeMultilib("/micromips")
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002096 .flag("+m32")
2097 .flag("-m64")
2098 .flag("+mmicromips");
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002099
Simon Atanasyan1b0542e2014-07-30 09:15:10 +00002100 auto MArchMips64r2 = makeMultilib("/mips64r2")
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002101 .flag("-m32")
2102 .flag("+m64")
2103 .flag("+march=mips64r2");
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002104
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002105 auto MArchMips64 = makeMultilib("/mips64").flag("-m32").flag("+m64").flag(
2106 "-march=mips64r2");
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002107
Simon Atanasyan1b0542e2014-07-30 09:15:10 +00002108 auto MArchDefault = makeMultilib("")
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002109 .flag("+m32")
2110 .flag("-m64")
2111 .flag("-mmicromips")
2112 .flag("+march=mips32r2");
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002113
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002114 auto Mips16 = makeMultilib("/mips16").flag("+mips16");
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002115
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002116 auto UCLibc = makeMultilib("/uclibc").flag("+muclibc");
Simon Atanasyand95c67d2014-08-13 14:34:14 +00002117
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002118 auto MAbi64 =
2119 makeMultilib("/64").flag("+mabi=n64").flag("-mabi=n32").flag("-m32");
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002120
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002121 auto BigEndian = makeMultilib("").flag("+EB").flag("-EL");
Simon Atanasyan738f85a2014-03-04 18:37:28 +00002122
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002123 auto LittleEndian = makeMultilib("/el").flag("+EL").flag("-EB");
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002124
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002125 auto SoftFloat = makeMultilib("/sof").flag("+msoft-float");
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002126
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002127 auto Nan2008 = makeMultilib("/nan2008").flag("+mnan=2008");
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002128
Simon Atanasyancf7ac672016-05-22 15:27:58 +00002129 MtiMipsMultilibsV1 =
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002130 MultilibSet()
2131 .Either(MArchMips32, MArchMicroMips, MArchMips64r2, MArchMips64,
2132 MArchDefault)
2133 .Maybe(UCLibc)
2134 .Maybe(Mips16)
2135 .FilterOut("/mips64/mips16")
2136 .FilterOut("/mips64r2/mips16")
2137 .FilterOut("/micromips/mips16")
2138 .Maybe(MAbi64)
2139 .FilterOut("/micromips/64")
2140 .FilterOut("/mips32/64")
2141 .FilterOut("^/64")
2142 .FilterOut("/mips16/64")
2143 .Either(BigEndian, LittleEndian)
2144 .Maybe(SoftFloat)
2145 .Maybe(Nan2008)
2146 .FilterOut(".*sof/nan2008")
2147 .FilterOut(NonExistent)
Simon Atanasyana45502d2016-05-19 15:07:21 +00002148 .setIncludeDirsCallback([](const Multilib &M) {
2149 std::vector<std::string> Dirs({"/include"});
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002150 if (StringRef(M.includeSuffix()).startswith("/uclibc"))
Simon Atanasyana45502d2016-05-19 15:07:21 +00002151 Dirs.push_back("/../../../../sysroot/uclibc/usr/include");
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002152 else
Simon Atanasyana45502d2016-05-19 15:07:21 +00002153 Dirs.push_back("/../../../../sysroot/usr/include");
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002154 return Dirs;
2155 });
Simon Atanasyan13e965a2013-11-26 11:57:14 +00002156 }
2157
Simon Atanasyanb4abcc52016-06-22 20:00:50 +00002158 // CodeScape IMG toolchain starting from v1.3.
Simon Atanasyan2834a222016-05-22 18:18:07 +00002159 MultilibSet MtiMipsMultilibsV2;
2160 {
2161 auto BeHard = makeMultilib("/mips-r2-hard")
2162 .flag("+EB")
2163 .flag("-msoft-float")
2164 .flag("-mnan=2008")
2165 .flag("-muclibc");
2166 auto BeSoft = makeMultilib("/mips-r2-soft")
2167 .flag("+EB")
2168 .flag("+msoft-float")
2169 .flag("-mnan=2008");
2170 auto ElHard = makeMultilib("/mipsel-r2-hard")
2171 .flag("+EL")
2172 .flag("-msoft-float")
2173 .flag("-mnan=2008")
2174 .flag("-muclibc");
2175 auto ElSoft = makeMultilib("/mipsel-r2-soft")
2176 .flag("+EL")
2177 .flag("+msoft-float")
2178 .flag("-mnan=2008")
2179 .flag("-mmicromips");
2180 auto BeHardNan = makeMultilib("/mips-r2-hard-nan2008")
2181 .flag("+EB")
2182 .flag("-msoft-float")
2183 .flag("+mnan=2008")
2184 .flag("-muclibc");
2185 auto ElHardNan = makeMultilib("/mipsel-r2-hard-nan2008")
2186 .flag("+EL")
2187 .flag("-msoft-float")
2188 .flag("+mnan=2008")
2189 .flag("-muclibc")
2190 .flag("-mmicromips");
2191 auto BeHardNanUclibc = makeMultilib("/mips-r2-hard-nan2008-uclibc")
2192 .flag("+EB")
2193 .flag("-msoft-float")
2194 .flag("+mnan=2008")
2195 .flag("+muclibc");
2196 auto ElHardNanUclibc = makeMultilib("/mipsel-r2-hard-nan2008-uclibc")
2197 .flag("+EL")
2198 .flag("-msoft-float")
2199 .flag("+mnan=2008")
2200 .flag("+muclibc");
2201 auto BeHardUclibc = makeMultilib("/mips-r2-hard-uclibc")
2202 .flag("+EB")
2203 .flag("-msoft-float")
2204 .flag("-mnan=2008")
2205 .flag("+muclibc");
2206 auto ElHardUclibc = makeMultilib("/mipsel-r2-hard-uclibc")
2207 .flag("+EL")
2208 .flag("-msoft-float")
2209 .flag("-mnan=2008")
2210 .flag("+muclibc");
2211 auto ElMicroHardNan = makeMultilib("/micromipsel-r2-hard-nan2008")
2212 .flag("+EL")
2213 .flag("-msoft-float")
2214 .flag("+mnan=2008")
2215 .flag("+mmicromips");
2216 auto ElMicroSoft = makeMultilib("/micromipsel-r2-soft")
2217 .flag("+EL")
2218 .flag("+msoft-float")
2219 .flag("-mnan=2008")
2220 .flag("+mmicromips");
2221
2222 auto O32 =
2223 makeMultilib("/lib").osSuffix("").flag("-mabi=n32").flag("-mabi=n64");
2224 auto N32 =
2225 makeMultilib("/lib32").osSuffix("").flag("+mabi=n32").flag("-mabi=n64");
2226 auto N64 =
2227 makeMultilib("/lib64").osSuffix("").flag("-mabi=n32").flag("+mabi=n64");
2228
2229 MtiMipsMultilibsV2 =
2230 MultilibSet()
2231 .Either({BeHard, BeSoft, ElHard, ElSoft, BeHardNan, ElHardNan,
2232 BeHardNanUclibc, ElHardNanUclibc, BeHardUclibc,
2233 ElHardUclibc, ElMicroHardNan, ElMicroSoft})
2234 .Either(O32, N32, N64)
2235 .FilterOut(NonExistent)
2236 .setIncludeDirsCallback([](const Multilib &M) {
2237 return std::vector<std::string>({"/../../../../sysroot" +
2238 M.includeSuffix() +
2239 "/../usr/include"});
2240 })
2241 .setFilePathsCallback([](const Multilib &M) {
2242 return std::vector<std::string>(
2243 {"/../../../../mips-mti-linux-gnu/lib" + M.gccSuffix()});
2244 });
2245 }
Simon Atanasyanb4abcc52016-06-22 20:00:50 +00002246 for (auto Candidate : {&MtiMipsMultilibsV1, &MtiMipsMultilibsV2}) {
2247 if (Candidate->select(Flags, Result.SelectedMultilib)) {
2248 Result.Multilibs = *Candidate;
2249 return true;
2250 }
Vasileios Kalintirisc744e122015-11-12 15:26:54 +00002251 }
Simon Atanasyanb4abcc52016-06-22 20:00:50 +00002252 return false;
2253}
Vasileios Kalintirisc744e122015-11-12 15:26:54 +00002254
Simon Atanasyanb4abcc52016-06-22 20:00:50 +00002255static bool findMipsImgMultilibs(const Multilib::flags_list &Flags,
2256 FilterNonExistent &NonExistent,
2257 DetectedMultilibs &Result) {
2258 // CodeScape IMG toolchain v1.2 and early.
Simon Atanasyancf7ac672016-05-22 15:27:58 +00002259 MultilibSet ImgMultilibsV1;
Daniel Sanders2bf13662014-07-10 14:40:57 +00002260 {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002261 auto Mips64r6 = makeMultilib("/mips64r6").flag("+m64").flag("-m32");
Daniel Sanders2bf13662014-07-10 14:40:57 +00002262
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002263 auto LittleEndian = makeMultilib("/el").flag("+EL").flag("-EB");
Daniel Sanders2bf13662014-07-10 14:40:57 +00002264
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002265 auto MAbi64 =
2266 makeMultilib("/64").flag("+mabi=n64").flag("-mabi=n32").flag("-m32");
Daniel Sanders2bf13662014-07-10 14:40:57 +00002267
Simon Atanasyancf7ac672016-05-22 15:27:58 +00002268 ImgMultilibsV1 =
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002269 MultilibSet()
2270 .Maybe(Mips64r6)
2271 .Maybe(MAbi64)
2272 .Maybe(LittleEndian)
2273 .FilterOut(NonExistent)
Simon Atanasyana45502d2016-05-19 15:07:21 +00002274 .setIncludeDirsCallback([](const Multilib &M) {
2275 return std::vector<std::string>(
2276 {"/include", "/../../../../sysroot/usr/include"});
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002277 });
Daniel Sanders2bf13662014-07-10 14:40:57 +00002278 }
2279
Simon Atanasyanb4abcc52016-06-22 20:00:50 +00002280 // CodeScape IMG toolchain starting from v1.3.
Simon Atanasyan2834a222016-05-22 18:18:07 +00002281 MultilibSet ImgMultilibsV2;
2282 {
2283 auto BeHard = makeMultilib("/mips-r6-hard")
2284 .flag("+EB")
2285 .flag("-msoft-float")
2286 .flag("-mmicromips");
2287 auto BeSoft = makeMultilib("/mips-r6-soft")
2288 .flag("+EB")
2289 .flag("+msoft-float")
2290 .flag("-mmicromips");
2291 auto ElHard = makeMultilib("/mipsel-r6-hard")
2292 .flag("+EL")
2293 .flag("-msoft-float")
2294 .flag("-mmicromips");
2295 auto ElSoft = makeMultilib("/mipsel-r6-soft")
2296 .flag("+EL")
2297 .flag("+msoft-float")
2298 .flag("-mmicromips");
2299 auto BeMicroHard = makeMultilib("/micromips-r6-hard")
Simon Atanasyan6c51f5a2016-05-22 18:18:41 +00002300 .flag("+EB")
2301 .flag("-msoft-float")
2302 .flag("+mmicromips");
Simon Atanasyan2834a222016-05-22 18:18:07 +00002303 auto BeMicroSoft = makeMultilib("/micromips-r6-soft")
Simon Atanasyan6c51f5a2016-05-22 18:18:41 +00002304 .flag("+EB")
2305 .flag("+msoft-float")
2306 .flag("+mmicromips");
Simon Atanasyan2834a222016-05-22 18:18:07 +00002307 auto ElMicroHard = makeMultilib("/micromipsel-r6-hard")
Simon Atanasyan6c51f5a2016-05-22 18:18:41 +00002308 .flag("+EL")
2309 .flag("-msoft-float")
2310 .flag("+mmicromips");
Simon Atanasyan2834a222016-05-22 18:18:07 +00002311 auto ElMicroSoft = makeMultilib("/micromipsel-r6-soft")
Simon Atanasyan6c51f5a2016-05-22 18:18:41 +00002312 .flag("+EL")
2313 .flag("+msoft-float")
2314 .flag("+mmicromips");
Simon Atanasyan2834a222016-05-22 18:18:07 +00002315
2316 auto O32 =
2317 makeMultilib("/lib").osSuffix("").flag("-mabi=n32").flag("-mabi=n64");
2318 auto N32 =
2319 makeMultilib("/lib32").osSuffix("").flag("+mabi=n32").flag("-mabi=n64");
2320 auto N64 =
2321 makeMultilib("/lib64").osSuffix("").flag("-mabi=n32").flag("+mabi=n64");
2322
Simon Atanasyan6c51f5a2016-05-22 18:18:41 +00002323 ImgMultilibsV2 =
2324 MultilibSet()
2325 .Either({BeHard, BeSoft, ElHard, ElSoft, BeMicroHard, BeMicroSoft,
2326 ElMicroHard, ElMicroSoft})
2327 .Either(O32, N32, N64)
2328 .FilterOut(NonExistent)
2329 .setIncludeDirsCallback([](const Multilib &M) {
2330 return std::vector<std::string>({"/../../../../sysroot" +
2331 M.includeSuffix() +
2332 "/../usr/include"});
2333 })
2334 .setFilePathsCallback([](const Multilib &M) {
2335 return std::vector<std::string>(
2336 {"/../../../../mips-img-linux-gnu/lib" + M.gccSuffix()});
2337 });
Simon Atanasyan2834a222016-05-22 18:18:07 +00002338 }
Simon Atanasyanb4abcc52016-06-22 20:00:50 +00002339 for (auto Candidate : {&ImgMultilibsV1, &ImgMultilibsV2}) {
2340 if (Candidate->select(Flags, Result.SelectedMultilib)) {
2341 Result.Multilibs = *Candidate;
2342 return true;
2343 }
2344 }
2345 return false;
2346}
2347
2348static bool findMIPSMultilibs(const Driver &D, const llvm::Triple &TargetTriple,
2349 StringRef Path, const ArgList &Args,
2350 DetectedMultilibs &Result) {
2351 FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());
Simon Atanasyan2834a222016-05-22 18:18:07 +00002352
Simon Atanasyan7018e1d2014-07-16 12:29:22 +00002353 StringRef CPUName;
2354 StringRef ABIName;
2355 tools::mips::getMipsCPUAndABI(Args, TargetTriple, CPUName, ABIName);
2356
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002357 llvm::Triple::ArchType TargetArch = TargetTriple.getArch();
2358
2359 Multilib::flags_list Flags;
2360 addMultilibFlag(isMips32(TargetArch), "m32", Flags);
2361 addMultilibFlag(isMips64(TargetArch), "m64", Flags);
2362 addMultilibFlag(isMips16(Args), "mips16", Flags);
Simon Atanasyan9988e3a2014-07-16 17:34:54 +00002363 addMultilibFlag(CPUName == "mips32", "march=mips32", Flags);
Simon Atanasyan59b25cb2015-02-26 04:45:57 +00002364 addMultilibFlag(CPUName == "mips32r2" || CPUName == "mips32r3" ||
Daniel Sandersff952582015-10-05 12:24:30 +00002365 CPUName == "mips32r5" || CPUName == "p5600",
Simon Atanasyan59b25cb2015-02-26 04:45:57 +00002366 "march=mips32r2", Flags);
Simon Atanasyan3f024032015-02-25 07:31:12 +00002367 addMultilibFlag(CPUName == "mips32r6", "march=mips32r6", Flags);
Simon Atanasyan9988e3a2014-07-16 17:34:54 +00002368 addMultilibFlag(CPUName == "mips64", "march=mips64", Flags);
Simon Atanasyan59b25cb2015-02-26 04:45:57 +00002369 addMultilibFlag(CPUName == "mips64r2" || CPUName == "mips64r3" ||
2370 CPUName == "mips64r5" || CPUName == "octeon",
Simon Atanasyan9988e3a2014-07-16 17:34:54 +00002371 "march=mips64r2", Flags);
Simon Atanasyan603018a2016-07-19 07:09:48 +00002372 addMultilibFlag(CPUName == "mips64r6", "march=mips64r6", Flags);
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002373 addMultilibFlag(isMicroMips(Args), "mmicromips", Flags);
Simon Atanasyand95c67d2014-08-13 14:34:14 +00002374 addMultilibFlag(tools::mips::isUCLibc(Args), "muclibc", Flags);
Simon Atanasyanab6db9f2014-07-16 12:24:48 +00002375 addMultilibFlag(tools::mips::isNaN2008(Args, TargetTriple), "mnan=2008",
2376 Flags);
Simon Atanasyan7018e1d2014-07-16 12:29:22 +00002377 addMultilibFlag(ABIName == "n32", "mabi=n32", Flags);
2378 addMultilibFlag(ABIName == "n64", "mabi=n64", Flags);
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002379 addMultilibFlag(isSoftFloatABI(Args), "msoft-float", Flags);
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002380 addMultilibFlag(!isSoftFloatABI(Args), "mhard-float", Flags);
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002381 addMultilibFlag(isMipsEL(TargetArch), "EL", Flags);
Simon Atanasyan7018e1d2014-07-16 12:29:22 +00002382 addMultilibFlag(!isMipsEL(TargetArch), "EB", Flags);
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002383
Simon Atanasyanb4abcc52016-06-22 20:00:50 +00002384 if (TargetTriple.isAndroid())
Simon Atanasyan603018a2016-07-19 07:09:48 +00002385 return findMipsAndroidMultilibs(D.getVFS(), Path, Flags, NonExistent,
2386 Result);
Simon Atanasyan738f85a2014-03-04 18:37:28 +00002387
Vasileios Kalintirisc744e122015-11-12 15:26:54 +00002388 if (TargetTriple.getVendor() == llvm::Triple::MipsTechnologies &&
2389 TargetTriple.getOS() == llvm::Triple::Linux &&
Simon Atanasyanb4abcc52016-06-22 20:00:50 +00002390 TargetTriple.getEnvironment() == llvm::Triple::UnknownEnvironment)
2391 return findMipsMuslMultilibs(Flags, NonExistent, Result);
Vasileios Kalintirisc744e122015-11-12 15:26:54 +00002392
Simon Atanasyan4f3fe5b2016-05-22 15:28:34 +00002393 if (TargetTriple.getVendor() == llvm::Triple::MipsTechnologies &&
2394 TargetTriple.getOS() == llvm::Triple::Linux &&
Simon Atanasyanb4abcc52016-06-22 20:00:50 +00002395 TargetTriple.getEnvironment() == llvm::Triple::GNU)
2396 return findMipsMtiMultilibs(Flags, NonExistent, Result);
Simon Atanasyan4f3fe5b2016-05-22 15:28:34 +00002397
Daniel Sanders2bf13662014-07-10 14:40:57 +00002398 if (TargetTriple.getVendor() == llvm::Triple::ImaginationTechnologies &&
2399 TargetTriple.getOS() == llvm::Triple::Linux &&
Simon Atanasyanb4abcc52016-06-22 20:00:50 +00002400 TargetTriple.getEnvironment() == llvm::Triple::GNU)
2401 return findMipsImgMultilibs(Flags, NonExistent, Result);
Daniel Sanders2bf13662014-07-10 14:40:57 +00002402
Simon Atanasyanb4abcc52016-06-22 20:00:50 +00002403 if (findMipsCsMultilibs(Flags, NonExistent, Result))
2404 return true;
Simon Atanasyan738f85a2014-03-04 18:37:28 +00002405
Simon Atanasyanb4abcc52016-06-22 20:00:50 +00002406 // Fallback to the regular toolchain-tree structure.
2407 Multilib Default;
2408 Result.Multilibs.push_back(Default);
2409 Result.Multilibs.FilterOut(NonExistent);
Simon Atanasyan3a46afa2014-06-24 19:00:12 +00002410
Simon Atanasyanb4abcc52016-06-22 20:00:50 +00002411 if (Result.Multilibs.select(Flags, Result.SelectedMultilib)) {
2412 Result.BiarchSibling = Multilib();
2413 return true;
Simon Atanasyan3a46afa2014-06-24 19:00:12 +00002414 }
2415
Simon Atanasyan738f85a2014-03-04 18:37:28 +00002416 return false;
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002417}
2418
Chih-Hung Hsiehb4d3bf72016-06-01 20:48:46 +00002419static void findAndroidArmMultilibs(const Driver &D,
2420 const llvm::Triple &TargetTriple,
2421 StringRef Path, const ArgList &Args,
2422 DetectedMultilibs &Result) {
2423 // Find multilibs with subdirectories like armv7-a, thumb, armv7-a/thumb.
Andrey Turetskiy4798eb62016-06-16 10:36:09 +00002424 FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());
Chih-Hung Hsiehb4d3bf72016-06-01 20:48:46 +00002425 Multilib ArmV7Multilib = makeMultilib("/armv7-a")
2426 .flag("+armv7")
2427 .flag("-thumb");
2428 Multilib ThumbMultilib = makeMultilib("/thumb")
2429 .flag("-armv7")
2430 .flag("+thumb");
2431 Multilib ArmV7ThumbMultilib = makeMultilib("/armv7-a/thumb")
2432 .flag("+armv7")
2433 .flag("+thumb");
2434 Multilib DefaultMultilib = makeMultilib("")
2435 .flag("-armv7")
2436 .flag("-thumb");
2437 MultilibSet AndroidArmMultilibs =
2438 MultilibSet()
2439 .Either(ThumbMultilib, ArmV7Multilib,
2440 ArmV7ThumbMultilib, DefaultMultilib)
2441 .FilterOut(NonExistent);
2442
2443 Multilib::flags_list Flags;
2444 llvm::StringRef Arch = Args.getLastArgValue(options::OPT_march_EQ);
2445 bool IsArmArch = TargetTriple.getArch() == llvm::Triple::arm;
2446 bool IsThumbArch = TargetTriple.getArch() == llvm::Triple::thumb;
2447 bool IsV7SubArch = TargetTriple.getSubArch() == llvm::Triple::ARMSubArch_v7;
2448 bool IsThumbMode = IsThumbArch ||
2449 Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, false) ||
2450 (IsArmArch && llvm::ARM::parseArchISA(Arch) == llvm::ARM::IK_THUMB);
2451 bool IsArmV7Mode = (IsArmArch || IsThumbArch) &&
2452 (llvm::ARM::parseArchVersion(Arch) == 7 ||
2453 (IsArmArch && Arch == "" && IsV7SubArch));
2454 addMultilibFlag(IsArmV7Mode, "armv7", Flags);
2455 addMultilibFlag(IsThumbMode, "thumb", Flags);
2456
2457 if (AndroidArmMultilibs.select(Flags, Result.SelectedMultilib))
2458 Result.Multilibs = AndroidArmMultilibs;
2459}
2460
Benjamin Kramerc5862f02015-10-09 13:03:18 +00002461static bool findBiarchMultilibs(const Driver &D,
2462 const llvm::Triple &TargetTriple,
Simon Atanasyan60280b42014-05-12 07:37:51 +00002463 StringRef Path, const ArgList &Args,
2464 bool NeedsBiarchSuffix,
2465 DetectedMultilibs &Result) {
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002466 // Some versions of SUSE and Fedora on ppc64 put 32-bit libs
2467 // in what would normally be GCCInstallPath and put the 64-bit
2468 // libs in a subdirectory named 64. The simple logic we follow is that
2469 // *if* there is a subdirectory of the right name with crtbegin.o in it,
2470 // we use that. If not, and if not a biarch triple alias, we look for
2471 // crtbegin.o without the subdirectory.
2472
2473 Multilib Default;
2474 Multilib Alt64 = Multilib()
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002475 .gccSuffix("/64")
2476 .includeSuffix("/64")
2477 .flag("-m32")
2478 .flag("+m64")
2479 .flag("-mx32");
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002480 Multilib Alt32 = Multilib()
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002481 .gccSuffix("/32")
2482 .includeSuffix("/32")
2483 .flag("+m32")
2484 .flag("-m64")
2485 .flag("-mx32");
Zinovy Nis1db95732014-07-10 15:27:19 +00002486 Multilib Altx32 = Multilib()
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002487 .gccSuffix("/x32")
2488 .includeSuffix("/x32")
2489 .flag("-m32")
2490 .flag("-m64")
2491 .flag("+mx32");
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002492
Andrey Turetskiy4798eb62016-06-16 10:36:09 +00002493 // GCC toolchain for IAMCU doesn't have crtbegin.o, so look for libgcc.a.
2494 FilterNonExistent NonExistent(
2495 Path, TargetTriple.isOSIAMCU() ? "/libgcc.a" : "/crtbegin.o", D.getVFS());
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002496
Zinovy Nis1db95732014-07-10 15:27:19 +00002497 // Determine default multilib from: 32, 64, x32
2498 // Also handle cases such as 64 on 32, 32 on 64, etc.
2499 enum { UNKNOWN, WANT32, WANT64, WANTX32 } Want = UNKNOWN;
David Blaikie40f842d2014-07-10 18:46:15 +00002500 const bool IsX32 = TargetTriple.getEnvironment() == llvm::Triple::GNUX32;
Alp Tokerf45fa3d2014-02-25 04:21:44 +00002501 if (TargetTriple.isArch32Bit() && !NonExistent(Alt32))
Zinovy Nis1db95732014-07-10 15:27:19 +00002502 Want = WANT64;
Zinovy Nis6e3c6302014-07-10 15:42:35 +00002503 else if (TargetTriple.isArch64Bit() && IsX32 && !NonExistent(Altx32))
Zinovy Nis1db95732014-07-10 15:27:19 +00002504 Want = WANT64;
Zinovy Nis6e3c6302014-07-10 15:42:35 +00002505 else if (TargetTriple.isArch64Bit() && !IsX32 && !NonExistent(Alt64))
Zinovy Nis1db95732014-07-10 15:27:19 +00002506 Want = WANT32;
Jonathan Roelofs3fa96d82014-02-12 01:36:51 +00002507 else {
Zinovy Nis1db95732014-07-10 15:27:19 +00002508 if (TargetTriple.isArch32Bit())
2509 Want = NeedsBiarchSuffix ? WANT64 : WANT32;
Zinovy Nis6e3c6302014-07-10 15:42:35 +00002510 else if (IsX32)
Zinovy Nis1db95732014-07-10 15:27:19 +00002511 Want = NeedsBiarchSuffix ? WANT64 : WANTX32;
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002512 else
Zinovy Nis1db95732014-07-10 15:27:19 +00002513 Want = NeedsBiarchSuffix ? WANT32 : WANT64;
Jonathan Roelofs0e7ec602014-02-12 01:29:25 +00002514 }
2515
Zinovy Nis1db95732014-07-10 15:27:19 +00002516 if (Want == WANT32)
2517 Default.flag("+m32").flag("-m64").flag("-mx32");
2518 else if (Want == WANT64)
2519 Default.flag("-m32").flag("+m64").flag("-mx32");
2520 else if (Want == WANTX32)
2521 Default.flag("-m32").flag("-m64").flag("+mx32");
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002522 else
Zinovy Nis1db95732014-07-10 15:27:19 +00002523 return false;
Jonathan Roelofs3fa96d82014-02-12 01:36:51 +00002524
Simon Atanasyan60280b42014-05-12 07:37:51 +00002525 Result.Multilibs.push_back(Default);
2526 Result.Multilibs.push_back(Alt64);
2527 Result.Multilibs.push_back(Alt32);
Zinovy Nis1db95732014-07-10 15:27:19 +00002528 Result.Multilibs.push_back(Altx32);
Jonathan Roelofs3fa96d82014-02-12 01:36:51 +00002529
Simon Atanasyan60280b42014-05-12 07:37:51 +00002530 Result.Multilibs.FilterOut(NonExistent);
Jonathan Roelofs3fa96d82014-02-12 01:36:51 +00002531
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002532 Multilib::flags_list Flags;
Zinovy Nis6e3c6302014-07-10 15:42:35 +00002533 addMultilibFlag(TargetTriple.isArch64Bit() && !IsX32, "m64", Flags);
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002534 addMultilibFlag(TargetTriple.isArch32Bit(), "m32", Flags);
Zinovy Nis6e3c6302014-07-10 15:42:35 +00002535 addMultilibFlag(TargetTriple.isArch64Bit() && IsX32, "mx32", Flags);
Jonathan Roelofs3fa96d82014-02-12 01:36:51 +00002536
Simon Atanasyan60280b42014-05-12 07:37:51 +00002537 if (!Result.Multilibs.select(Flags, Result.SelectedMultilib))
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002538 return false;
Jonathan Roelofs3fa96d82014-02-12 01:36:51 +00002539
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002540 if (Result.SelectedMultilib == Alt64 || Result.SelectedMultilib == Alt32 ||
Zinovy Nis1db95732014-07-10 15:27:19 +00002541 Result.SelectedMultilib == Altx32)
Simon Atanasyan60280b42014-05-12 07:37:51 +00002542 Result.BiarchSibling = Default;
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002543
2544 return true;
Simon Atanasyan08450bd2013-04-20 08:15:03 +00002545}
2546
Rafael Espindolac53c5b12015-08-31 19:17:51 +00002547void Generic_GCC::GCCInstallationDetector::scanLibDirForGCCTripleSolaris(
2548 const llvm::Triple &TargetArch, const llvm::opt::ArgList &Args,
2549 const std::string &LibDir, StringRef CandidateTriple,
2550 bool NeedsBiarchSuffix) {
2551 // Solaris is a special case. The GCC installation is under
2552 // /usr/gcc/<major>.<minor>/lib/gcc/<triple>/<major>.<minor>.<patch>/, so we
2553 // need to iterate twice.
2554 std::error_code EC;
Benjamin Kramerd45b2052015-10-07 15:48:01 +00002555 for (vfs::directory_iterator LI = D.getVFS().dir_begin(LibDir, EC), LE;
2556 !EC && LI != LE; LI = LI.increment(EC)) {
2557 StringRef VersionText = llvm::sys::path::filename(LI->getName());
Rafael Espindolac53c5b12015-08-31 19:17:51 +00002558 GCCVersion CandidateVersion = GCCVersion::Parse(VersionText);
2559
2560 if (CandidateVersion.Major != -1) // Filter obviously bad entries.
Benjamin Kramerd45b2052015-10-07 15:48:01 +00002561 if (!CandidateGCCInstallPaths.insert(LI->getName()).second)
Rafael Espindolac53c5b12015-08-31 19:17:51 +00002562 continue; // Saw this path before; no need to look at it again.
2563 if (CandidateVersion.isOlderThan(4, 1, 1))
2564 continue;
2565 if (CandidateVersion <= Version)
2566 continue;
2567
2568 GCCInstallPath =
2569 LibDir + "/" + VersionText.str() + "/lib/gcc/" + CandidateTriple.str();
Benjamin Kramerd45b2052015-10-07 15:48:01 +00002570 if (!D.getVFS().exists(GCCInstallPath))
Rafael Espindolac53c5b12015-08-31 19:17:51 +00002571 continue;
2572
2573 // If we make it here there has to be at least one GCC version, let's just
2574 // use the latest one.
2575 std::error_code EEC;
Benjamin Kramerd45b2052015-10-07 15:48:01 +00002576 for (vfs::directory_iterator
2577 LLI = D.getVFS().dir_begin(GCCInstallPath, EEC),
2578 LLE;
Rafael Espindolac53c5b12015-08-31 19:17:51 +00002579 !EEC && LLI != LLE; LLI = LLI.increment(EEC)) {
2580
Benjamin Kramerd45b2052015-10-07 15:48:01 +00002581 StringRef SubVersionText = llvm::sys::path::filename(LLI->getName());
Rafael Espindolac53c5b12015-08-31 19:17:51 +00002582 GCCVersion CandidateSubVersion = GCCVersion::Parse(SubVersionText);
2583
2584 if (CandidateSubVersion > Version)
2585 Version = CandidateSubVersion;
2586 }
2587
2588 GCCTriple.setTriple(CandidateTriple);
2589
2590 GCCInstallPath += "/" + Version.Text;
2591 GCCParentLibPath = GCCInstallPath + "/../../../../";
2592
2593 IsValid = true;
2594 }
2595}
2596
Chandler Carruth4c90fba2011-11-06 23:39:34 +00002597void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple(
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002598 const llvm::Triple &TargetTriple, const ArgList &Args,
Chandler Carruthb427c562013-06-22 11:35:51 +00002599 const std::string &LibDir, StringRef CandidateTriple,
2600 bool NeedsBiarchSuffix) {
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002601 llvm::Triple::ArchType TargetArch = TargetTriple.getArch();
Chandler Carruth4c90fba2011-11-06 23:39:34 +00002602 // There are various different suffixes involving the triple we
2603 // check for. We also record what is necessary to walk from each back
Douglas Katzmancb07d152015-08-14 15:52:12 +00002604 // up to the lib directory. Specifically, the number of "up" steps
2605 // in the second half of each row is 1 + the number of path separators
2606 // in the first half.
2607 const std::string LibAndInstallSuffixes[][2] = {
2608 {"/gcc/" + CandidateTriple.str(), "/../../.."},
2609
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002610 // Debian puts cross-compilers in gcc-cross
Douglas Katzmancb07d152015-08-14 15:52:12 +00002611 {"/gcc-cross/" + CandidateTriple.str(), "/../../.."},
2612
2613 {"/" + CandidateTriple.str() + "/gcc/" + CandidateTriple.str(),
2614 "/../../../.."},
Chandler Carruth4c90fba2011-11-06 23:39:34 +00002615
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002616 // The Freescale PPC SDK has the gcc libraries in
2617 // <sysroot>/usr/lib/<triple>/x.y.z so have a look there as well.
Douglas Katzmancb07d152015-08-14 15:52:12 +00002618 {"/" + CandidateTriple.str(), "/../.."},
Hal Finkelf3587912012-09-18 22:25:07 +00002619
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002620 // Ubuntu has a strange mis-matched pair of triples that this happens to
2621 // match.
2622 // FIXME: It may be worthwhile to generalize this and look for a second
2623 // triple.
Douglas Katzmancb07d152015-08-14 15:52:12 +00002624 {"/i386-linux-gnu/gcc/" + CandidateTriple.str(), "/../../../.."}};
2625
Rafael Espindolac53c5b12015-08-31 19:17:51 +00002626 if (TargetTriple.getOS() == llvm::Triple::Solaris) {
2627 scanLibDirForGCCTripleSolaris(TargetTriple, Args, LibDir, CandidateTriple,
2628 NeedsBiarchSuffix);
2629 return;
2630 }
2631
Chandler Carruth4c90fba2011-11-06 23:39:34 +00002632 // Only look at the final, weird Ubuntu suffix for i386-linux-gnu.
Douglas Katzmancb07d152015-08-14 15:52:12 +00002633 const unsigned NumLibSuffixes = (llvm::array_lengthof(LibAndInstallSuffixes) -
2634 (TargetArch != llvm::Triple::x86));
Chandler Carruth866faab2012-01-25 07:21:38 +00002635 for (unsigned i = 0; i < NumLibSuffixes; ++i) {
Douglas Katzmancb07d152015-08-14 15:52:12 +00002636 StringRef LibSuffix = LibAndInstallSuffixes[i][0];
Rafael Espindolac0809172014-06-12 14:02:15 +00002637 std::error_code EC;
Benjamin Kramerd45b2052015-10-07 15:48:01 +00002638 for (vfs::directory_iterator
2639 LI = D.getVFS().dir_begin(LibDir + LibSuffix, EC),
2640 LE;
Chandler Carruth4c90fba2011-11-06 23:39:34 +00002641 !EC && LI != LE; LI = LI.increment(EC)) {
Benjamin Kramerd45b2052015-10-07 15:48:01 +00002642 StringRef VersionText = llvm::sys::path::filename(LI->getName());
Chandler Carruth4c90fba2011-11-06 23:39:34 +00002643 GCCVersion CandidateVersion = GCCVersion::Parse(VersionText);
Benjamin Kramera97e4d12013-08-14 18:38:51 +00002644 if (CandidateVersion.Major != -1) // Filter obviously bad entries.
Benjamin Kramerd45b2052015-10-07 15:48:01 +00002645 if (!CandidateGCCInstallPaths.insert(LI->getName()).second)
Benjamin Kramera97e4d12013-08-14 18:38:51 +00002646 continue; // Saw this path before; no need to look at it again.
Benjamin Kramer604e8482013-08-09 17:17:48 +00002647 if (CandidateVersion.isOlderThan(4, 1, 1))
Chandler Carruth4c90fba2011-11-06 23:39:34 +00002648 continue;
2649 if (CandidateVersion <= Version)
2650 continue;
Hal Finkel221e11e2011-12-08 05:50:03 +00002651
Simon Atanasyan60280b42014-05-12 07:37:51 +00002652 DetectedMultilibs Detected;
Simon Atanasyanee1accf2013-09-28 13:45:11 +00002653
Chih-Hung Hsiehb4d3bf72016-06-01 20:48:46 +00002654 // Android standalone toolchain could have multilibs for ARM and Thumb.
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002655 // Debian mips multilibs behave more like the rest of the biarch ones,
2656 // so handle them there
Chih-Hung Hsiehb4d3bf72016-06-01 20:48:46 +00002657 if (isArmOrThumbArch(TargetArch) && TargetTriple.isAndroid()) {
2658 // It should also work without multilibs in a simplified toolchain.
2659 findAndroidArmMultilibs(D, TargetTriple, LI->getName(), Args, Detected);
2660 } else if (isMipsArch(TargetArch)) {
Benjamin Kramerc5862f02015-10-09 13:03:18 +00002661 if (!findMIPSMultilibs(D, TargetTriple, LI->getName(), Args, Detected))
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00002662 continue;
Benjamin Kramerc5862f02015-10-09 13:03:18 +00002663 } else if (!findBiarchMultilibs(D, TargetTriple, LI->getName(), Args,
Simon Atanasyan60280b42014-05-12 07:37:51 +00002664 NeedsBiarchSuffix, Detected)) {
Simon Atanasyanee1accf2013-09-28 13:45:11 +00002665 continue;
Simon Atanasyan60280b42014-05-12 07:37:51 +00002666 }
Chandler Carruth4c90fba2011-11-06 23:39:34 +00002667
Simon Atanasyan60280b42014-05-12 07:37:51 +00002668 Multilibs = Detected.Multilibs;
2669 SelectedMultilib = Detected.SelectedMultilib;
2670 BiarchSibling = Detected.BiarchSibling;
Chandler Carruth4c90fba2011-11-06 23:39:34 +00002671 Version = CandidateVersion;
Chandler Carruth4d9d7682012-01-24 19:28:29 +00002672 GCCTriple.setTriple(CandidateTriple);
Chandler Carruth4c90fba2011-11-06 23:39:34 +00002673 // FIXME: We hack together the directory name here instead of
2674 // using LI to ensure stable path separators across Windows and
2675 // Linux.
Douglas Katzmancb07d152015-08-14 15:52:12 +00002676 GCCInstallPath =
2677 LibDir + LibAndInstallSuffixes[i][0] + "/" + VersionText.str();
2678 GCCParentLibPath = GCCInstallPath + LibAndInstallSuffixes[i][1];
Chandler Carruth4c90fba2011-11-06 23:39:34 +00002679 IsValid = true;
2680 }
2681 }
2682}
2683
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002684Generic_GCC::Generic_GCC(const Driver &D, const llvm::Triple &Triple,
Rafael Espindola1af7c212012-02-19 01:38:32 +00002685 const ArgList &Args)
Benjamin Kramerd45b2052015-10-07 15:48:01 +00002686 : ToolChain(D, Triple, Args), GCCInstallation(D), CudaInstallation(D) {
Daniel Dunbar88979912010-08-01 22:29:51 +00002687 getProgramPaths().push_back(getDriver().getInstalledDir());
Benjamin Kramer51477bd2011-03-01 22:50:47 +00002688 if (getDriver().getInstalledDir() != getDriver().Dir)
Daniel Dunbar88979912010-08-01 22:29:51 +00002689 getProgramPaths().push_back(getDriver().Dir);
Daniel Dunbar76ce7412009-03-23 16:15:50 +00002690}
2691
Angel Garcia Gomez637d1e62015-10-20 13:23:58 +00002692Generic_GCC::~Generic_GCC() {}
Daniel Dunbar59e5e882009-03-20 00:20:03 +00002693
Rafael Espindola7cf32212013-03-20 03:05:54 +00002694Tool *Generic_GCC::getTool(Action::ActionClass AC) const {
Rafael Espindola260e28d2013-03-18 20:48:54 +00002695 switch (AC) {
Rafael Espindolac8e3a012013-03-18 18:50:01 +00002696 case Action::PreprocessJobClass:
Rafael Espindola7cf32212013-03-20 03:05:54 +00002697 if (!Preprocess)
Douglas Katzman95354292015-06-23 20:42:09 +00002698 Preprocess.reset(new tools::gcc::Preprocessor(*this));
Rafael Espindola7cf32212013-03-20 03:05:54 +00002699 return Preprocess.get();
Rafael Espindolac8e3a012013-03-18 18:50:01 +00002700 case Action::CompileJobClass:
Rafael Espindola7cf32212013-03-20 03:05:54 +00002701 if (!Compile)
Douglas Katzman95354292015-06-23 20:42:09 +00002702 Compile.reset(new tools::gcc::Compiler(*this));
Rafael Espindola7cf32212013-03-20 03:05:54 +00002703 return Compile.get();
Rafael Espindolad15a8912013-03-19 00:36:57 +00002704 default:
Rafael Espindola7cf32212013-03-20 03:05:54 +00002705 return ToolChain::getTool(AC);
Daniel Dunbar59e5e882009-03-20 00:20:03 +00002706 }
Daniel Dunbar59e5e882009-03-20 00:20:03 +00002707}
2708
Rafael Espindola7cf32212013-03-20 03:05:54 +00002709Tool *Generic_GCC::buildAssembler() const {
Douglas Katzman95354292015-06-23 20:42:09 +00002710 return new tools::gnutools::Assembler(*this);
Rafael Espindola7cf32212013-03-20 03:05:54 +00002711}
2712
Douglas Katzman95354292015-06-23 20:42:09 +00002713Tool *Generic_GCC::buildLinker() const { return new tools::gcc::Linker(*this); }
Rafael Espindola7cf32212013-03-20 03:05:54 +00002714
Chandler Carruth0ae39aa2013-07-30 17:57:09 +00002715void Generic_GCC::printVerboseInfo(raw_ostream &OS) const {
2716 // Print the information about how we detected the GCC installation.
2717 GCCInstallation.print(OS);
Artem Belevich98607b62015-09-23 21:49:39 +00002718 CudaInstallation.print(OS);
Chandler Carruth0ae39aa2013-07-30 17:57:09 +00002719}
2720
Daniel Dunbar59e5e882009-03-20 00:20:03 +00002721bool Generic_GCC::IsUnwindTablesDefault() const {
Rafael Espindola08f1ebb2012-09-22 15:04:11 +00002722 return getArch() == llvm::Triple::x86_64;
Daniel Dunbar59e5e882009-03-20 00:20:03 +00002723}
2724
David Majnemer17f448b2015-06-28 04:23:33 +00002725bool Generic_GCC::isPICDefault() const {
2726 return getArch() == llvm::Triple::x86_64 && getTriple().isOSWindows();
2727}
Daniel Dunbar59e5e882009-03-20 00:20:03 +00002728
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002729bool Generic_GCC::isPIEDefault() const { return false; }
Peter Collingbourne54d770c2013-04-09 04:35:11 +00002730
David Majnemer17f448b2015-06-28 04:23:33 +00002731bool Generic_GCC::isPICDefaultForced() const {
2732 return getArch() == llvm::Triple::x86_64 && getTriple().isOSWindows();
2733}
Chandler Carruth76a943b2012-11-19 03:52:03 +00002734
Rafael Espindolaa8b3b682013-11-25 18:50:53 +00002735bool Generic_GCC::IsIntegratedAssemblerDefault() const {
Douglas Katzman7ae27b82015-06-03 19:40:30 +00002736 switch (getTriple().getArch()) {
2737 case llvm::Triple::x86:
2738 case llvm::Triple::x86_64:
2739 case llvm::Triple::aarch64:
2740 case llvm::Triple::aarch64_be:
2741 case llvm::Triple::arm:
2742 case llvm::Triple::armeb:
Alexei Starovoitovf657ca82015-06-10 22:59:13 +00002743 case llvm::Triple::bpfel:
2744 case llvm::Triple::bpfeb:
Douglas Katzman7ae27b82015-06-03 19:40:30 +00002745 case llvm::Triple::thumb:
2746 case llvm::Triple::thumbeb:
2747 case llvm::Triple::ppc:
2748 case llvm::Triple::ppc64:
2749 case llvm::Triple::ppc64le:
Douglas Katzman7ae27b82015-06-03 19:40:30 +00002750 case llvm::Triple::systemz:
Daniel Sanderse160f832016-05-14 12:43:08 +00002751 case llvm::Triple::mips:
2752 case llvm::Triple::mipsel:
Douglas Katzman7ae27b82015-06-03 19:40:30 +00002753 return true;
2754 default:
2755 return false;
2756 }
Rafael Espindolaa8b3b682013-11-25 18:50:53 +00002757}
2758
James Y Knighta6c9ee72015-10-16 18:46:26 +00002759/// \brief Helper to add the variant paths of a libstdc++ installation.
2760bool Generic_GCC::addLibStdCXXIncludePaths(
2761 Twine Base, Twine Suffix, StringRef GCCTriple, StringRef GCCMultiarchTriple,
2762 StringRef TargetMultiarchTriple, Twine IncludeSuffix,
2763 const ArgList &DriverArgs, ArgStringList &CC1Args) const {
2764 if (!getVFS().exists(Base + Suffix))
2765 return false;
2766
2767 addSystemInclude(DriverArgs, CC1Args, Base + Suffix);
2768
2769 // The vanilla GCC layout of libstdc++ headers uses a triple subdirectory. If
2770 // that path exists or we have neither a GCC nor target multiarch triple, use
2771 // this vanilla search path.
2772 if ((GCCMultiarchTriple.empty() && TargetMultiarchTriple.empty()) ||
2773 getVFS().exists(Base + Suffix + "/" + GCCTriple + IncludeSuffix)) {
2774 addSystemInclude(DriverArgs, CC1Args,
2775 Base + Suffix + "/" + GCCTriple + IncludeSuffix);
2776 } else {
2777 // Otherwise try to use multiarch naming schemes which have normalized the
2778 // triples and put the triple before the suffix.
2779 //
2780 // GCC surprisingly uses *both* the GCC triple with a multilib suffix and
2781 // the target triple, so we support that here.
2782 addSystemInclude(DriverArgs, CC1Args,
2783 Base + "/" + GCCMultiarchTriple + Suffix + IncludeSuffix);
2784 addSystemInclude(DriverArgs, CC1Args,
2785 Base + "/" + TargetMultiarchTriple + Suffix);
2786 }
2787
2788 addSystemInclude(DriverArgs, CC1Args, Base + Suffix + "/backward");
2789 return true;
2790}
2791
Kristof Beylsfb387292014-01-10 13:44:34 +00002792void Generic_ELF::addClangTargetOptions(const ArgList &DriverArgs,
2793 ArgStringList &CC1Args) const {
2794 const Generic_GCC::GCCVersion &V = GCCInstallation.getVersion();
Tim Northovera2ee4332014-03-29 15:09:45 +00002795 bool UseInitArrayDefault =
Kristof Beylsfb387292014-01-10 13:44:34 +00002796 getTriple().getArch() == llvm::Triple::aarch64 ||
Christian Pirker9b019ae2014-02-25 13:51:00 +00002797 getTriple().getArch() == llvm::Triple::aarch64_be ||
Tim Northovera2ee4332014-03-29 15:09:45 +00002798 (getTriple().getOS() == llvm::Triple::Linux &&
Evgeniy Stepanov14deb7b2015-10-08 21:21:44 +00002799 (!V.isOlderThan(4, 7, 0) || getTriple().isAndroid())) ||
Vasileios Kalintirisc744e122015-11-12 15:26:54 +00002800 getTriple().getOS() == llvm::Triple::NaCl ||
2801 (getTriple().getVendor() == llvm::Triple::MipsTechnologies &&
2802 !getTriple().hasEnvironment());
Kristof Beylsfb387292014-01-10 13:44:34 +00002803
2804 if (DriverArgs.hasFlag(options::OPT_fuse_init_array,
Douglas Katzmana67e50c2015-06-26 15:47:46 +00002805 options::OPT_fno_use_init_array, UseInitArrayDefault))
Kristof Beylsfb387292014-01-10 13:44:34 +00002806 CC1Args.push_back("-fuse-init-array");
2807}
2808
Vasileios Kalintirisc744e122015-11-12 15:26:54 +00002809/// Mips Toolchain
2810MipsLLVMToolChain::MipsLLVMToolChain(const Driver &D,
2811 const llvm::Triple &Triple,
2812 const ArgList &Args)
2813 : Linux(D, Triple, Args) {
2814 // Select the correct multilib according to the given arguments.
2815 DetectedMultilibs Result;
2816 findMIPSMultilibs(D, Triple, "", Args, Result);
2817 Multilibs = Result.Multilibs;
2818 SelectedMultilib = Result.SelectedMultilib;
2819
2820 // Find out the library suffix based on the ABI.
2821 LibSuffix = tools::mips::getMipsABILibSuffix(Args, Triple);
2822 getFilePaths().clear();
2823 getFilePaths().push_back(computeSysRoot() + "/usr/lib" + LibSuffix);
2824
2825 // Use LLD by default.
Peter Collingbourne39719a72015-11-20 20:49:39 +00002826 DefaultLinker = "lld";
Vasileios Kalintirisc744e122015-11-12 15:26:54 +00002827}
2828
2829void MipsLLVMToolChain::AddClangSystemIncludeArgs(
2830 const ArgList &DriverArgs, ArgStringList &CC1Args) const {
2831 if (DriverArgs.hasArg(options::OPT_nostdinc))
2832 return;
2833
2834 const Driver &D = getDriver();
2835
2836 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
2837 SmallString<128> P(D.ResourceDir);
2838 llvm::sys::path::append(P, "include");
2839 addSystemInclude(DriverArgs, CC1Args, P);
2840 }
2841
2842 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
2843 return;
2844
2845 const auto &Callback = Multilibs.includeDirsCallback();
2846 if (Callback) {
Simon Atanasyana45502d2016-05-19 15:07:21 +00002847 for (const auto &Path : Callback(SelectedMultilib))
2848 addExternCSystemIncludeIfExists(DriverArgs, CC1Args,
2849 D.getInstalledDir() + Path);
Vasileios Kalintirisc744e122015-11-12 15:26:54 +00002850 }
2851}
2852
2853Tool *MipsLLVMToolChain::buildLinker() const {
2854 return new tools::gnutools::Linker(*this);
2855}
2856
2857std::string MipsLLVMToolChain::computeSysRoot() const {
2858 if (!getDriver().SysRoot.empty())
2859 return getDriver().SysRoot + SelectedMultilib.osSuffix();
2860
2861 const std::string InstalledDir(getDriver().getInstalledDir());
2862 std::string SysRootPath =
2863 InstalledDir + "/../sysroot" + SelectedMultilib.osSuffix();
2864 if (llvm::sys::fs::exists(SysRootPath))
2865 return SysRootPath;
2866
2867 return std::string();
2868}
2869
2870ToolChain::CXXStdlibType
2871MipsLLVMToolChain::GetCXXStdlibType(const ArgList &Args) const {
2872 Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
2873 if (A) {
2874 StringRef Value = A->getValue();
2875 if (Value != "libc++")
2876 getDriver().Diag(diag::err_drv_invalid_stdlib_name)
2877 << A->getAsString(Args);
2878 }
2879
2880 return ToolChain::CST_Libcxx;
2881}
2882
2883void MipsLLVMToolChain::AddClangCXXStdlibIncludeArgs(
2884 const ArgList &DriverArgs, ArgStringList &CC1Args) const {
2885 if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
2886 DriverArgs.hasArg(options::OPT_nostdincxx))
2887 return;
2888
2889 assert((GetCXXStdlibType(DriverArgs) == ToolChain::CST_Libcxx) &&
2890 "Only -lc++ (aka libcxx) is suported in this toolchain.");
2891
2892 const auto &Callback = Multilibs.includeDirsCallback();
2893 if (Callback) {
Simon Atanasyana45502d2016-05-19 15:07:21 +00002894 for (std::string Path : Callback(SelectedMultilib)) {
2895 Path = getDriver().getInstalledDir() + Path + "/c++/v1";
2896 if (llvm::sys::fs::exists(Path)) {
2897 addSystemInclude(DriverArgs, CC1Args, Path);
Vasileios Kalintirisc744e122015-11-12 15:26:54 +00002898 break;
2899 }
2900 }
2901 }
2902}
2903
2904void MipsLLVMToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
2905 ArgStringList &CmdArgs) const {
2906 assert((GetCXXStdlibType(Args) == ToolChain::CST_Libcxx) &&
2907 "Only -lc++ (aka libxx) is suported in this toolchain.");
2908
2909 CmdArgs.push_back("-lc++");
2910 CmdArgs.push_back("-lc++abi");
2911 CmdArgs.push_back("-lunwind");
2912}
2913
Vedant Kumar5fb00e42016-07-27 23:01:55 +00002914std::string MipsLLVMToolChain::getCompilerRT(const ArgList &Args,
2915 StringRef Component,
2916 bool Shared) const {
Vasileios Kalintirisc744e122015-11-12 15:26:54 +00002917 SmallString<128> Path(getDriver().ResourceDir);
2918 llvm::sys::path::append(Path, SelectedMultilib.osSuffix(), "lib" + LibSuffix,
2919 getOS());
2920 llvm::sys::path::append(Path, Twine("libclang_rt." + Component + "-" +
Vasileios Kalintirisbbc99302015-11-16 15:41:30 +00002921 "mips" + (Shared ? ".so" : ".a")));
Vasileios Kalintirisc744e122015-11-12 15:26:54 +00002922 return Path.str();
2923}
2924
Tony Linthicum76329bf2011-12-12 21:14:55 +00002925/// Hexagon Toolchain
2926
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00002927std::string HexagonToolChain::getHexagonTargetDir(
2928 const std::string &InstalledDir,
2929 const SmallVectorImpl<std::string> &PrefixDirs) const {
2930 std::string InstallRelDir;
2931 const Driver &D = getDriver();
2932
Matthew Curtis22dd8da2012-12-06 12:43:18 +00002933 // Locate the rest of the toolchain ...
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00002934 for (auto &I : PrefixDirs)
2935 if (D.getVFS().exists(I))
2936 return I;
Samuel Antaoc909c992014-11-07 17:48:03 +00002937
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00002938 if (getVFS().exists(InstallRelDir = InstalledDir + "/../target"))
Matthew Curtis22dd8da2012-12-06 12:43:18 +00002939 return InstallRelDir;
2940
Matthew Curtis22dd8da2012-12-06 12:43:18 +00002941 return InstallRelDir;
2942}
2943
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00002944Optional<unsigned> HexagonToolChain::getSmallDataThreshold(
2945 const ArgList &Args) {
2946 StringRef Gn = "";
2947 if (Arg *A = Args.getLastArg(options::OPT_G, options::OPT_G_EQ,
2948 options::OPT_msmall_data_threshold_EQ)) {
2949 Gn = A->getValue();
2950 } else if (Args.getLastArg(options::OPT_shared, options::OPT_fpic,
2951 options::OPT_fPIC)) {
2952 Gn = "0";
2953 }
Ikhlas Ajbar522e6192015-05-14 13:52:08 +00002954
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00002955 unsigned G;
2956 if (!Gn.getAsInteger(10, G))
2957 return G;
Ikhlas Ajbar522e6192015-05-14 13:52:08 +00002958
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00002959 return None;
Ikhlas Ajbar522e6192015-05-14 13:52:08 +00002960}
2961
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00002962void HexagonToolChain::getHexagonLibraryPaths(const ArgList &Args,
2963 ToolChain::path_list &LibPaths) const {
2964 const Driver &D = getDriver();
Matthew Curtise689b052012-12-06 15:46:07 +00002965
2966 //----------------------------------------------------------------------------
2967 // -L Args
2968 //----------------------------------------------------------------------------
Douglas Katzman6bbffc42015-06-25 18:51:37 +00002969 for (Arg *A : Args.filtered(options::OPT_L))
2970 for (const char *Value : A->getValues())
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00002971 LibPaths.push_back(Value);
Matthew Curtise689b052012-12-06 15:46:07 +00002972
2973 //----------------------------------------------------------------------------
2974 // Other standard paths
2975 //----------------------------------------------------------------------------
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00002976 std::vector<std::string> RootDirs;
Krzysztof Parzyszekf4467cd2016-01-06 14:13:11 +00002977 std::copy(D.PrefixDirs.begin(), D.PrefixDirs.end(),
2978 std::back_inserter(RootDirs));
Matthew Curtise689b052012-12-06 15:46:07 +00002979
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00002980 std::string TargetDir = getHexagonTargetDir(D.getInstalledDir(),
2981 D.PrefixDirs);
2982 if (std::find(RootDirs.begin(), RootDirs.end(), TargetDir) == RootDirs.end())
2983 RootDirs.push_back(TargetDir);
2984
2985 bool HasPIC = Args.hasArg(options::OPT_fpic, options::OPT_fPIC);
2986 // Assume G0 with -shared.
2987 bool HasG0 = Args.hasArg(options::OPT_shared);
2988 if (auto G = getSmallDataThreshold(Args))
2989 HasG0 = G.getValue() == 0;
2990
2991 const std::string CpuVer = GetTargetCPUVersion(Args).str();
2992 for (auto &Dir : RootDirs) {
2993 std::string LibDir = Dir + "/hexagon/lib";
2994 std::string LibDirCpu = LibDir + '/' + CpuVer;
2995 if (HasG0) {
2996 if (HasPIC)
2997 LibPaths.push_back(LibDirCpu + "/G0/pic");
2998 LibPaths.push_back(LibDirCpu + "/G0");
2999 }
3000 LibPaths.push_back(LibDirCpu);
3001 LibPaths.push_back(LibDir);
Matthew Curtise689b052012-12-06 15:46:07 +00003002 }
Matthew Curtise689b052012-12-06 15:46:07 +00003003}
3004
Douglas Katzman54366072015-07-27 16:53:08 +00003005HexagonToolChain::HexagonToolChain(const Driver &D, const llvm::Triple &Triple,
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00003006 const llvm::opt::ArgList &Args)
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003007 : Linux(D, Triple, Args) {
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00003008 const std::string TargetDir = getHexagonTargetDir(D.getInstalledDir(),
3009 D.PrefixDirs);
Matthew Curtis22dd8da2012-12-06 12:43:18 +00003010
3011 // Note: Generic_GCC::Generic_GCC adds InstalledDir and getDriver().Dir to
3012 // program paths
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00003013 const std::string BinDir(TargetDir + "/bin");
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003014 if (D.getVFS().exists(BinDir))
Matthew Curtis22dd8da2012-12-06 12:43:18 +00003015 getProgramPaths().push_back(BinDir);
3016
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00003017 ToolChain::path_list &LibPaths = getFilePaths();
Matthew Curtise689b052012-12-06 15:46:07 +00003018
3019 // Remove paths added by Linux toolchain. Currently Hexagon_TC really targets
3020 // 'elf' OS type, so the Linux paths are not appropriate. When we actually
3021 // support 'linux' we'll need to fix this up
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00003022 LibPaths.clear();
3023 getHexagonLibraryPaths(Args, LibPaths);
Tony Linthicum76329bf2011-12-12 21:14:55 +00003024}
3025
Angel Garcia Gomez637d1e62015-10-20 13:23:58 +00003026HexagonToolChain::~HexagonToolChain() {}
Tony Linthicum76329bf2011-12-12 21:14:55 +00003027
Douglas Katzman54366072015-07-27 16:53:08 +00003028Tool *HexagonToolChain::buildAssembler() const {
Douglas Katzman95354292015-06-23 20:42:09 +00003029 return new tools::hexagon::Assembler(*this);
Rafael Espindola7cf32212013-03-20 03:05:54 +00003030}
3031
Douglas Katzman54366072015-07-27 16:53:08 +00003032Tool *HexagonToolChain::buildLinker() const {
Douglas Katzman95354292015-06-23 20:42:09 +00003033 return new tools::hexagon::Linker(*this);
Tony Linthicum76329bf2011-12-12 21:14:55 +00003034}
3035
Douglas Katzman54366072015-07-27 16:53:08 +00003036void HexagonToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
3037 ArgStringList &CC1Args) const {
Matthew Curtis22dd8da2012-12-06 12:43:18 +00003038 if (DriverArgs.hasArg(options::OPT_nostdinc) ||
3039 DriverArgs.hasArg(options::OPT_nostdlibinc))
3040 return;
3041
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00003042 const Driver &D = getDriver();
3043 std::string TargetDir = getHexagonTargetDir(D.getInstalledDir(),
3044 D.PrefixDirs);
3045 addExternCSystemInclude(DriverArgs, CC1Args, TargetDir + "/hexagon/include");
Tony Linthicum76329bf2011-12-12 21:14:55 +00003046}
3047
Douglas Katzman54366072015-07-27 16:53:08 +00003048void HexagonToolChain::AddClangCXXStdlibIncludeArgs(
3049 const ArgList &DriverArgs, ArgStringList &CC1Args) const {
Matthew Curtis22dd8da2012-12-06 12:43:18 +00003050 if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
3051 DriverArgs.hasArg(options::OPT_nostdincxx))
3052 return;
3053
3054 const Driver &D = getDriver();
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00003055 std::string TargetDir = getHexagonTargetDir(D.InstalledDir, D.PrefixDirs);
3056 addSystemInclude(DriverArgs, CC1Args, TargetDir + "/hexagon/include/c++");
Chandler Carruth76a943b2012-11-19 03:52:03 +00003057}
Matthew Curtisf10a5952012-12-06 14:16:43 +00003058
Matthew Curtise689b052012-12-06 15:46:07 +00003059ToolChain::CXXStdlibType
Douglas Katzman54366072015-07-27 16:53:08 +00003060HexagonToolChain::GetCXXStdlibType(const ArgList &Args) const {
Matthew Curtise689b052012-12-06 15:46:07 +00003061 Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
3062 if (!A)
3063 return ToolChain::CST_Libstdcxx;
3064
3065 StringRef Value = A->getValue();
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00003066 if (Value != "libstdc++")
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003067 getDriver().Diag(diag::err_drv_invalid_stdlib_name) << A->getAsString(Args);
Matthew Curtise689b052012-12-06 15:46:07 +00003068
3069 return ToolChain::CST_Libstdcxx;
3070}
3071
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00003072//
3073// Returns the default CPU for Hexagon. This is the default compilation target
3074// if no Hexagon processor is selected at the command-line.
3075//
3076const StringRef HexagonToolChain::GetDefaultCPU() {
3077 return "hexagonv60";
Matthew Curtisf10a5952012-12-06 14:16:43 +00003078}
3079
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00003080const StringRef HexagonToolChain::GetTargetCPUVersion(const ArgList &Args) {
3081 Arg *CpuArg = nullptr;
Krzysztof Parzyszek972f72c2016-01-06 21:12:03 +00003082 if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ, options::OPT_march_EQ))
3083 CpuArg = A;
Krzysztof Parzyszek1e6e3c62015-12-14 15:03:57 +00003084
3085 StringRef CPU = CpuArg ? CpuArg->getValue() : GetDefaultCPU();
3086 if (CPU.startswith("hexagon"))
3087 return CPU.substr(sizeof("hexagon") - 1);
3088 return CPU;
Matthew Curtisf10a5952012-12-06 14:16:43 +00003089}
Matthew Curtis22dd8da2012-12-06 12:43:18 +00003090// End Hexagon
Daniel Dunbardac54a82009-03-25 04:13:45 +00003091
Tom Stellard8fa33092015-07-18 01:49:05 +00003092/// AMDGPU Toolchain
3093AMDGPUToolChain::AMDGPUToolChain(const Driver &D, const llvm::Triple &Triple,
3094 const ArgList &Args)
3095 : Generic_ELF(D, Triple, Args) { }
3096
3097Tool *AMDGPUToolChain::buildLinker() const {
3098 return new tools::amdgpu::Linker(*this);
3099}
3100// End AMDGPU
3101
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003102/// NaCl Toolchain
Douglas Katzman54366072015-07-27 16:53:08 +00003103NaClToolChain::NaClToolChain(const Driver &D, const llvm::Triple &Triple,
3104 const ArgList &Args)
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003105 : Generic_ELF(D, Triple, Args) {
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003106
3107 // Remove paths added by Generic_GCC. NaCl Toolchain cannot use the
3108 // default paths, and must instead only use the paths provided
3109 // with this toolchain based on architecture.
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003110 path_list &file_paths = getFilePaths();
3111 path_list &prog_paths = getProgramPaths();
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003112
3113 file_paths.clear();
3114 prog_paths.clear();
3115
3116 // Path for library files (libc.a, ...)
3117 std::string FilePath(getDriver().Dir + "/../");
3118
3119 // Path for tools (clang, ld, etc..)
3120 std::string ProgPath(getDriver().Dir + "/../");
3121
3122 // Path for toolchain libraries (libgcc.a, ...)
3123 std::string ToolPath(getDriver().ResourceDir + "/lib/");
3124
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003125 switch (Triple.getArch()) {
Hans Wennborgdcfba332015-10-06 23:40:43 +00003126 case llvm::Triple::x86:
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003127 file_paths.push_back(FilePath + "x86_64-nacl/lib32");
Derek Schuff9afb0502015-08-26 17:14:08 +00003128 file_paths.push_back(FilePath + "i686-nacl/usr/lib");
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003129 prog_paths.push_back(ProgPath + "x86_64-nacl/bin");
3130 file_paths.push_back(ToolPath + "i686-nacl");
3131 break;
Hans Wennborgdcfba332015-10-06 23:40:43 +00003132 case llvm::Triple::x86_64:
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003133 file_paths.push_back(FilePath + "x86_64-nacl/lib");
3134 file_paths.push_back(FilePath + "x86_64-nacl/usr/lib");
3135 prog_paths.push_back(ProgPath + "x86_64-nacl/bin");
3136 file_paths.push_back(ToolPath + "x86_64-nacl");
3137 break;
Hans Wennborgdcfba332015-10-06 23:40:43 +00003138 case llvm::Triple::arm:
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003139 file_paths.push_back(FilePath + "arm-nacl/lib");
3140 file_paths.push_back(FilePath + "arm-nacl/usr/lib");
3141 prog_paths.push_back(ProgPath + "arm-nacl/bin");
3142 file_paths.push_back(ToolPath + "arm-nacl");
3143 break;
Hans Wennborgdcfba332015-10-06 23:40:43 +00003144 case llvm::Triple::mipsel:
Petar Jovanovic26a4a402015-07-08 13:07:31 +00003145 file_paths.push_back(FilePath + "mipsel-nacl/lib");
3146 file_paths.push_back(FilePath + "mipsel-nacl/usr/lib");
3147 prog_paths.push_back(ProgPath + "bin");
3148 file_paths.push_back(ToolPath + "mipsel-nacl");
3149 break;
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003150 default:
3151 break;
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003152 }
3153
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003154 NaClArmMacrosPath = GetFilePath("nacl-arm-macros.s");
3155}
3156
Douglas Katzman54366072015-07-27 16:53:08 +00003157void NaClToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
3158 ArgStringList &CC1Args) const {
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003159 const Driver &D = getDriver();
3160 if (DriverArgs.hasArg(options::OPT_nostdinc))
3161 return;
3162
3163 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
3164 SmallString<128> P(D.ResourceDir);
3165 llvm::sys::path::append(P, "include");
3166 addSystemInclude(DriverArgs, CC1Args, P.str());
3167 }
3168
3169 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
3170 return;
3171
3172 SmallString<128> P(D.Dir + "/../");
Douglas Katzman7e37afb2015-06-23 03:02:39 +00003173 switch (getTriple().getArch()) {
Derek Schuff9afb0502015-08-26 17:14:08 +00003174 case llvm::Triple::x86:
3175 // x86 is special because multilib style uses x86_64-nacl/include for libc
3176 // headers but the SDK wants i686-nacl/usr/include. The other architectures
3177 // have the same substring.
3178 llvm::sys::path::append(P, "i686-nacl/usr/include");
3179 addSystemInclude(DriverArgs, CC1Args, P.str());
3180 llvm::sys::path::remove_filename(P);
3181 llvm::sys::path::remove_filename(P);
3182 llvm::sys::path::remove_filename(P);
3183 llvm::sys::path::append(P, "x86_64-nacl/include");
3184 addSystemInclude(DriverArgs, CC1Args, P.str());
3185 return;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00003186 case llvm::Triple::arm:
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003187 llvm::sys::path::append(P, "arm-nacl/usr/include");
Douglas Katzman7e37afb2015-06-23 03:02:39 +00003188 break;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00003189 case llvm::Triple::x86_64:
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003190 llvm::sys::path::append(P, "x86_64-nacl/usr/include");
Douglas Katzman7e37afb2015-06-23 03:02:39 +00003191 break;
Petar Jovanovic26a4a402015-07-08 13:07:31 +00003192 case llvm::Triple::mipsel:
3193 llvm::sys::path::append(P, "mipsel-nacl/usr/include");
3194 break;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00003195 default:
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003196 return;
3197 }
3198
3199 addSystemInclude(DriverArgs, CC1Args, P.str());
3200 llvm::sys::path::remove_filename(P);
3201 llvm::sys::path::remove_filename(P);
3202 llvm::sys::path::append(P, "include");
3203 addSystemInclude(DriverArgs, CC1Args, P.str());
3204}
3205
Douglas Katzman54366072015-07-27 16:53:08 +00003206void NaClToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
3207 ArgStringList &CmdArgs) const {
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003208 // Check for -stdlib= flags. We only support libc++ but this consumes the arg
3209 // if the value is libc++, and emits an error for other values.
3210 GetCXXStdlibType(Args);
3211 CmdArgs.push_back("-lc++");
3212}
3213
Douglas Katzman54366072015-07-27 16:53:08 +00003214void NaClToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
3215 ArgStringList &CC1Args) const {
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003216 const Driver &D = getDriver();
3217 if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
3218 DriverArgs.hasArg(options::OPT_nostdincxx))
3219 return;
3220
3221 // Check for -stdlib= flags. We only support libc++ but this consumes the arg
3222 // if the value is libc++, and emits an error for other values.
3223 GetCXXStdlibType(DriverArgs);
3224
Douglas Katzman7e37afb2015-06-23 03:02:39 +00003225 SmallString<128> P(D.Dir + "/../");
3226 switch (getTriple().getArch()) {
3227 case llvm::Triple::arm:
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003228 llvm::sys::path::append(P, "arm-nacl/include/c++/v1");
3229 addSystemInclude(DriverArgs, CC1Args, P.str());
Douglas Katzman7e37afb2015-06-23 03:02:39 +00003230 break;
3231 case llvm::Triple::x86:
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003232 llvm::sys::path::append(P, "x86_64-nacl/include/c++/v1");
3233 addSystemInclude(DriverArgs, CC1Args, P.str());
Douglas Katzman7e37afb2015-06-23 03:02:39 +00003234 break;
3235 case llvm::Triple::x86_64:
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003236 llvm::sys::path::append(P, "x86_64-nacl/include/c++/v1");
3237 addSystemInclude(DriverArgs, CC1Args, P.str());
Douglas Katzman7e37afb2015-06-23 03:02:39 +00003238 break;
Petar Jovanovic26a4a402015-07-08 13:07:31 +00003239 case llvm::Triple::mipsel:
3240 llvm::sys::path::append(P, "mipsel-nacl/include/c++/v1");
3241 addSystemInclude(DriverArgs, CC1Args, P.str());
3242 break;
Douglas Katzman9ad0ec22015-06-23 04:20:44 +00003243 default:
3244 break;
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003245 }
3246}
3247
Douglas Katzman54366072015-07-27 16:53:08 +00003248ToolChain::CXXStdlibType
3249NaClToolChain::GetCXXStdlibType(const ArgList &Args) const {
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003250 if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) {
3251 StringRef Value = A->getValue();
3252 if (Value == "libc++")
3253 return ToolChain::CST_Libcxx;
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003254 getDriver().Diag(diag::err_drv_invalid_stdlib_name) << A->getAsString(Args);
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003255 }
3256
3257 return ToolChain::CST_Libcxx;
3258}
3259
Douglas Katzman54366072015-07-27 16:53:08 +00003260std::string
3261NaClToolChain::ComputeEffectiveClangTriple(const ArgList &Args,
3262 types::ID InputType) const {
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003263 llvm::Triple TheTriple(ComputeLLVMTriple(Args, InputType));
3264 if (TheTriple.getArch() == llvm::Triple::arm &&
3265 TheTriple.getEnvironment() == llvm::Triple::UnknownEnvironment)
3266 TheTriple.setEnvironment(llvm::Triple::GNUEABIHF);
3267 return TheTriple.getTriple();
3268}
3269
Douglas Katzman54366072015-07-27 16:53:08 +00003270Tool *NaClToolChain::buildLinker() const {
Douglas Katzman95354292015-06-23 20:42:09 +00003271 return new tools::nacltools::Linker(*this);
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003272}
3273
Douglas Katzman54366072015-07-27 16:53:08 +00003274Tool *NaClToolChain::buildAssembler() const {
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003275 if (getTriple().getArch() == llvm::Triple::arm)
Douglas Katzman95354292015-06-23 20:42:09 +00003276 return new tools::nacltools::AssemblerARM(*this);
3277 return new tools::gnutools::Assembler(*this);
Derek Schuff6ab52fa2015-03-30 20:31:33 +00003278}
3279// End NaCl
3280
Chris Lattner09797542010-03-04 21:07:38 +00003281/// TCEToolChain - A tool chain using the llvm bitcode tools to perform
3282/// all subcommands. See http://tce.cs.tut.fi for our peculiar target.
3283/// Currently does not support anything else but compilation.
3284
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003285TCEToolChain::TCEToolChain(const Driver &D, const llvm::Triple &Triple,
Rafael Espindola84b588b2013-03-18 18:10:27 +00003286 const ArgList &Args)
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003287 : ToolChain(D, Triple, Args) {
Chris Lattner09797542010-03-04 21:07:38 +00003288 // Path mangling to find libexec
3289 std::string Path(getDriver().Dir);
3290
3291 Path += "/../libexec";
3292 getProgramPaths().push_back(Path);
3293}
3294
Angel Garcia Gomez637d1e62015-10-20 13:23:58 +00003295TCEToolChain::~TCEToolChain() {}
Chris Lattner09797542010-03-04 21:07:38 +00003296
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003297bool TCEToolChain::IsMathErrnoDefault() const { return true; }
Chris Lattner09797542010-03-04 21:07:38 +00003298
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003299bool TCEToolChain::isPICDefault() const { return false; }
Chris Lattner09797542010-03-04 21:07:38 +00003300
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003301bool TCEToolChain::isPIEDefault() const { return false; }
Peter Collingbourne54d770c2013-04-09 04:35:11 +00003302
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003303bool TCEToolChain::isPICDefaultForced() const { return false; }
Chris Lattner09797542010-03-04 21:07:38 +00003304
Ed Schouten3c3e58c2015-03-26 11:13:44 +00003305// CloudABI - CloudABI tool chain which can call ld(1) directly.
3306
3307CloudABI::CloudABI(const Driver &D, const llvm::Triple &Triple,
3308 const ArgList &Args)
3309 : Generic_ELF(D, Triple, Args) {
3310 SmallString<128> P(getDriver().Dir);
3311 llvm::sys::path::append(P, "..", getTriple().str(), "lib");
3312 getFilePaths().push_back(P.str());
3313}
3314
3315void CloudABI::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
3316 ArgStringList &CC1Args) const {
3317 if (DriverArgs.hasArg(options::OPT_nostdlibinc) &&
3318 DriverArgs.hasArg(options::OPT_nostdincxx))
3319 return;
3320
3321 SmallString<128> P(getDriver().Dir);
3322 llvm::sys::path::append(P, "..", getTriple().str(), "include/c++/v1");
3323 addSystemInclude(DriverArgs, CC1Args, P.str());
3324}
3325
3326void CloudABI::AddCXXStdlibLibArgs(const ArgList &Args,
3327 ArgStringList &CmdArgs) const {
3328 CmdArgs.push_back("-lc++");
3329 CmdArgs.push_back("-lc++abi");
3330 CmdArgs.push_back("-lunwind");
3331}
3332
Douglas Katzman95354292015-06-23 20:42:09 +00003333Tool *CloudABI::buildLinker() const {
3334 return new tools::cloudabi::Linker(*this);
3335}
Ed Schouten3c3e58c2015-03-26 11:13:44 +00003336
Ed Schouten51bfbe72016-02-17 18:56:20 +00003337SanitizerMask CloudABI::getSupportedSanitizers() const {
3338 SanitizerMask Res = ToolChain::getSupportedSanitizers();
3339 Res |= SanitizerKind::SafeStack;
3340 return Res;
3341}
3342
Ed Schoutenfc79d2c2016-03-29 21:13:53 +00003343SanitizerMask CloudABI::getDefaultSanitizers() const {
3344 return SanitizerKind::SafeStack;
3345}
3346
Reid Kleckner330fb172016-05-11 16:19:05 +00003347/// Haiku - Haiku tool chain which can call as(1) and ld(1) directly.
3348
3349Haiku::Haiku(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
3350 : Generic_ELF(D, Triple, Args) {
3351
3352}
3353
3354void Haiku::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
3355 ArgStringList &CC1Args) const {
3356 if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
3357 DriverArgs.hasArg(options::OPT_nostdincxx))
3358 return;
3359
3360 switch (GetCXXStdlibType(DriverArgs)) {
3361 case ToolChain::CST_Libcxx:
3362 addSystemInclude(DriverArgs, CC1Args,
3363 getDriver().SysRoot + "/system/develop/headers/c++/v1");
3364 break;
3365 case ToolChain::CST_Libstdcxx:
3366 addSystemInclude(DriverArgs, CC1Args,
3367 getDriver().SysRoot + "/system/develop/headers/c++");
3368 addSystemInclude(DriverArgs, CC1Args,
3369 getDriver().SysRoot + "/system/develop/headers/c++/backward");
3370
3371 StringRef Triple = getTriple().str();
3372 addSystemInclude(DriverArgs, CC1Args,
3373 getDriver().SysRoot + "/system/develop/headers/c++/" +
3374 Triple);
3375 break;
3376 }
3377}
3378
Daniel Dunbar10de9e62009-06-29 20:52:51 +00003379/// OpenBSD - OpenBSD tool chain which can call as(1) and ld(1) directly.
3380
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003381OpenBSD::OpenBSD(const Driver &D, const llvm::Triple &Triple,
3382 const ArgList &Args)
3383 : Generic_ELF(D, Triple, Args) {
Daniel Dunbar083edf72009-12-21 18:54:17 +00003384 getFilePaths().push_back(getDriver().Dir + "/../lib");
Daniel Dunbar10de9e62009-06-29 20:52:51 +00003385 getFilePaths().push_back("/usr/lib");
3386}
3387
Rafael Espindola7cf32212013-03-20 03:05:54 +00003388Tool *OpenBSD::buildAssembler() const {
Douglas Katzman95354292015-06-23 20:42:09 +00003389 return new tools::openbsd::Assembler(*this);
Rafael Espindola7cf32212013-03-20 03:05:54 +00003390}
3391
Douglas Katzman95354292015-06-23 20:42:09 +00003392Tool *OpenBSD::buildLinker() const { return new tools::openbsd::Linker(*this); }
Daniel Dunbar10de9e62009-06-29 20:52:51 +00003393
Eli Friedman9fa28852012-08-08 23:57:20 +00003394/// Bitrig - Bitrig tool chain which can call as(1) and ld(1) directly.
3395
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003396Bitrig::Bitrig(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
3397 : Generic_ELF(D, Triple, Args) {
Eli Friedman9fa28852012-08-08 23:57:20 +00003398 getFilePaths().push_back(getDriver().Dir + "/../lib");
3399 getFilePaths().push_back("/usr/lib");
3400}
3401
Rafael Espindola7cf32212013-03-20 03:05:54 +00003402Tool *Bitrig::buildAssembler() const {
Douglas Katzman95354292015-06-23 20:42:09 +00003403 return new tools::bitrig::Assembler(*this);
Rafael Espindola7cf32212013-03-20 03:05:54 +00003404}
3405
Douglas Katzman95354292015-06-23 20:42:09 +00003406Tool *Bitrig::buildLinker() const { return new tools::bitrig::Linker(*this); }
Eli Friedman9fa28852012-08-08 23:57:20 +00003407
Jonas Hahnfeldaae83742016-02-12 07:48:37 +00003408ToolChain::CXXStdlibType Bitrig::GetDefaultCXXStdlibType() const {
Richard Smith51af5192014-05-01 23:24:24 +00003409 return ToolChain::CST_Libcxx;
3410}
3411
Eli Friedman9fa28852012-08-08 23:57:20 +00003412void Bitrig::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
3413 ArgStringList &CC1Args) const {
3414 if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
3415 DriverArgs.hasArg(options::OPT_nostdincxx))
3416 return;
3417
Chandler Carruthc0f5cd12012-10-08 21:31:38 +00003418 switch (GetCXXStdlibType(DriverArgs)) {
3419 case ToolChain::CST_Libcxx:
3420 addSystemInclude(DriverArgs, CC1Args,
Richard Smith51af5192014-05-01 23:24:24 +00003421 getDriver().SysRoot + "/usr/include/c++/v1");
Chandler Carruthc0f5cd12012-10-08 21:31:38 +00003422 break;
3423 case ToolChain::CST_Libstdcxx:
3424 addSystemInclude(DriverArgs, CC1Args,
3425 getDriver().SysRoot + "/usr/include/c++/stdc++");
3426 addSystemInclude(DriverArgs, CC1Args,
3427 getDriver().SysRoot + "/usr/include/c++/stdc++/backward");
Eli Friedman9fa28852012-08-08 23:57:20 +00003428
Chandler Carruthc0f5cd12012-10-08 21:31:38 +00003429 StringRef Triple = getTriple().str();
3430 if (Triple.startswith("amd64"))
3431 addSystemInclude(DriverArgs, CC1Args,
3432 getDriver().SysRoot + "/usr/include/c++/stdc++/x86_64" +
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003433 Triple.substr(5));
Chandler Carruthc0f5cd12012-10-08 21:31:38 +00003434 else
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003435 addSystemInclude(DriverArgs, CC1Args, getDriver().SysRoot +
3436 "/usr/include/c++/stdc++/" +
3437 Triple);
Chandler Carruthc0f5cd12012-10-08 21:31:38 +00003438 break;
3439 }
Eli Friedman9fa28852012-08-08 23:57:20 +00003440}
3441
3442void Bitrig::AddCXXStdlibLibArgs(const ArgList &Args,
3443 ArgStringList &CmdArgs) const {
Chandler Carruthc0f5cd12012-10-08 21:31:38 +00003444 switch (GetCXXStdlibType(Args)) {
3445 case ToolChain::CST_Libcxx:
3446 CmdArgs.push_back("-lc++");
Richard Smith51af5192014-05-01 23:24:24 +00003447 CmdArgs.push_back("-lc++abi");
3448 CmdArgs.push_back("-lpthread");
Chandler Carruthc0f5cd12012-10-08 21:31:38 +00003449 break;
3450 case ToolChain::CST_Libstdcxx:
3451 CmdArgs.push_back("-lstdc++");
3452 break;
3453 }
Eli Friedman9fa28852012-08-08 23:57:20 +00003454}
3455
Daniel Dunbare24297c2009-03-30 21:06:03 +00003456/// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly.
3457
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003458FreeBSD::FreeBSD(const Driver &D, const llvm::Triple &Triple,
3459 const ArgList &Args)
3460 : Generic_ELF(D, Triple, Args) {
Daniel Dunbara18a4872010-08-02 05:43:59 +00003461
Chandler Carruth0b1756b2012-01-26 01:35:15 +00003462 // When targeting 32-bit platforms, look for '/usr/lib32/crt1.o' and fall
3463 // back to '/usr/lib' if it doesn't exist.
Chandler Carruthf7bf3db2012-01-25 11:24:24 +00003464 if ((Triple.getArch() == llvm::Triple::x86 ||
3465 Triple.getArch() == llvm::Triple::ppc) &&
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003466 D.getVFS().exists(getDriver().SysRoot + "/usr/lib32/crt1.o"))
Chandler Carruthf7bf3db2012-01-25 11:24:24 +00003467 getFilePaths().push_back(getDriver().SysRoot + "/usr/lib32");
3468 else
3469 getFilePaths().push_back(getDriver().SysRoot + "/usr/lib");
Daniel Dunbare24297c2009-03-30 21:06:03 +00003470}
3471
Jonas Hahnfeld09954192016-03-14 14:34:04 +00003472ToolChain::CXXStdlibType FreeBSD::GetDefaultCXXStdlibType() const {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003473 if (getTriple().getOSMajorVersion() >= 10)
David Chisnall867ccd82013-11-09 15:10:56 +00003474 return ToolChain::CST_Libcxx;
3475 return ToolChain::CST_Libstdcxx;
3476}
3477
3478void FreeBSD::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
3479 ArgStringList &CC1Args) const {
3480 if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
3481 DriverArgs.hasArg(options::OPT_nostdincxx))
3482 return;
3483
3484 switch (GetCXXStdlibType(DriverArgs)) {
3485 case ToolChain::CST_Libcxx:
3486 addSystemInclude(DriverArgs, CC1Args,
3487 getDriver().SysRoot + "/usr/include/c++/v1");
3488 break;
3489 case ToolChain::CST_Libstdcxx:
3490 addSystemInclude(DriverArgs, CC1Args,
3491 getDriver().SysRoot + "/usr/include/c++/4.2");
3492 addSystemInclude(DriverArgs, CC1Args,
3493 getDriver().SysRoot + "/usr/include/c++/4.2/backward");
3494 break;
3495 }
3496}
3497
Dimitry Andric60907392016-02-14 16:08:20 +00003498void FreeBSD::AddCXXStdlibLibArgs(const ArgList &Args,
3499 ArgStringList &CmdArgs) const {
3500 CXXStdlibType Type = GetCXXStdlibType(Args);
3501 bool Profiling = Args.hasArg(options::OPT_pg);
3502
3503 switch (Type) {
3504 case ToolChain::CST_Libcxx:
3505 CmdArgs.push_back(Profiling ? "-lc++_p" : "-lc++");
3506 break;
3507
3508 case ToolChain::CST_Libstdcxx:
3509 CmdArgs.push_back(Profiling ? "-lstdc++_p" : "-lstdc++");
3510 break;
3511 }
3512}
3513
Rafael Espindola7cf32212013-03-20 03:05:54 +00003514Tool *FreeBSD::buildAssembler() const {
Douglas Katzman95354292015-06-23 20:42:09 +00003515 return new tools::freebsd::Assembler(*this);
Rafael Espindola7cf32212013-03-20 03:05:54 +00003516}
3517
Douglas Katzman95354292015-06-23 20:42:09 +00003518Tool *FreeBSD::buildLinker() const { return new tools::freebsd::Linker(*this); }
Daniel Dunbarcc912342009-05-02 18:28:39 +00003519
Tim Northovere931f9f2015-10-30 16:30:41 +00003520bool FreeBSD::UseSjLjExceptions(const ArgList &Args) const {
Rafael Espindola0f207ed2012-12-13 04:17:14 +00003521 // FreeBSD uses SjLj exceptions on ARM oabi.
3522 switch (getTriple().getEnvironment()) {
Renato Golinf4421f72014-02-19 10:44:07 +00003523 case llvm::Triple::GNUEABIHF:
Rafael Espindola0f207ed2012-12-13 04:17:14 +00003524 case llvm::Triple::GNUEABI:
3525 case llvm::Triple::EABI:
3526 return false;
3527
3528 default:
3529 return (getTriple().getArch() == llvm::Triple::arm ||
3530 getTriple().getArch() == llvm::Triple::thumb);
3531 }
3532}
3533
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003534bool FreeBSD::HasNativeLLVMSupport() const { return true; }
Alexey Samsonove65ceb92014-02-25 13:26:03 +00003535
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003536bool FreeBSD::isPIEDefault() const { return getSanitizerArgs().requiresPIE(); }
Alexey Samsonove65ceb92014-02-25 13:26:03 +00003537
Alexey Samsonov7f2a0d22015-06-19 21:36:47 +00003538SanitizerMask FreeBSD::getSupportedSanitizers() const {
3539 const bool IsX86 = getTriple().getArch() == llvm::Triple::x86;
3540 const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64;
3541 const bool IsMIPS64 = getTriple().getArch() == llvm::Triple::mips64 ||
3542 getTriple().getArch() == llvm::Triple::mips64el;
3543 SanitizerMask Res = ToolChain::getSupportedSanitizers();
3544 Res |= SanitizerKind::Address;
3545 Res |= SanitizerKind::Vptr;
3546 if (IsX86_64 || IsMIPS64) {
3547 Res |= SanitizerKind::Leak;
3548 Res |= SanitizerKind::Thread;
3549 }
3550 if (IsX86 || IsX86_64) {
3551 Res |= SanitizerKind::SafeStack;
3552 }
3553 return Res;
3554}
3555
Benjamin Kramer24f1d3e2011-02-02 18:59:27 +00003556/// NetBSD - NetBSD tool chain which can call as(1) and ld(1) directly.
3557
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003558NetBSD::NetBSD(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
3559 : Generic_ELF(D, Triple, Args) {
Joerg Sonnenbergerbc923f32011-03-21 13:59:26 +00003560 if (getDriver().UseStdLib) {
Chandler Carruth1ccbed82012-01-25 11:18:20 +00003561 // When targeting a 32-bit platform, try the special directory used on
3562 // 64-bit hosts, and only fall back to the main library directory if that
3563 // doesn't work.
3564 // FIXME: It'd be nicer to test if this directory exists, but I'm not sure
3565 // what all logic is needed to emulate the '=' prefix here.
Joerg Sonnenberger25de31d2014-02-02 22:47:37 +00003566 switch (Triple.getArch()) {
3567 case llvm::Triple::x86:
Joerg Sonnenbergerbc923f32011-03-21 13:59:26 +00003568 getFilePaths().push_back("=/usr/lib/i386");
Joerg Sonnenberger25de31d2014-02-02 22:47:37 +00003569 break;
3570 case llvm::Triple::arm:
Joerg Sonnenberger3a6c28a2014-05-07 08:24:23 +00003571 case llvm::Triple::armeb:
Joerg Sonnenberger25de31d2014-02-02 22:47:37 +00003572 case llvm::Triple::thumb:
Joerg Sonnenberger3a6c28a2014-05-07 08:24:23 +00003573 case llvm::Triple::thumbeb:
Joerg Sonnenberger25de31d2014-02-02 22:47:37 +00003574 switch (Triple.getEnvironment()) {
3575 case llvm::Triple::EABI:
Joerg Sonnenberger25de31d2014-02-02 22:47:37 +00003576 case llvm::Triple::GNUEABI:
Joerg Sonnenberger25de31d2014-02-02 22:47:37 +00003577 getFilePaths().push_back("=/usr/lib/eabi");
3578 break;
Joerg Sonnenberger17a80e42014-08-09 19:01:52 +00003579 case llvm::Triple::EABIHF:
3580 case llvm::Triple::GNUEABIHF:
3581 getFilePaths().push_back("=/usr/lib/eabihf");
3582 break;
Joerg Sonnenberger25de31d2014-02-02 22:47:37 +00003583 default:
3584 getFilePaths().push_back("=/usr/lib/oabi");
3585 break;
3586 }
3587 break;
Joerg Sonnenbergere7f97592014-02-02 22:59:16 +00003588 case llvm::Triple::mips64:
3589 case llvm::Triple::mips64el:
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00003590 if (tools::mips::hasMipsAbiArg(Args, "o32"))
Joerg Sonnenbergere7f97592014-02-02 22:59:16 +00003591 getFilePaths().push_back("=/usr/lib/o32");
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00003592 else if (tools::mips::hasMipsAbiArg(Args, "64"))
Joerg Sonnenbergere7f97592014-02-02 22:59:16 +00003593 getFilePaths().push_back("=/usr/lib/64");
3594 break;
Joerg Sonnenbergerdd13b302014-08-13 14:17:32 +00003595 case llvm::Triple::ppc:
3596 getFilePaths().push_back("=/usr/lib/powerpc");
3597 break;
Joerg Sonnenberger8280abe2014-04-16 20:44:17 +00003598 case llvm::Triple::sparc:
3599 getFilePaths().push_back("=/usr/lib/sparc");
3600 break;
Joerg Sonnenberger25de31d2014-02-02 22:47:37 +00003601 default:
3602 break;
3603 }
Chandler Carruth1ccbed82012-01-25 11:18:20 +00003604
3605 getFilePaths().push_back("=/usr/lib");
Benjamin Kramer24f1d3e2011-02-02 18:59:27 +00003606 }
3607}
3608
Rafael Espindola7cf32212013-03-20 03:05:54 +00003609Tool *NetBSD::buildAssembler() const {
Douglas Katzman95354292015-06-23 20:42:09 +00003610 return new tools::netbsd::Assembler(*this);
Rafael Espindola7cf32212013-03-20 03:05:54 +00003611}
3612
Douglas Katzman95354292015-06-23 20:42:09 +00003613Tool *NetBSD::buildLinker() const { return new tools::netbsd::Linker(*this); }
Benjamin Kramer24f1d3e2011-02-02 18:59:27 +00003614
Jonas Hahnfeld09954192016-03-14 14:34:04 +00003615ToolChain::CXXStdlibType NetBSD::GetDefaultCXXStdlibType() const {
Joerg Sonnenbergera4435632013-10-14 20:13:05 +00003616 unsigned Major, Minor, Micro;
3617 getTriple().getOSVersion(Major, Minor, Micro);
Joerg Sonnenberger21156e82016-02-11 23:35:03 +00003618 if (Major >= 7 || Major == 0) {
Joerg Sonnenbergerd769a1e2014-01-18 00:50:49 +00003619 switch (getArch()) {
Joerg Sonnenberger323cea92014-08-09 18:28:36 +00003620 case llvm::Triple::aarch64:
Joerg Sonnenberger1ea66472014-05-07 08:45:26 +00003621 case llvm::Triple::arm:
3622 case llvm::Triple::armeb:
3623 case llvm::Triple::thumb:
3624 case llvm::Triple::thumbeb:
Joerg Sonnenbergerc8887572014-07-25 20:57:24 +00003625 case llvm::Triple::ppc:
Joerg Sonnenbergerdd13b302014-08-13 14:17:32 +00003626 case llvm::Triple::ppc64:
3627 case llvm::Triple::ppc64le:
Joerg Sonnenberger059613c2016-02-11 23:18:36 +00003628 case llvm::Triple::sparc:
3629 case llvm::Triple::sparcv9:
Joerg Sonnenbergerd769a1e2014-01-18 00:50:49 +00003630 case llvm::Triple::x86:
3631 case llvm::Triple::x86_64:
Joerg Sonnenbergera4435632013-10-14 20:13:05 +00003632 return ToolChain::CST_Libcxx;
Joerg Sonnenbergerd769a1e2014-01-18 00:50:49 +00003633 default:
3634 break;
3635 }
Joerg Sonnenbergera4435632013-10-14 20:13:05 +00003636 }
Joerg Sonnenberger428ef1e2013-04-30 01:21:43 +00003637 return ToolChain::CST_Libstdcxx;
3638}
3639
3640void NetBSD::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
3641 ArgStringList &CC1Args) const {
3642 if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
3643 DriverArgs.hasArg(options::OPT_nostdincxx))
3644 return;
3645
3646 switch (GetCXXStdlibType(DriverArgs)) {
3647 case ToolChain::CST_Libcxx:
3648 addSystemInclude(DriverArgs, CC1Args,
3649 getDriver().SysRoot + "/usr/include/c++/");
3650 break;
3651 case ToolChain::CST_Libstdcxx:
3652 addSystemInclude(DriverArgs, CC1Args,
3653 getDriver().SysRoot + "/usr/include/g++");
3654 addSystemInclude(DriverArgs, CC1Args,
3655 getDriver().SysRoot + "/usr/include/g++/backward");
3656 break;
3657 }
3658}
3659
Chris Lattner3e2ee142010-07-07 16:01:42 +00003660/// Minix - Minix tool chain which can call as(1) and ld(1) directly.
3661
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003662Minix::Minix(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
3663 : Generic_ELF(D, Triple, Args) {
Chris Lattner3e2ee142010-07-07 16:01:42 +00003664 getFilePaths().push_back(getDriver().Dir + "/../lib");
3665 getFilePaths().push_back("/usr/lib");
Chris Lattner3e2ee142010-07-07 16:01:42 +00003666}
3667
Rafael Espindola7cf32212013-03-20 03:05:54 +00003668Tool *Minix::buildAssembler() const {
Douglas Katzman95354292015-06-23 20:42:09 +00003669 return new tools::minix::Assembler(*this);
Rafael Espindola7cf32212013-03-20 03:05:54 +00003670}
3671
Douglas Katzman95354292015-06-23 20:42:09 +00003672Tool *Minix::buildLinker() const { return new tools::minix::Linker(*this); }
Chris Lattner3e2ee142010-07-07 16:01:42 +00003673
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003674static void addPathIfExists(const Driver &D, const Twine &Path,
3675 ToolChain::path_list &Paths) {
3676 if (D.getVFS().exists(Path))
Rafael Espindolac53c5b12015-08-31 19:17:51 +00003677 Paths.push_back(Path.str());
3678}
3679
David Chisnallf571cde2012-02-15 13:39:01 +00003680/// Solaris - Solaris tool chain which can call as(1) and ld(1) directly.
3681
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003682Solaris::Solaris(const Driver &D, const llvm::Triple &Triple,
Rafael Espindola1af7c212012-02-19 01:38:32 +00003683 const ArgList &Args)
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003684 : Generic_GCC(D, Triple, Args) {
David Chisnallf571cde2012-02-15 13:39:01 +00003685
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003686 GCCInstallation.init(Triple, Args);
David Chisnallf571cde2012-02-15 13:39:01 +00003687
Rafael Espindolac53c5b12015-08-31 19:17:51 +00003688 path_list &Paths = getFilePaths();
3689 if (GCCInstallation.isValid())
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003690 addPathIfExists(D, GCCInstallation.getInstallPath(), Paths);
Rafael Espindolac53c5b12015-08-31 19:17:51 +00003691
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003692 addPathIfExists(D, getDriver().getInstalledDir(), Paths);
Rafael Espindolac53c5b12015-08-31 19:17:51 +00003693 if (getDriver().getInstalledDir() != getDriver().Dir)
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003694 addPathIfExists(D, getDriver().Dir, Paths);
Rafael Espindolac53c5b12015-08-31 19:17:51 +00003695
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003696 addPathIfExists(D, getDriver().SysRoot + getDriver().Dir + "/../lib", Paths);
Rafael Espindolac53c5b12015-08-31 19:17:51 +00003697
3698 std::string LibPath = "/usr/lib/";
3699 switch (Triple.getArch()) {
3700 case llvm::Triple::x86:
3701 case llvm::Triple::sparc:
3702 break;
3703 case llvm::Triple::x86_64:
3704 LibPath += "amd64/";
3705 break;
3706 case llvm::Triple::sparcv9:
3707 LibPath += "sparcv9/";
3708 break;
3709 default:
3710 llvm_unreachable("Unsupported architecture");
3711 }
3712
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003713 addPathIfExists(D, getDriver().SysRoot + LibPath, Paths);
David Chisnallf571cde2012-02-15 13:39:01 +00003714}
3715
Rafael Espindola7cf32212013-03-20 03:05:54 +00003716Tool *Solaris::buildAssembler() const {
Douglas Katzman95354292015-06-23 20:42:09 +00003717 return new tools::solaris::Assembler(*this);
Rafael Espindola7cf32212013-03-20 03:05:54 +00003718}
3719
Douglas Katzman95354292015-06-23 20:42:09 +00003720Tool *Solaris::buildLinker() const { return new tools::solaris::Linker(*this); }
Edward O'Callaghan856e4ff2009-08-22 01:06:46 +00003721
Rafael Espindolad5117262015-09-09 13:36:00 +00003722void Solaris::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
3723 ArgStringList &CC1Args) const {
3724 if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
3725 DriverArgs.hasArg(options::OPT_nostdincxx))
3726 return;
3727
3728 // Include the support directory for things like xlocale and fudged system
3729 // headers.
3730 addSystemInclude(DriverArgs, CC1Args, "/usr/include/c++/v1/support/solaris");
3731
3732 if (GCCInstallation.isValid()) {
3733 GCCVersion Version = GCCInstallation.getVersion();
3734 addSystemInclude(DriverArgs, CC1Args,
3735 getDriver().SysRoot + "/usr/gcc/" +
3736 Version.MajorStr + "." +
3737 Version.MinorStr +
3738 "/include/c++/" + Version.Text);
3739 addSystemInclude(DriverArgs, CC1Args,
3740 getDriver().SysRoot + "/usr/gcc/" + Version.MajorStr +
3741 "." + Version.MinorStr + "/include/c++/" +
3742 Version.Text + "/" +
3743 GCCInstallation.getTriple().str());
3744 }
3745}
3746
Thomas Schwinge6d94da02013-03-28 19:02:48 +00003747/// Distribution (very bare-bones at the moment).
Eli Friedman5cd659f2009-05-26 07:52:18 +00003748
Thomas Schwinge6d94da02013-03-28 19:02:48 +00003749enum Distro {
Douglas Katzmana5df0c82015-06-22 20:55:31 +00003750 // NB: Releases of a particular Linux distro should be kept together
3751 // in this enum, because some tests are done by integer comparison against
3752 // the first and last known member in the family, e.g. IsRedHat().
Chandler Carruth6a4e8e32011-02-25 06:39:53 +00003753 ArchLinux,
Rafael Espindolac8f008f2010-11-07 20:14:31 +00003754 DebianLenny,
3755 DebianSqueeze,
Eli Friedmanf7600942011-06-02 21:36:53 +00003756 DebianWheezy,
Sylvestre Ledrubdef2892013-01-06 08:09:29 +00003757 DebianJessie,
Benjamin Kramer1a8fa8b2015-04-06 12:30:43 +00003758 DebianStretch,
Rafael Espindola12479842010-11-11 02:07:13 +00003759 Exherbo,
Chris Lattner84e38552011-05-22 05:36:06 +00003760 RHEL5,
3761 RHEL6,
Benjamin Kramer1a8fa8b2015-04-06 12:30:43 +00003762 RHEL7,
Rafael Espindola0d2cbc02013-10-25 18:09:41 +00003763 Fedora,
Rafael Espindola10a63c22013-07-03 14:14:00 +00003764 OpenSUSE,
Douglas Gregor0a36f4d2011-03-14 15:39:50 +00003765 UbuntuHardy,
3766 UbuntuIntrepid,
Rafael Espindola66b291a2010-11-10 05:00:22 +00003767 UbuntuJaunty,
Zhongxing Xu14776cf2010-11-15 09:01:52 +00003768 UbuntuKarmic,
Rafael Espindolac8f008f2010-11-07 20:14:31 +00003769 UbuntuLucid,
3770 UbuntuMaverick,
Ted Kremenek43d47cc2011-04-05 22:04:27 +00003771 UbuntuNatty,
Benjamin Kramerf90b5de2011-06-05 16:08:59 +00003772 UbuntuOneiric,
Benjamin Kramer7c3f09d2012-02-06 14:36:09 +00003773 UbuntuPrecise,
Rafael Espindola62e87702012-12-13 20:26:05 +00003774 UbuntuQuantal,
3775 UbuntuRaring,
Sylvestre Ledru93c47b72013-06-13 11:52:27 +00003776 UbuntuSaucy,
Sylvestre Ledruaaf01a72013-11-07 09:31:30 +00003777 UbuntuTrusty,
Benjamin Kramer1a8fa8b2015-04-06 12:30:43 +00003778 UbuntuUtopic,
3779 UbuntuVivid,
Benjamin Kramer2d469802015-07-09 15:31:17 +00003780 UbuntuWily,
Sylvestre Ledru43b95712015-10-29 17:27:55 +00003781 UbuntuXenial,
Sylvestre Ledrud3078e72016-07-19 14:00:57 +00003782 UbuntuYakkety,
Rafael Espindolac8f008f2010-11-07 20:14:31 +00003783 UnknownDistro
3784};
3785
Thomas Schwinge6d94da02013-03-28 19:02:48 +00003786static bool IsRedhat(enum Distro Distro) {
Rafael Espindola52fe8962016-05-09 13:13:50 +00003787 return Distro == Fedora || (Distro >= RHEL5 && Distro <= RHEL7);
Rafael Espindolac8f008f2010-11-07 20:14:31 +00003788}
3789
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003790static bool IsOpenSUSE(enum Distro Distro) { return Distro == OpenSUSE; }
Rafael Espindolac8f008f2010-11-07 20:14:31 +00003791
Thomas Schwinge6d94da02013-03-28 19:02:48 +00003792static bool IsDebian(enum Distro Distro) {
Benjamin Kramer1a8fa8b2015-04-06 12:30:43 +00003793 return Distro >= DebianLenny && Distro <= DebianStretch;
Rafael Espindolac8f008f2010-11-07 20:14:31 +00003794}
3795
Thomas Schwinge6d94da02013-03-28 19:02:48 +00003796static bool IsUbuntu(enum Distro Distro) {
Sylvestre Ledrud3078e72016-07-19 14:00:57 +00003797 return Distro >= UbuntuHardy && Distro <= UbuntuYakkety;
Rafael Espindolac8f008f2010-11-07 20:14:31 +00003798}
3799
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003800static Distro DetectDistro(const Driver &D, llvm::Triple::ArchType Arch) {
Rafael Espindola2d2b4202014-07-06 17:43:24 +00003801 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> File =
3802 llvm::MemoryBuffer::getFile("/etc/lsb-release");
3803 if (File) {
Chris Lattner0e62c1c2011-07-23 10:55:15 +00003804 StringRef Data = File.get()->getBuffer();
Hans Wennborg3b7dd8d2014-08-11 18:09:32 +00003805 SmallVector<StringRef, 16> Lines;
Rafael Espindolac8f008f2010-11-07 20:14:31 +00003806 Data.split(Lines, "\n");
Thomas Schwinge6d94da02013-03-28 19:02:48 +00003807 Distro Version = UnknownDistro;
Benjamin Kramer72e64312015-09-24 14:48:49 +00003808 for (StringRef Line : Lines)
Douglas Katzman6bbffc42015-06-25 18:51:37 +00003809 if (Version == UnknownDistro && Line.startswith("DISTRIB_CODENAME="))
3810 Version = llvm::StringSwitch<Distro>(Line.substr(17))
3811 .Case("hardy", UbuntuHardy)
3812 .Case("intrepid", UbuntuIntrepid)
3813 .Case("jaunty", UbuntuJaunty)
3814 .Case("karmic", UbuntuKarmic)
3815 .Case("lucid", UbuntuLucid)
3816 .Case("maverick", UbuntuMaverick)
3817 .Case("natty", UbuntuNatty)
3818 .Case("oneiric", UbuntuOneiric)
3819 .Case("precise", UbuntuPrecise)
3820 .Case("quantal", UbuntuQuantal)
3821 .Case("raring", UbuntuRaring)
3822 .Case("saucy", UbuntuSaucy)
3823 .Case("trusty", UbuntuTrusty)
3824 .Case("utopic", UbuntuUtopic)
3825 .Case("vivid", UbuntuVivid)
Benjamin Kramer2d469802015-07-09 15:31:17 +00003826 .Case("wily", UbuntuWily)
Sylvestre Ledru43b95712015-10-29 17:27:55 +00003827 .Case("xenial", UbuntuXenial)
Sylvestre Ledrud3078e72016-07-19 14:00:57 +00003828 .Case("yakkety", UbuntuYakkety)
Douglas Katzman6bbffc42015-06-25 18:51:37 +00003829 .Default(UnknownDistro);
Rafael Espindola52fe8962016-05-09 13:13:50 +00003830 if (Version != UnknownDistro)
3831 return Version;
Rafael Espindolac8f008f2010-11-07 20:14:31 +00003832 }
3833
Rafael Espindola2d2b4202014-07-06 17:43:24 +00003834 File = llvm::MemoryBuffer::getFile("/etc/redhat-release");
3835 if (File) {
Chris Lattner0e62c1c2011-07-23 10:55:15 +00003836 StringRef Data = File.get()->getBuffer();
Rafael Espindola0d2cbc02013-10-25 18:09:41 +00003837 if (Data.startswith("Fedora release"))
3838 return Fedora;
Benjamin Kramer6af073b2014-05-05 12:39:32 +00003839 if (Data.startswith("Red Hat Enterprise Linux") ||
Rafael Espindola52fe8962016-05-09 13:13:50 +00003840 Data.startswith("CentOS") ||
3841 Data.startswith("Scientific Linux")) {
Benjamin Kramer1a8fa8b2015-04-06 12:30:43 +00003842 if (Data.find("release 7") != StringRef::npos)
3843 return RHEL7;
3844 else if (Data.find("release 6") != StringRef::npos)
Benjamin Kramer6af073b2014-05-05 12:39:32 +00003845 return RHEL6;
3846 else if (Data.find("release 5") != StringRef::npos)
3847 return RHEL5;
Benjamin Kramer6af073b2014-05-05 12:39:32 +00003848 }
Rafael Espindolac8f008f2010-11-07 20:14:31 +00003849 return UnknownDistro;
3850 }
3851
Rafael Espindola2d2b4202014-07-06 17:43:24 +00003852 File = llvm::MemoryBuffer::getFile("/etc/debian_version");
3853 if (File) {
Chris Lattner0e62c1c2011-07-23 10:55:15 +00003854 StringRef Data = File.get()->getBuffer();
Rafael Espindolac8f008f2010-11-07 20:14:31 +00003855 if (Data[0] == '5')
3856 return DebianLenny;
Rafael Espindola1510c852011-12-28 18:17:14 +00003857 else if (Data.startswith("squeeze/sid") || Data[0] == '6')
Rafael Espindolac8f008f2010-11-07 20:14:31 +00003858 return DebianSqueeze;
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003859 else if (Data.startswith("wheezy/sid") || Data[0] == '7')
Eli Friedmanf7600942011-06-02 21:36:53 +00003860 return DebianWheezy;
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003861 else if (Data.startswith("jessie/sid") || Data[0] == '8')
Sylvestre Ledrubdef2892013-01-06 08:09:29 +00003862 return DebianJessie;
Benjamin Kramer1a8fa8b2015-04-06 12:30:43 +00003863 else if (Data.startswith("stretch/sid") || Data[0] == '9')
3864 return DebianStretch;
Rafael Espindolac8f008f2010-11-07 20:14:31 +00003865 return UnknownDistro;
3866 }
3867
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003868 if (D.getVFS().exists("/etc/SuSE-release"))
Rafael Espindola10a63c22013-07-03 14:14:00 +00003869 return OpenSUSE;
Rafael Espindolac8f008f2010-11-07 20:14:31 +00003870
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003871 if (D.getVFS().exists("/etc/exherbo-release"))
Rafael Espindola12479842010-11-11 02:07:13 +00003872 return Exherbo;
3873
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003874 if (D.getVFS().exists("/etc/arch-release"))
Chandler Carruth6a4e8e32011-02-25 06:39:53 +00003875 return ArchLinux;
3876
Rafael Espindolac8f008f2010-11-07 20:14:31 +00003877 return UnknownDistro;
3878}
3879
Chandler Carruthfb7fa242011-10-31 08:42:24 +00003880/// \brief Get our best guess at the multiarch triple for a target.
3881///
3882/// Debian-based systems are starting to use a multiarch setup where they use
3883/// a target-triple directory in the library and header search paths.
3884/// Unfortunately, this triple does not align with the vanilla target triple,
3885/// so we provide a rough mapping here.
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003886static std::string getMultiarchTriple(const Driver &D,
3887 const llvm::Triple &TargetTriple,
Chandler Carruthfb7fa242011-10-31 08:42:24 +00003888 StringRef SysRoot) {
Eric Christopherefef8ef2015-12-07 22:43:05 +00003889 llvm::Triple::EnvironmentType TargetEnvironment =
3890 TargetTriple.getEnvironment();
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003891
Chandler Carruthfb7fa242011-10-31 08:42:24 +00003892 // For most architectures, just use whatever we have rather than trying to be
3893 // clever.
3894 switch (TargetTriple.getArch()) {
3895 default:
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003896 break;
Chandler Carruthfb7fa242011-10-31 08:42:24 +00003897
Douglas Katzmana67e50c2015-06-26 15:47:46 +00003898 // We use the existence of '/lib/<triple>' as a directory to detect some
3899 // common linux triples that don't quite match the Clang triple for both
3900 // 32-bit and 64-bit targets. Multiarch fixes its install triples to these
3901 // regardless of what the actual target triple is.
Chad Rosier4dce73a2012-07-11 19:08:21 +00003902 case llvm::Triple::arm:
3903 case llvm::Triple::thumb:
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003904 if (TargetEnvironment == llvm::Triple::GNUEABIHF) {
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003905 if (D.getVFS().exists(SysRoot + "/lib/arm-linux-gnueabihf"))
Jiangning Liu61b06cb2012-07-31 08:06:29 +00003906 return "arm-linux-gnueabihf";
3907 } else {
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003908 if (D.getVFS().exists(SysRoot + "/lib/arm-linux-gnueabi"))
Jiangning Liu61b06cb2012-07-31 08:06:29 +00003909 return "arm-linux-gnueabi";
3910 }
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003911 break;
Christian Pirkerf01cd6f2014-03-28 14:40:46 +00003912 case llvm::Triple::armeb:
3913 case llvm::Triple::thumbeb:
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003914 if (TargetEnvironment == llvm::Triple::GNUEABIHF) {
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003915 if (D.getVFS().exists(SysRoot + "/lib/armeb-linux-gnueabihf"))
Christian Pirkerf01cd6f2014-03-28 14:40:46 +00003916 return "armeb-linux-gnueabihf";
3917 } else {
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003918 if (D.getVFS().exists(SysRoot + "/lib/armeb-linux-gnueabi"))
Christian Pirkerf01cd6f2014-03-28 14:40:46 +00003919 return "armeb-linux-gnueabi";
3920 }
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003921 break;
Chandler Carruthfb7fa242011-10-31 08:42:24 +00003922 case llvm::Triple::x86:
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003923 if (D.getVFS().exists(SysRoot + "/lib/i386-linux-gnu"))
Chandler Carruthfb7fa242011-10-31 08:42:24 +00003924 return "i386-linux-gnu";
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003925 break;
Chandler Carruthfb7fa242011-10-31 08:42:24 +00003926 case llvm::Triple::x86_64:
Zinovy Nis1db95732014-07-10 15:27:19 +00003927 // We don't want this for x32, otherwise it will match x86_64 libs
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003928 if (TargetEnvironment != llvm::Triple::GNUX32 &&
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003929 D.getVFS().exists(SysRoot + "/lib/x86_64-linux-gnu"))
Chandler Carruthfb7fa242011-10-31 08:42:24 +00003930 return "x86_64-linux-gnu";
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003931 break;
Tim Northover9bb857a2013-01-31 12:13:10 +00003932 case llvm::Triple::aarch64:
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003933 if (D.getVFS().exists(SysRoot + "/lib/aarch64-linux-gnu"))
Tim Northover9bb857a2013-01-31 12:13:10 +00003934 return "aarch64-linux-gnu";
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003935 break;
Christian Pirkera74c7912014-03-14 12:15:45 +00003936 case llvm::Triple::aarch64_be:
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003937 if (D.getVFS().exists(SysRoot + "/lib/aarch64_be-linux-gnu"))
Christian Pirkera74c7912014-03-14 12:15:45 +00003938 return "aarch64_be-linux-gnu";
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003939 break;
Eli Friedman27b8c4f2011-11-08 19:43:37 +00003940 case llvm::Triple::mips:
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003941 if (D.getVFS().exists(SysRoot + "/lib/mips-linux-gnu"))
Eli Friedman27b8c4f2011-11-08 19:43:37 +00003942 return "mips-linux-gnu";
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003943 break;
Eli Friedman27b8c4f2011-11-08 19:43:37 +00003944 case llvm::Triple::mipsel:
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003945 if (D.getVFS().exists(SysRoot + "/lib/mipsel-linux-gnu"))
Eli Friedman27b8c4f2011-11-08 19:43:37 +00003946 return "mipsel-linux-gnu";
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003947 break;
Simon Atanasyan3a46afa2014-06-24 19:00:12 +00003948 case llvm::Triple::mips64:
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003949 if (D.getVFS().exists(SysRoot + "/lib/mips64-linux-gnu"))
Simon Atanasyan3a46afa2014-06-24 19:00:12 +00003950 return "mips64-linux-gnu";
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003951 if (D.getVFS().exists(SysRoot + "/lib/mips64-linux-gnuabi64"))
Simon Atanasyan3a46afa2014-06-24 19:00:12 +00003952 return "mips64-linux-gnuabi64";
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003953 break;
Simon Atanasyan3a46afa2014-06-24 19:00:12 +00003954 case llvm::Triple::mips64el:
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003955 if (D.getVFS().exists(SysRoot + "/lib/mips64el-linux-gnu"))
Simon Atanasyan3a46afa2014-06-24 19:00:12 +00003956 return "mips64el-linux-gnu";
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003957 if (D.getVFS().exists(SysRoot + "/lib/mips64el-linux-gnuabi64"))
Simon Atanasyan3a46afa2014-06-24 19:00:12 +00003958 return "mips64el-linux-gnuabi64";
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003959 break;
Chandler Carruthaf3c2092012-02-26 09:03:21 +00003960 case llvm::Triple::ppc:
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003961 if (D.getVFS().exists(SysRoot + "/lib/powerpc-linux-gnuspe"))
Sylvestre Ledrue0bf5812013-03-15 16:22:43 +00003962 return "powerpc-linux-gnuspe";
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003963 if (D.getVFS().exists(SysRoot + "/lib/powerpc-linux-gnu"))
Chandler Carruthaf3c2092012-02-26 09:03:21 +00003964 return "powerpc-linux-gnu";
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003965 break;
Chandler Carruthaf3c2092012-02-26 09:03:21 +00003966 case llvm::Triple::ppc64:
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003967 if (D.getVFS().exists(SysRoot + "/lib/powerpc64-linux-gnu"))
Chandler Carruthaf3c2092012-02-26 09:03:21 +00003968 return "powerpc64-linux-gnu";
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003969 break;
Bill Schmidt778d3872013-07-26 01:36:11 +00003970 case llvm::Triple::ppc64le:
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003971 if (D.getVFS().exists(SysRoot + "/lib/powerpc64le-linux-gnu"))
Bill Schmidt778d3872013-07-26 01:36:11 +00003972 return "powerpc64le-linux-gnu";
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003973 break;
James Y Knightc0aeadf2015-06-04 15:36:30 +00003974 case llvm::Triple::sparc:
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003975 if (D.getVFS().exists(SysRoot + "/lib/sparc-linux-gnu"))
James Y Knightc0aeadf2015-06-04 15:36:30 +00003976 return "sparc-linux-gnu";
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003977 break;
James Y Knightc0aeadf2015-06-04 15:36:30 +00003978 case llvm::Triple::sparcv9:
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003979 if (D.getVFS().exists(SysRoot + "/lib/sparc64-linux-gnu"))
James Y Knightc0aeadf2015-06-04 15:36:30 +00003980 return "sparc64-linux-gnu";
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003981 break;
Sylvestre Ledruc0babf22015-08-28 12:26:09 +00003982 case llvm::Triple::systemz:
Benjamin Kramerd45b2052015-10-07 15:48:01 +00003983 if (D.getVFS().exists(SysRoot + "/lib/s390x-linux-gnu"))
Sylvestre Ledruc0babf22015-08-28 12:26:09 +00003984 return "s390x-linux-gnu";
3985 break;
Chandler Carruthfb7fa242011-10-31 08:42:24 +00003986 }
Douglas Katzmanecddb3a2015-06-26 18:37:15 +00003987 return TargetTriple.str();
Chandler Carruthfb7fa242011-10-31 08:42:24 +00003988}
3989
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00003990static StringRef getOSLibDir(const llvm::Triple &Triple, const ArgList &Args) {
Chandler Carruthda797042013-10-29 10:27:30 +00003991 if (isMipsArch(Triple.getArch())) {
Simon Atanasyan603018a2016-07-19 07:09:48 +00003992 if (Triple.isAndroid()) {
3993 StringRef CPUName;
3994 StringRef ABIName;
3995 tools::mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
3996 if (CPUName == "mips32r6")
3997 return "libr6";
3998 if (CPUName == "mips32r2")
3999 return "libr2";
4000 }
Chandler Carruthda797042013-10-29 10:27:30 +00004001 // lib32 directory has a special meaning on MIPS targets.
4002 // It contains N32 ABI binaries. Use this folder if produce
4003 // code for N32 ABI only.
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00004004 if (tools::mips::hasMipsAbiArg(Args, "n32"))
Chandler Carruthda797042013-10-29 10:27:30 +00004005 return "lib32";
4006 return Triple.isArch32Bit() ? "lib" : "lib64";
4007 }
Simon Atanasyand4413882012-09-14 11:27:24 +00004008
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00004009 // It happens that only x86 and PPC use the 'lib32' variant of oslibdir, and
Chandler Carruthda797042013-10-29 10:27:30 +00004010 // using that variant while targeting other architectures causes problems
4011 // because the libraries are laid out in shared system roots that can't cope
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00004012 // with a 'lib32' library search path being considered. So we only enable
Chandler Carruthda797042013-10-29 10:27:30 +00004013 // them when we know we may need it.
4014 //
4015 // FIXME: This is a bit of a hack. We should really unify this code for
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00004016 // reasoning about oslibdir spellings with the lib dir spellings in the
Chandler Carruthda797042013-10-29 10:27:30 +00004017 // GCCInstallationDetector, but that is a more significant refactoring.
4018 if (Triple.getArch() == llvm::Triple::x86 ||
4019 Triple.getArch() == llvm::Triple::ppc)
Simon Atanasyand4413882012-09-14 11:27:24 +00004020 return "lib32";
4021
Zinovy Nis1db95732014-07-10 15:27:19 +00004022 if (Triple.getArch() == llvm::Triple::x86_64 &&
4023 Triple.getEnvironment() == llvm::Triple::GNUX32)
4024 return "libx32";
4025
Simon Atanasyand4413882012-09-14 11:27:24 +00004026 return Triple.isArch32Bit() ? "lib" : "lib64";
4027}
4028
Simon Atanasyan2834a222016-05-22 18:18:07 +00004029static void addMultilibsFilePaths(const Driver &D, const MultilibSet &Multilibs,
4030 const Multilib &Multilib,
4031 StringRef InstallPath,
4032 ToolChain::path_list &Paths) {
4033 if (const auto &PathsCallback = Multilibs.filePathsCallback())
4034 for (const auto &Path : PathsCallback(Multilib))
4035 addPathIfExists(D, InstallPath + Path, Paths);
4036}
4037
Rafael Espindola1af7c212012-02-19 01:38:32 +00004038Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004039 : Generic_ELF(D, Triple, Args) {
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004040 GCCInstallation.init(Triple, Args);
4041 CudaInstallation.init(Triple, Args);
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00004042 Multilibs = GCCInstallation.getMultilibs();
Chandler Carruth96bae7b2012-01-24 20:08:17 +00004043 llvm::Triple::ArchType Arch = Triple.getArch();
Simon Atanasyana0d89572013-10-05 14:37:55 +00004044 std::string SysRoot = computeSysRoot();
Rafael Espindolac8f008f2010-11-07 20:14:31 +00004045
Rafael Espindola10a63c22013-07-03 14:14:00 +00004046 // Cross-compiling binutils and GCC installations (vanilla and openSUSE at
Chandler Carruthd6c62b62013-06-20 23:37:54 +00004047 // least) put various tools in a triple-prefixed directory off of the parent
4048 // of the GCC installation. We use the GCC triple here to ensure that we end
4049 // up with tools that support the same amount of cross compiling as the
4050 // detected GCC installation. For example, if we find a GCC installation
4051 // targeting x86_64, but it is a bi-arch GCC installation, it can also be
4052 // used to target i386.
4053 // FIXME: This seems unlikely to be Linux-specific.
Rafael Espindola5f344ff2011-09-01 16:25:49 +00004054 ToolChain::path_list &PPaths = getProgramPaths();
Chandler Carruth4be70dd2011-11-06 09:21:54 +00004055 PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + "/../" +
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004056 GCCInstallation.getTriple().str() + "/bin")
4057 .str());
Rafael Espindola5f344ff2011-09-01 16:25:49 +00004058
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004059 Distro Distro = DetectDistro(D, Arch);
Rafael Espindolac8f008f2010-11-07 20:14:31 +00004060
Rafael Espindola10a63c22013-07-03 14:14:00 +00004061 if (IsOpenSUSE(Distro) || IsUbuntu(Distro)) {
Rafael Espindolac5688622010-11-08 14:48:47 +00004062 ExtraOpts.push_back("-z");
4063 ExtraOpts.push_back("relro");
4064 }
Rafael Espindolac8f008f2010-11-07 20:14:31 +00004065
Douglas Gregord9bb1522011-03-06 19:11:49 +00004066 if (Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb)
Rafael Espindolac8f008f2010-11-07 20:14:31 +00004067 ExtraOpts.push_back("-X");
4068
Evgeniy Stepanov14deb7b2015-10-08 21:21:44 +00004069 const bool IsAndroid = Triple.isAndroid();
Simon Atanasyan08450bd2013-04-20 08:15:03 +00004070 const bool IsMips = isMipsArch(Arch);
4071
4072 if (IsMips && !SysRoot.empty())
4073 ExtraOpts.push_back("--sysroot=" + SysRoot);
Evgeniy Stepanov2ca1aa52012-01-13 09:30:38 +00004074
Chandler Carruth0b842912011-12-09 04:45:18 +00004075 // Do not use 'gnu' hash style for Mips targets because .gnu.hash
4076 // and the MIPS ABI require .dynsym to be sorted in different ways.
4077 // .gnu.hash needs symbols to be grouped by hash code whereas the MIPS
4078 // ABI requires a mapping between the GOT and the symbol table.
Evgeniy Stepanov2ca1aa52012-01-13 09:30:38 +00004079 // Android loader does not support .gnu.hash.
Simon Atanasyan08450bd2013-04-20 08:15:03 +00004080 if (!IsMips && !IsAndroid) {
Rafael Espindola10a63c22013-07-03 14:14:00 +00004081 if (IsRedhat(Distro) || IsOpenSUSE(Distro) ||
Benjamin Kramer7c3f09d2012-02-06 14:36:09 +00004082 (IsUbuntu(Distro) && Distro >= UbuntuMaverick))
Chandler Carruth0b842912011-12-09 04:45:18 +00004083 ExtraOpts.push_back("--hash-style=gnu");
4084
Rafael Espindola10a63c22013-07-03 14:14:00 +00004085 if (IsDebian(Distro) || IsOpenSUSE(Distro) || Distro == UbuntuLucid ||
Chandler Carruth0b842912011-12-09 04:45:18 +00004086 Distro == UbuntuJaunty || Distro == UbuntuKarmic)
4087 ExtraOpts.push_back("--hash-style=both");
4088 }
Rafael Espindolac8f008f2010-11-07 20:14:31 +00004089
Rafael Espindola52fe8962016-05-09 13:13:50 +00004090 if (IsRedhat(Distro) && Distro != RHEL5 && Distro != RHEL6)
Rafael Espindolac8f008f2010-11-07 20:14:31 +00004091 ExtraOpts.push_back("--no-add-needed");
4092
Rafael Espindola5ed89d42016-06-03 17:26:16 +00004093#ifdef ENABLE_LINKER_BUILD_ID
4094 ExtraOpts.push_back("--build-id");
4095#endif
Rafael Espindolac8f008f2010-11-07 20:14:31 +00004096
Rafael Espindola10a63c22013-07-03 14:14:00 +00004097 if (IsOpenSUSE(Distro))
Chandler Carruthe5d9d902011-05-24 07:51:17 +00004098 ExtraOpts.push_back("--enable-new-dtags");
Chris Lattnerd075c822011-05-22 16:45:07 +00004099
Chandler Carruth413e5ac2011-10-03 05:28:29 +00004100 // The selection of paths to try here is designed to match the patterns which
4101 // the GCC driver itself uses, as this is part of the GCC-compatible driver.
4102 // This was determined by running GCC in a fake filesystem, creating all
4103 // possible permutations of these directories, and seeing which ones it added
4104 // to the link paths.
4105 path_list &Paths = getFilePaths();
Chandler Carruth6a4e8e32011-02-25 06:39:53 +00004106
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00004107 const std::string OSLibDir = getOSLibDir(Triple, Args);
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004108 const std::string MultiarchTriple = getMultiarchTriple(D, Triple, SysRoot);
Chandler Carruth413e5ac2011-10-03 05:28:29 +00004109
Chandler Carruthd0b93d62011-11-06 23:09:05 +00004110 // Add the multilib suffixed paths where they are available.
4111 if (GCCInstallation.isValid()) {
Chandler Carruth4d9d7682012-01-24 19:28:29 +00004112 const llvm::Triple &GCCTriple = GCCInstallation.getTriple();
Chandler Carruth96bae7b2012-01-24 20:08:17 +00004113 const std::string &LibPath = GCCInstallation.getParentLibPath();
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00004114 const Multilib &Multilib = GCCInstallation.getMultilib();
Simon Atanasyan2834a222016-05-22 18:18:07 +00004115 const MultilibSet &Multilibs = GCCInstallation.getMultilibs();
4116
4117 // Add toolchain / multilib specific file paths.
4118 addMultilibsFilePaths(D, Multilibs, Multilib,
4119 GCCInstallation.getInstallPath(), Paths);
Simon Atanasyan53fefd12012-10-03 17:46:38 +00004120
Chandler Carruth7f8042c2013-07-31 00:37:07 +00004121 // Sourcery CodeBench MIPS toolchain holds some libraries under
Chandler Carruth9b6ce932013-10-29 02:27:56 +00004122 // a biarch-like suffix of the GCC installation.
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004123 addPathIfExists(D, GCCInstallation.getInstallPath() + Multilib.gccSuffix(),
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00004124 Paths);
Chandler Carruth7f8042c2013-07-31 00:37:07 +00004125
4126 // GCC cross compiling toolchains will install target libraries which ship
4127 // as part of the toolchain under <prefix>/<triple>/<libdir> rather than as
4128 // any part of the GCC installation in
4129 // <prefix>/<libdir>/gcc/<triple>/<version>. This decision is somewhat
4130 // debatable, but is the reality today. We need to search this tree even
4131 // when we have a sysroot somewhere else. It is the responsibility of
Alp Tokerf6a24ce2013-12-05 16:25:25 +00004132 // whomever is doing the cross build targeting a sysroot using a GCC
Chandler Carruth7f8042c2013-07-31 00:37:07 +00004133 // installation that is *not* within the system root to ensure two things:
4134 //
4135 // 1) Any DSOs that are linked in from this tree or from the install path
Alexander Potapenkoc8e749a2014-09-01 12:35:57 +00004136 // above must be present on the system root and found via an
Chandler Carruth7f8042c2013-07-31 00:37:07 +00004137 // appropriate rpath.
4138 // 2) There must not be libraries installed into
4139 // <prefix>/<triple>/<libdir> unless they should be preferred over
4140 // those within the system root.
4141 //
4142 // Note that this matches the GCC behavior. See the below comment for where
4143 // Clang diverges from GCC's behavior.
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004144 addPathIfExists(D, LibPath + "/../" + GCCTriple.str() + "/lib/../" +
4145 OSLibDir + Multilib.osSuffix(),
Chandler Carruth7f8042c2013-07-31 00:37:07 +00004146 Paths);
4147
Chandler Carruth69a125b2012-04-06 16:32:06 +00004148 // If the GCC installation we found is inside of the sysroot, we want to
4149 // prefer libraries installed in the parent prefix of the GCC installation.
4150 // It is important to *not* use these paths when the GCC installation is
Gabor Greif5d3231c2012-04-18 10:59:08 +00004151 // outside of the system root as that can pick up unintended libraries.
Chandler Carruth69a125b2012-04-06 16:32:06 +00004152 // This usually happens when there is an external cross compiler on the
4153 // host system, and a more minimal sysroot available that is the target of
Chandler Carruth7f8042c2013-07-31 00:37:07 +00004154 // the cross. Note that GCC does include some of these directories in some
4155 // configurations but this seems somewhere between questionable and simply
4156 // a bug.
Chandler Carruth69a125b2012-04-06 16:32:06 +00004157 if (StringRef(LibPath).startswith(SysRoot)) {
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004158 addPathIfExists(D, LibPath + "/" + MultiarchTriple, Paths);
4159 addPathIfExists(D, LibPath + "/../" + OSLibDir, Paths);
Chandler Carruth69a125b2012-04-06 16:32:06 +00004160 }
Rafael Espindolac8f008f2010-11-07 20:14:31 +00004161 }
Chandler Carruth902efc62014-01-21 22:49:05 +00004162
4163 // Similar to the logic for GCC above, if we currently running Clang inside
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00004164 // of the requested system root, add its parent library paths to
Chandler Carruth902efc62014-01-21 22:49:05 +00004165 // those searched.
4166 // FIXME: It's not clear whether we should use the driver's installed
4167 // directory ('Dir' below) or the ResourceDir.
4168 if (StringRef(D.Dir).startswith(SysRoot)) {
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004169 addPathIfExists(D, D.Dir + "/../lib/" + MultiarchTriple, Paths);
4170 addPathIfExists(D, D.Dir + "/../" + OSLibDir, Paths);
Chandler Carruth902efc62014-01-21 22:49:05 +00004171 }
4172
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004173 addPathIfExists(D, SysRoot + "/lib/" + MultiarchTriple, Paths);
4174 addPathIfExists(D, SysRoot + "/lib/../" + OSLibDir, Paths);
4175 addPathIfExists(D, SysRoot + "/usr/lib/" + MultiarchTriple, Paths);
4176 addPathIfExists(D, SysRoot + "/usr/lib/../" + OSLibDir, Paths);
Chandler Carruthd0b93d62011-11-06 23:09:05 +00004177
Chandler Carruthb427c562013-06-22 11:35:51 +00004178 // Try walking via the GCC triple path in case of biarch or multiarch GCC
Chandler Carruthd0b93d62011-11-06 23:09:05 +00004179 // installations with strange symlinks.
Rafael Espindolab6250162013-10-25 17:06:04 +00004180 if (GCCInstallation.isValid()) {
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004181 addPathIfExists(D,
4182 SysRoot + "/usr/lib/" + GCCInstallation.getTriple().str() +
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004183 "/../../" + OSLibDir,
4184 Paths);
Rafael Espindola30490212011-06-03 15:39:42 +00004185
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00004186 // Add the 'other' biarch variant path
4187 Multilib BiarchSibling;
4188 if (GCCInstallation.getBiarchSibling(BiarchSibling)) {
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004189 addPathIfExists(D, GCCInstallation.getInstallPath() +
4190 BiarchSibling.gccSuffix(),
4191 Paths);
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00004192 }
Chandler Carruth69a125b2012-04-06 16:32:06 +00004193
Chandler Carruth7f8042c2013-07-31 00:37:07 +00004194 // See comments above on the multilib variant for details of why this is
4195 // included even from outside the sysroot.
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00004196 const std::string &LibPath = GCCInstallation.getParentLibPath();
4197 const llvm::Triple &GCCTriple = GCCInstallation.getTriple();
4198 const Multilib &Multilib = GCCInstallation.getMultilib();
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004199 addPathIfExists(D, LibPath + "/../" + GCCTriple.str() + "/lib" +
4200 Multilib.osSuffix(),
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004201 Paths);
Chandler Carruth7f8042c2013-07-31 00:37:07 +00004202
4203 // See comments above on the multilib variant for details of why this is
4204 // only included from within the sysroot.
4205 if (StringRef(LibPath).startswith(SysRoot))
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004206 addPathIfExists(D, LibPath, Paths);
Chandler Carruth413e5ac2011-10-03 05:28:29 +00004207 }
Chandler Carruth902efc62014-01-21 22:49:05 +00004208
4209 // Similar to the logic for GCC above, if we are currently running Clang
4210 // inside of the requested system root, add its parent library path to those
4211 // searched.
4212 // FIXME: It's not clear whether we should use the driver's installed
4213 // directory ('Dir' below) or the ResourceDir.
4214 if (StringRef(D.Dir).startswith(SysRoot))
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004215 addPathIfExists(D, D.Dir + "/../lib", Paths);
Chandler Carruth902efc62014-01-21 22:49:05 +00004216
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004217 addPathIfExists(D, SysRoot + "/lib", Paths);
4218 addPathIfExists(D, SysRoot + "/usr/lib", Paths);
Rafael Espindolac8f008f2010-11-07 20:14:31 +00004219}
4220
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004221bool Linux::HasNativeLLVMSupport() const { return true; }
Eli Friedman5cd659f2009-05-26 07:52:18 +00004222
Douglas Katzman95354292015-06-23 20:42:09 +00004223Tool *Linux::buildLinker() const { return new tools::gnutools::Linker(*this); }
Rafael Espindola7cf32212013-03-20 03:05:54 +00004224
4225Tool *Linux::buildAssembler() const {
Douglas Katzman95354292015-06-23 20:42:09 +00004226 return new tools::gnutools::Assembler(*this);
Rafael Espindola92b00932010-08-10 00:25:48 +00004227}
4228
Simon Atanasyana0d89572013-10-05 14:37:55 +00004229std::string Linux::computeSysRoot() const {
Simon Atanasyan08450bd2013-04-20 08:15:03 +00004230 if (!getDriver().SysRoot.empty())
4231 return getDriver().SysRoot;
4232
4233 if (!GCCInstallation.isValid() || !isMipsArch(getTriple().getArch()))
4234 return std::string();
4235
Simon Atanasyana61b7ec2013-10-10 07:57:44 +00004236 // Standalone MIPS toolchains use different names for sysroot folder
4237 // and put it into different places. Here we try to check some known
4238 // variants.
Simon Atanasyan08450bd2013-04-20 08:15:03 +00004239
Simon Atanasyana61b7ec2013-10-10 07:57:44 +00004240 const StringRef InstallDir = GCCInstallation.getInstallPath();
4241 const StringRef TripleStr = GCCInstallation.getTriple().str();
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00004242 const Multilib &Multilib = GCCInstallation.getMultilib();
Simon Atanasyana61b7ec2013-10-10 07:57:44 +00004243
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004244 std::string Path =
4245 (InstallDir + "/../../../../" + TripleStr + "/libc" + Multilib.osSuffix())
4246 .str();
Simon Atanasyana61b7ec2013-10-10 07:57:44 +00004247
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004248 if (getVFS().exists(Path))
Simon Atanasyana61b7ec2013-10-10 07:57:44 +00004249 return Path;
4250
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00004251 Path = (InstallDir + "/../../../../sysroot" + Multilib.osSuffix()).str();
Simon Atanasyana61b7ec2013-10-10 07:57:44 +00004252
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004253 if (getVFS().exists(Path))
Simon Atanasyana61b7ec2013-10-10 07:57:44 +00004254 return Path;
4255
4256 return std::string();
Simon Atanasyan08450bd2013-04-20 08:15:03 +00004257}
4258
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004259std::string Linux::getDynamicLinker(const ArgList &Args) const {
4260 const llvm::Triple::ArchType Arch = getArch();
4261 const llvm::Triple &Triple = getTriple();
4262
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004263 const enum Distro Distro = DetectDistro(getDriver(), Arch);
4264
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004265 if (Triple.isAndroid())
4266 return Triple.isArch64Bit() ? "/system/bin/linker64" : "/system/bin/linker";
Rafael Espindola0fa66802016-06-24 21:35:06 +00004267 else if (Triple.isMusl()) {
4268 std::string ArchName;
4269 switch (Arch) {
4270 case llvm::Triple::thumb:
4271 ArchName = "arm";
4272 break;
4273 case llvm::Triple::thumbeb:
4274 ArchName = "armeb";
4275 break;
4276 default:
4277 ArchName = Triple.getArchName().str();
4278 }
4279 if (Triple.getEnvironment() == llvm::Triple::MuslEABIHF)
4280 ArchName += "hf";
4281
4282 return "/lib/ld-musl-" + ArchName + ".so.1";
4283 }
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004284
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004285 std::string LibDir;
4286 std::string Loader;
4287
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004288 switch (Arch) {
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004289 default:
4290 llvm_unreachable("unsupported architecture");
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004291
4292 case llvm::Triple::aarch64:
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004293 LibDir = "lib";
4294 Loader = "ld-linux-aarch64.so.1";
4295 break;
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004296 case llvm::Triple::aarch64_be:
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004297 LibDir = "lib";
4298 Loader = "ld-linux-aarch64_be.so.1";
4299 break;
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004300 case llvm::Triple::arm:
4301 case llvm::Triple::thumb:
4302 case llvm::Triple::armeb:
4303 case llvm::Triple::thumbeb: {
Vedant Kumar5fb00e42016-07-27 23:01:55 +00004304 const bool HF =
4305 Triple.getEnvironment() == llvm::Triple::GNUEABIHF ||
4306 tools::arm::getARMFloatABI(*this, Args) == tools::arm::FloatABI::Hard;
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004307
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004308 LibDir = "lib";
4309 Loader = HF ? "ld-linux-armhf.so.3" : "ld-linux.so.3";
4310 break;
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004311 }
4312 case llvm::Triple::mips:
4313 case llvm::Triple::mipsel:
4314 case llvm::Triple::mips64:
4315 case llvm::Triple::mips64el: {
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004316 bool LE = (Triple.getArch() == llvm::Triple::mipsel) ||
4317 (Triple.getArch() == llvm::Triple::mips64el);
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004318 bool IsNaN2008 = tools::mips::isNaN2008(Args, Triple);
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004319
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004320 LibDir = "lib" + tools::mips::getMipsABILibSuffix(Args, Triple);
4321
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004322 if (tools::mips::isUCLibc(Args))
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004323 Loader = IsNaN2008 ? "ld-uClibc-mipsn8.so.0" : "ld-uClibc.so.0";
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004324 else if (!Triple.hasEnvironment() &&
4325 Triple.getVendor() == llvm::Triple::VendorType::MipsTechnologies)
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004326 Loader = LE ? "ld-musl-mipsel.so.1" : "ld-musl-mips.so.1";
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004327 else
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004328 Loader = IsNaN2008 ? "ld-linux-mipsn8.so.1" : "ld.so.1";
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004329
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004330 break;
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004331 }
4332 case llvm::Triple::ppc:
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004333 LibDir = "lib";
4334 Loader = "ld.so.1";
4335 break;
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004336 case llvm::Triple::ppc64:
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004337 LibDir = "lib64";
4338 Loader =
4339 (tools::ppc::hasPPCAbiArg(Args, "elfv2")) ? "ld64.so.2" : "ld64.so.1";
4340 break;
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004341 case llvm::Triple::ppc64le:
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004342 LibDir = "lib64";
4343 Loader =
4344 (tools::ppc::hasPPCAbiArg(Args, "elfv1")) ? "ld64.so.1" : "ld64.so.2";
4345 break;
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004346 case llvm::Triple::sparc:
4347 case llvm::Triple::sparcel:
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004348 LibDir = "lib";
4349 Loader = "ld-linux.so.2";
4350 break;
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004351 case llvm::Triple::sparcv9:
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004352 LibDir = "lib64";
4353 Loader = "ld-linux.so.2";
4354 break;
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004355 case llvm::Triple::systemz:
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004356 LibDir = "lib";
4357 Loader = "ld64.so.1";
4358 break;
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004359 case llvm::Triple::x86:
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004360 LibDir = "lib";
4361 Loader = "ld-linux.so.2";
4362 break;
4363 case llvm::Triple::x86_64: {
4364 bool X32 = Triple.getEnvironment() == llvm::Triple::GNUX32;
4365
4366 LibDir = X32 ? "libx32" : "lib64";
4367 Loader = X32 ? "ld-linux-x32.so.2" : "ld-linux-x86-64.so.2";
4368 break;
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004369 }
Saleem Abdulrasool6f8442b2016-05-23 02:17:28 +00004370 }
4371
4372 if (Distro == Exherbo && (Triple.getVendor() == llvm::Triple::UnknownVendor ||
4373 Triple.getVendor() == llvm::Triple::PC))
4374 return "/usr/" + Triple.str() + "/lib/" + Loader;
4375 return "/" + LibDir + "/" + Loader;
Saleem Abdulrasool783fc632016-05-22 03:12:19 +00004376}
4377
Chandler Carrutha796f532011-11-05 20:17:13 +00004378void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
4379 ArgStringList &CC1Args) const {
4380 const Driver &D = getDriver();
Simon Atanasyana0d89572013-10-05 14:37:55 +00004381 std::string SysRoot = computeSysRoot();
Chandler Carrutha796f532011-11-05 20:17:13 +00004382
4383 if (DriverArgs.hasArg(options::OPT_nostdinc))
4384 return;
4385
4386 if (!DriverArgs.hasArg(options::OPT_nostdlibinc))
Simon Atanasyan08450bd2013-04-20 08:15:03 +00004387 addSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/local/include");
Chandler Carrutha796f532011-11-05 20:17:13 +00004388
4389 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
Rafael Espindola358256c2013-06-26 02:13:00 +00004390 SmallString<128> P(D.ResourceDir);
4391 llvm::sys::path::append(P, "include");
Yaron Keren92e1b622015-03-18 10:17:07 +00004392 addSystemInclude(DriverArgs, CC1Args, P);
Chandler Carrutha796f532011-11-05 20:17:13 +00004393 }
4394
4395 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
4396 return;
4397
4398 // Check for configure-time C include directories.
4399 StringRef CIncludeDirs(C_INCLUDE_DIRS);
4400 if (CIncludeDirs != "") {
4401 SmallVector<StringRef, 5> dirs;
4402 CIncludeDirs.split(dirs, ":");
Simon Atanasyan6f657c42014-05-08 19:32:46 +00004403 for (StringRef dir : dirs) {
Benjamin Kramer33cd6dc2015-02-18 18:45:54 +00004404 StringRef Prefix =
4405 llvm::sys::path::is_absolute(dir) ? StringRef(SysRoot) : "";
Simon Atanasyan6f657c42014-05-08 19:32:46 +00004406 addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir);
Chandler Carrutha796f532011-11-05 20:17:13 +00004407 }
4408 return;
4409 }
4410
4411 // Lacking those, try to detect the correct set of system includes for the
4412 // target triple.
4413
Simon Atanasyan9e49e142014-08-06 05:44:47 +00004414 // Add include directories specific to the selected multilib set and multilib.
4415 if (GCCInstallation.isValid()) {
Benjamin Kramerac75baa2015-03-22 15:56:12 +00004416 const auto &Callback = Multilibs.includeDirsCallback();
Simon Atanasyan9e49e142014-08-06 05:44:47 +00004417 if (Callback) {
Simon Atanasyana45502d2016-05-19 15:07:21 +00004418 for (const auto &Path : Callback(GCCInstallation.getMultilib()))
4419 addExternCSystemIncludeIfExists(
4420 DriverArgs, CC1Args, GCCInstallation.getInstallPath() + Path);
Simon Atanasyan9e49e142014-08-06 05:44:47 +00004421 }
Simon Atanasyan08450bd2013-04-20 08:15:03 +00004422 }
4423
Chandler Carruth5b77c6c2011-11-06 08:21:07 +00004424 // Implement generic Debian multiarch support.
4425 const StringRef X86_64MultiarchIncludeDirs[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004426 "/usr/include/x86_64-linux-gnu",
Chandler Carruth5b77c6c2011-11-06 08:21:07 +00004427
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004428 // FIXME: These are older forms of multiarch. It's not clear that they're
4429 // in use in any released version of Debian, so we should consider
4430 // removing them.
4431 "/usr/include/i686-linux-gnu/64", "/usr/include/i486-linux-gnu/64"};
Chandler Carruth5b77c6c2011-11-06 08:21:07 +00004432 const StringRef X86MultiarchIncludeDirs[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004433 "/usr/include/i386-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/x86_64-linux-gnu/32", "/usr/include/i686-linux-gnu",
4439 "/usr/include/i486-linux-gnu"};
Tim Northover9bb857a2013-01-31 12:13:10 +00004440 const StringRef AArch64MultiarchIncludeDirs[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004441 "/usr/include/aarch64-linux-gnu"};
Chandler Carruth5b77c6c2011-11-06 08:21:07 +00004442 const StringRef ARMMultiarchIncludeDirs[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004443 "/usr/include/arm-linux-gnueabi"};
Jiangning Liu61b06cb2012-07-31 08:06:29 +00004444 const StringRef ARMHFMultiarchIncludeDirs[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004445 "/usr/include/arm-linux-gnueabihf"};
Saleem Abdulrasool20f733a2015-12-11 06:20:59 +00004446 const StringRef ARMEBMultiarchIncludeDirs[] = {
4447 "/usr/include/armeb-linux-gnueabi"};
4448 const StringRef ARMEBHFMultiarchIncludeDirs[] = {
4449 "/usr/include/armeb-linux-gnueabihf"};
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004450 const StringRef MIPSMultiarchIncludeDirs[] = {"/usr/include/mips-linux-gnu"};
Eli Friedman7771c832011-11-11 03:05:19 +00004451 const StringRef MIPSELMultiarchIncludeDirs[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004452 "/usr/include/mipsel-linux-gnu"};
Simon Atanasyan3a46afa2014-06-24 19:00:12 +00004453 const StringRef MIPS64MultiarchIncludeDirs[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004454 "/usr/include/mips64-linux-gnu", "/usr/include/mips64-linux-gnuabi64"};
Simon Atanasyan3a46afa2014-06-24 19:00:12 +00004455 const StringRef MIPS64ELMultiarchIncludeDirs[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004456 "/usr/include/mips64el-linux-gnu",
4457 "/usr/include/mips64el-linux-gnuabi64"};
Chandler Carruth2e9d7312012-02-26 09:21:43 +00004458 const StringRef PPCMultiarchIncludeDirs[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004459 "/usr/include/powerpc-linux-gnu"};
Chandler Carruth2e9d7312012-02-26 09:21:43 +00004460 const StringRef PPC64MultiarchIncludeDirs[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004461 "/usr/include/powerpc64-linux-gnu"};
Ulrich Weiganda8331b92014-06-20 13:41:24 +00004462 const StringRef PPC64LEMultiarchIncludeDirs[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004463 "/usr/include/powerpc64le-linux-gnu"};
James Y Knight09677ad2015-06-05 13:44:43 +00004464 const StringRef SparcMultiarchIncludeDirs[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004465 "/usr/include/sparc-linux-gnu"};
James Y Knight09677ad2015-06-05 13:44:43 +00004466 const StringRef Sparc64MultiarchIncludeDirs[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004467 "/usr/include/sparc64-linux-gnu"};
Sylvestre Ledruc0babf22015-08-28 12:26:09 +00004468 const StringRef SYSTEMZMultiarchIncludeDirs[] = {
4469 "/usr/include/s390x-linux-gnu"};
Chandler Carruth5b77c6c2011-11-06 08:21:07 +00004470 ArrayRef<StringRef> MultiarchIncludeDirs;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00004471 switch (getTriple().getArch()) {
4472 case llvm::Triple::x86_64:
Chandler Carruth5b77c6c2011-11-06 08:21:07 +00004473 MultiarchIncludeDirs = X86_64MultiarchIncludeDirs;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00004474 break;
4475 case llvm::Triple::x86:
Chandler Carruth5b77c6c2011-11-06 08:21:07 +00004476 MultiarchIncludeDirs = X86MultiarchIncludeDirs;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00004477 break;
4478 case llvm::Triple::aarch64:
4479 case llvm::Triple::aarch64_be:
Tim Northover9bb857a2013-01-31 12:13:10 +00004480 MultiarchIncludeDirs = AArch64MultiarchIncludeDirs;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00004481 break;
4482 case llvm::Triple::arm:
Saleem Abdulrasool20f733a2015-12-11 06:20:59 +00004483 case llvm::Triple::thumb:
Jiangning Liu61b06cb2012-07-31 08:06:29 +00004484 if (getTriple().getEnvironment() == llvm::Triple::GNUEABIHF)
4485 MultiarchIncludeDirs = ARMHFMultiarchIncludeDirs;
4486 else
4487 MultiarchIncludeDirs = ARMMultiarchIncludeDirs;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00004488 break;
Saleem Abdulrasool20f733a2015-12-11 06:20:59 +00004489 case llvm::Triple::armeb:
4490 case llvm::Triple::thumbeb:
4491 if (getTriple().getEnvironment() == llvm::Triple::GNUEABIHF)
4492 MultiarchIncludeDirs = ARMEBHFMultiarchIncludeDirs;
4493 else
4494 MultiarchIncludeDirs = ARMEBMultiarchIncludeDirs;
4495 break;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00004496 case llvm::Triple::mips:
Eli Friedman7771c832011-11-11 03:05:19 +00004497 MultiarchIncludeDirs = MIPSMultiarchIncludeDirs;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00004498 break;
4499 case llvm::Triple::mipsel:
Eli Friedman7771c832011-11-11 03:05:19 +00004500 MultiarchIncludeDirs = MIPSELMultiarchIncludeDirs;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00004501 break;
4502 case llvm::Triple::mips64:
Simon Atanasyan3a46afa2014-06-24 19:00:12 +00004503 MultiarchIncludeDirs = MIPS64MultiarchIncludeDirs;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00004504 break;
4505 case llvm::Triple::mips64el:
Simon Atanasyan3a46afa2014-06-24 19:00:12 +00004506 MultiarchIncludeDirs = MIPS64ELMultiarchIncludeDirs;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00004507 break;
4508 case llvm::Triple::ppc:
Chandler Carruth2e9d7312012-02-26 09:21:43 +00004509 MultiarchIncludeDirs = PPCMultiarchIncludeDirs;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00004510 break;
4511 case llvm::Triple::ppc64:
Chandler Carruth2e9d7312012-02-26 09:21:43 +00004512 MultiarchIncludeDirs = PPC64MultiarchIncludeDirs;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00004513 break;
4514 case llvm::Triple::ppc64le:
Ulrich Weiganda8331b92014-06-20 13:41:24 +00004515 MultiarchIncludeDirs = PPC64LEMultiarchIncludeDirs;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00004516 break;
4517 case llvm::Triple::sparc:
James Y Knight09677ad2015-06-05 13:44:43 +00004518 MultiarchIncludeDirs = SparcMultiarchIncludeDirs;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00004519 break;
4520 case llvm::Triple::sparcv9:
James Y Knight09677ad2015-06-05 13:44:43 +00004521 MultiarchIncludeDirs = Sparc64MultiarchIncludeDirs;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00004522 break;
Sylvestre Ledruc0babf22015-08-28 12:26:09 +00004523 case llvm::Triple::systemz:
4524 MultiarchIncludeDirs = SYSTEMZMultiarchIncludeDirs;
4525 break;
Douglas Katzman7e37afb2015-06-23 03:02:39 +00004526 default:
4527 break;
Chandler Carruth5b77c6c2011-11-06 08:21:07 +00004528 }
Simon Atanasyan6f657c42014-05-08 19:32:46 +00004529 for (StringRef Dir : MultiarchIncludeDirs) {
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004530 if (D.getVFS().exists(SysRoot + Dir)) {
Simon Atanasyan6f657c42014-05-08 19:32:46 +00004531 addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + Dir);
Chandler Carruth5b77c6c2011-11-06 08:21:07 +00004532 break;
4533 }
Chandler Carrutha796f532011-11-05 20:17:13 +00004534 }
4535
4536 if (getTriple().getOS() == llvm::Triple::RTEMS)
4537 return;
4538
Chandler Carruth475ab6a2011-11-08 17:19:47 +00004539 // Add an include of '/include' directly. This isn't provided by default by
4540 // system GCCs, but is often used with cross-compiling GCCs, and harmless to
4541 // add even when Clang is acting as-if it were a system compiler.
Simon Atanasyan08450bd2013-04-20 08:15:03 +00004542 addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/include");
Chandler Carruth475ab6a2011-11-08 17:19:47 +00004543
Simon Atanasyan08450bd2013-04-20 08:15:03 +00004544 addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include");
Chandler Carrutha796f532011-11-05 20:17:13 +00004545}
4546
Evgeniy Stepanov65bc2b12015-11-09 21:10:54 +00004547static std::string DetectLibcxxIncludePath(StringRef base) {
4548 std::error_code EC;
4549 int MaxVersion = 0;
4550 std::string MaxVersionString = "";
4551 for (llvm::sys::fs::directory_iterator LI(base, EC), LE; !EC && LI != LE;
4552 LI = LI.increment(EC)) {
4553 StringRef VersionText = llvm::sys::path::filename(LI->path());
4554 int Version;
4555 if (VersionText[0] == 'v' &&
4556 !VersionText.slice(1, StringRef::npos).getAsInteger(10, Version)) {
4557 if (Version > MaxVersion) {
4558 MaxVersion = Version;
4559 MaxVersionString = VersionText;
4560 }
4561 }
4562 }
4563 return MaxVersion ? (base + "/" + MaxVersionString).str() : "";
4564}
4565
Chandler Carrutha796f532011-11-05 20:17:13 +00004566void Linux::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
4567 ArgStringList &CC1Args) const {
4568 if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
4569 DriverArgs.hasArg(options::OPT_nostdincxx))
4570 return;
4571
Chandler Carruthf4701732011-11-07 09:01:17 +00004572 // Check if libc++ has been enabled and provide its include paths if so.
4573 if (GetCXXStdlibType(DriverArgs) == ToolChain::CST_Libcxx) {
Chandler Carruth5a3d8982014-01-20 09:42:24 +00004574 const std::string LibCXXIncludePathCandidates[] = {
Evgeniy Stepanov65bc2b12015-11-09 21:10:54 +00004575 DetectLibcxxIncludePath(getDriver().Dir + "/../include/c++"),
Yaron Keren5439b642016-05-17 19:01:16 +00004576 // If this is a development, non-installed, clang, libcxx will
4577 // not be found at ../include/c++ but it likely to be found at
4578 // one of the following two locations:
4579 DetectLibcxxIncludePath(getDriver().SysRoot + "/usr/local/include/c++"),
4580 DetectLibcxxIncludePath(getDriver().SysRoot + "/usr/include/c++") };
Simon Atanasyan6f657c42014-05-08 19:32:46 +00004581 for (const auto &IncludePath : LibCXXIncludePathCandidates) {
Evgeniy Stepanov65bc2b12015-11-09 21:10:54 +00004582 if (IncludePath.empty() || !getVFS().exists(IncludePath))
Chandler Carruth5a3d8982014-01-20 09:42:24 +00004583 continue;
4584 // Add the first candidate that exists.
Simon Atanasyan6f657c42014-05-08 19:32:46 +00004585 addSystemInclude(DriverArgs, CC1Args, IncludePath);
Chandler Carruth5a3d8982014-01-20 09:42:24 +00004586 break;
4587 }
Chandler Carruthf4701732011-11-07 09:01:17 +00004588 return;
4589 }
4590
Chandler Carrutha1f1fd32012-01-25 08:04:13 +00004591 // We need a detected GCC installation on Linux to provide libstdc++'s
4592 // headers. We handled the libc++ case above.
4593 if (!GCCInstallation.isValid())
4594 return;
Chandler Carrutha796f532011-11-05 20:17:13 +00004595
Chandler Carruthf5d4df92011-11-06 10:31:01 +00004596 // By default, look for the C++ headers in an include directory adjacent to
4597 // the lib directory of the GCC installation. Note that this is expect to be
4598 // equivalent to '/usr/include/c++/X.Y' in almost all cases.
4599 StringRef LibDir = GCCInstallation.getParentLibPath();
4600 StringRef InstallDir = GCCInstallation.getInstallPath();
Evgeniy Stepanov763671e2012-09-03 09:05:50 +00004601 StringRef TripleStr = GCCInstallation.getTriple().str();
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00004602 const Multilib &Multilib = GCCInstallation.getMultilib();
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004603 const std::string GCCMultiarchTriple = getMultiarchTriple(
4604 getDriver(), GCCInstallation.getTriple(), getDriver().SysRoot);
Chandler Carruthc44f4d42014-08-27 08:41:41 +00004605 const std::string TargetMultiarchTriple =
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004606 getMultiarchTriple(getDriver(), getTriple(), getDriver().SysRoot);
Chandler Carruth1f2b2f82013-08-26 08:59:53 +00004607 const GCCVersion &Version = GCCInstallation.getVersion();
Evgeniy Stepanov763671e2012-09-03 09:05:50 +00004608
Chandler Carruthc44f4d42014-08-27 08:41:41 +00004609 // The primary search for libstdc++ supports multiarch variants.
Chandler Carruth8677d922013-10-29 08:53:03 +00004610 if (addLibStdCXXIncludePaths(LibDir.str() + "/../include",
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004611 "/c++/" + Version.Text, TripleStr,
4612 GCCMultiarchTriple, TargetMultiarchTriple,
Jonathan Roelofs2cea1be2014-02-12 03:21:20 +00004613 Multilib.includeSuffix(), DriverArgs, CC1Args))
Dmitri Gribenko15225ae2013-03-06 17:14:05 +00004614 return;
4615
Chandler Carruthc44f4d42014-08-27 08:41:41 +00004616 // Otherwise, fall back on a bunch of options which don't use multiarch
4617 // layouts for simplicity.
Chandler Carruth5a3d8982014-01-20 09:42:24 +00004618 const std::string LibStdCXXIncludePathCandidates[] = {
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004619 // Gentoo is weird and places its headers inside the GCC install,
4620 // so if the first attempt to find the headers fails, try these patterns.
Chandler Carruth81296fb2016-05-08 07:59:56 +00004621 InstallDir.str() + "/include/g++-v" + Version.Text,
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004622 InstallDir.str() + "/include/g++-v" + Version.MajorStr + "." +
4623 Version.MinorStr,
4624 InstallDir.str() + "/include/g++-v" + Version.MajorStr,
4625 // Android standalone toolchain has C++ headers in yet another place.
4626 LibDir.str() + "/../" + TripleStr.str() + "/include/c++/" + Version.Text,
4627 // Freescale SDK C++ headers are directly in <sysroot>/usr/include/c++,
4628 // without a subdirectory corresponding to the gcc version.
4629 LibDir.str() + "/../include/c++",
Evgeniy Stepanov763671e2012-09-03 09:05:50 +00004630 };
4631
Simon Atanasyan6f657c42014-05-08 19:32:46 +00004632 for (const auto &IncludePath : LibStdCXXIncludePathCandidates) {
Chandler Carruthc44f4d42014-08-27 08:41:41 +00004633 if (addLibStdCXXIncludePaths(IncludePath, /*Suffix*/ "", TripleStr,
4634 /*GCCMultiarchTriple*/ "",
4635 /*TargetMultiarchTriple*/ "",
4636 Multilib.includeSuffix(), DriverArgs, CC1Args))
Evgeniy Stepanov763671e2012-09-03 09:05:50 +00004637 break;
Chandler Carruthf5d4df92011-11-06 10:31:01 +00004638 }
Chandler Carrutha796f532011-11-05 20:17:13 +00004639}
4640
Artem Belevichfa11ab52015-11-17 22:28:46 +00004641void Linux::AddCudaIncludeArgs(const ArgList &DriverArgs,
4642 ArgStringList &CC1Args) const {
4643 if (DriverArgs.hasArg(options::OPT_nocudainc))
4644 return;
4645
Justin Lebar423019d2016-04-16 00:11:11 +00004646 if (!CudaInstallation.isValid()) {
4647 getDriver().Diag(diag::err_drv_no_cuda_installation);
4648 return;
Artem Belevich86017332015-11-17 22:28:55 +00004649 }
Justin Lebar423019d2016-04-16 00:11:11 +00004650
4651 addSystemInclude(DriverArgs, CC1Args, CudaInstallation.getIncludePath());
4652 CC1Args.push_back("-include");
4653 CC1Args.push_back("__clang_cuda_runtime_wrapper.h");
Artem Belevichfa11ab52015-11-17 22:28:46 +00004654}
4655
Andrey Turetskiy4798eb62016-06-16 10:36:09 +00004656void Linux::AddIAMCUIncludeArgs(const ArgList &DriverArgs,
4657 ArgStringList &CC1Args) const {
4658 if (GCCInstallation.isValid()) {
4659 CC1Args.push_back("-isystem");
4660 CC1Args.push_back(DriverArgs.MakeArgString(
4661 GCCInstallation.getParentLibPath() + "/../" +
4662 GCCInstallation.getTriple().str() + "/include"));
4663 }
4664}
4665
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004666bool Linux::isPIEDefault() const { return getSanitizerArgs().requiresPIE(); }
Peter Collingbourne54d770c2013-04-09 04:35:11 +00004667
Alexey Samsonov7f2a0d22015-06-19 21:36:47 +00004668SanitizerMask Linux::getSupportedSanitizers() const {
4669 const bool IsX86 = getTriple().getArch() == llvm::Triple::x86;
4670 const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64;
4671 const bool IsMIPS64 = getTriple().getArch() == llvm::Triple::mips64 ||
4672 getTriple().getArch() == llvm::Triple::mips64el;
Jay Foade967dd02015-06-25 10:35:19 +00004673 const bool IsPowerPC64 = getTriple().getArch() == llvm::Triple::ppc64 ||
4674 getTriple().getArch() == llvm::Triple::ppc64le;
Adhemerval Zanella76aee672015-07-30 20:50:39 +00004675 const bool IsAArch64 = getTriple().getArch() == llvm::Triple::aarch64 ||
4676 getTriple().getArch() == llvm::Triple::aarch64_be;
Alexey Samsonov7f2a0d22015-06-19 21:36:47 +00004677 SanitizerMask Res = ToolChain::getSupportedSanitizers();
4678 Res |= SanitizerKind::Address;
4679 Res |= SanitizerKind::KernelAddress;
4680 Res |= SanitizerKind::Vptr;
Evgeniy Stepanov299238a2015-09-24 17:22:46 +00004681 Res |= SanitizerKind::SafeStack;
Adhemerval Zanella76aee672015-07-30 20:50:39 +00004682 if (IsX86_64 || IsMIPS64 || IsAArch64)
Alexey Samsonov7f2a0d22015-06-19 21:36:47 +00004683 Res |= SanitizerKind::DataFlow;
Adhemerval Zanellabffb20d2015-10-05 19:16:42 +00004684 if (IsX86_64 || IsMIPS64 || IsAArch64)
Alexey Samsonov7f2a0d22015-06-19 21:36:47 +00004685 Res |= SanitizerKind::Leak;
Bill Schmidt4b8841a2015-12-08 22:48:02 +00004686 if (IsX86_64 || IsMIPS64 || IsAArch64 || IsPowerPC64)
Alexey Samsonov7f2a0d22015-06-19 21:36:47 +00004687 Res |= SanitizerKind::Thread;
Adhemerval Zanella567b9262015-09-16 15:11:21 +00004688 if (IsX86_64 || IsMIPS64 || IsPowerPC64 || IsAArch64)
Jay Foade967dd02015-06-25 10:35:19 +00004689 Res |= SanitizerKind::Memory;
Derek Bruening256c2e12016-04-21 21:32:04 +00004690 if (IsX86_64)
4691 Res |= SanitizerKind::Efficiency;
Alexey Samsonov7f2a0d22015-06-19 21:36:47 +00004692 if (IsX86 || IsX86_64) {
4693 Res |= SanitizerKind::Function;
Alexey Samsonov7f2a0d22015-06-19 21:36:47 +00004694 }
4695 return Res;
4696}
4697
Vedant Kumar5fb00e42016-07-27 23:01:55 +00004698void Linux::addProfileRTLibs(const llvm::opt::ArgList &Args,
Xinliang David Li170cd102015-10-27 05:15:35 +00004699 llvm::opt::ArgStringList &CmdArgs) const {
Vedant Kumar5fb00e42016-07-27 23:01:55 +00004700 if (!needsProfileRT(Args)) return;
Xinliang David Li170cd102015-10-27 05:15:35 +00004701
4702 // Add linker option -u__llvm_runtime_variable to cause runtime
4703 // initialization module to be linked in.
4704 if (!Args.hasArg(options::OPT_coverage))
4705 CmdArgs.push_back(Args.MakeArgString(
4706 Twine("-u", llvm::getInstrProfRuntimeHookVarName())));
Vedant Kumar5fb00e42016-07-27 23:01:55 +00004707 ToolChain::addProfileRTLibs(Args, CmdArgs);
Xinliang David Li170cd102015-10-27 05:15:35 +00004708}
4709
Daniel Dunbarcc912342009-05-02 18:28:39 +00004710/// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly.
4711
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004712DragonFly::DragonFly(const Driver &D, const llvm::Triple &Triple,
4713 const ArgList &Args)
4714 : Generic_ELF(D, Triple, Args) {
Daniel Dunbarcc912342009-05-02 18:28:39 +00004715
4716 // Path mangling to find libexec
Daniel Dunbar88979912010-08-01 22:29:51 +00004717 getProgramPaths().push_back(getDriver().getInstalledDir());
Benjamin Kramer51477bd2011-03-01 22:50:47 +00004718 if (getDriver().getInstalledDir() != getDriver().Dir)
Daniel Dunbar88979912010-08-01 22:29:51 +00004719 getProgramPaths().push_back(getDriver().Dir);
Daniel Dunbarcc912342009-05-02 18:28:39 +00004720
Daniel Dunbar083edf72009-12-21 18:54:17 +00004721 getFilePaths().push_back(getDriver().Dir + "/../lib");
Daniel Dunbarcc912342009-05-02 18:28:39 +00004722 getFilePaths().push_back("/usr/lib");
Dimitry Andricf59a2b32015-12-27 10:01:44 +00004723 getFilePaths().push_back("/usr/lib/gcc50");
Daniel Dunbarcc912342009-05-02 18:28:39 +00004724}
4725
Rafael Espindola7cf32212013-03-20 03:05:54 +00004726Tool *DragonFly::buildAssembler() const {
Douglas Katzman95354292015-06-23 20:42:09 +00004727 return new tools::dragonfly::Assembler(*this);
Rafael Espindola7cf32212013-03-20 03:05:54 +00004728}
4729
4730Tool *DragonFly::buildLinker() const {
Douglas Katzman95354292015-06-23 20:42:09 +00004731 return new tools::dragonfly::Linker(*this);
Daniel Dunbarcc912342009-05-02 18:28:39 +00004732}
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004733
Justin Lebar21e5d4f2016-01-14 21:41:27 +00004734/// CUDA toolchain. Our assembler is ptxas, and our "linker" is fatbinary,
4735/// which isn't properly a linker but nonetheless performs the step of stitching
4736/// together object files from the assembler into a single blob.
Artem Belevich0ff05cd2015-07-13 23:27:56 +00004737
4738CudaToolChain::CudaToolChain(const Driver &D, const llvm::Triple &Triple,
4739 const ArgList &Args)
Justin Lebar21e5d4f2016-01-14 21:41:27 +00004740 : Linux(D, Triple, Args) {
4741 if (CudaInstallation.isValid())
4742 getProgramPaths().push_back(CudaInstallation.getBinPath());
4743}
Artem Belevich0ff05cd2015-07-13 23:27:56 +00004744
4745void
4746CudaToolChain::addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
4747 llvm::opt::ArgStringList &CC1Args) const {
4748 Linux::addClangTargetOptions(DriverArgs, CC1Args);
4749 CC1Args.push_back("-fcuda-is-device");
Artem Belevich34f481a2015-11-17 22:28:50 +00004750
Justin Lebard3a44f62016-04-05 18:26:20 +00004751 if (DriverArgs.hasFlag(options::OPT_fcuda_flush_denormals_to_zero,
4752 options::OPT_fno_cuda_flush_denormals_to_zero, false))
4753 CC1Args.push_back("-fcuda-flush-denormals-to-zero");
4754
Justin Lebar91f6f072016-05-23 20:19:56 +00004755 if (DriverArgs.hasFlag(options::OPT_fcuda_approx_transcendentals,
4756 options::OPT_fno_cuda_approx_transcendentals, false))
4757 CC1Args.push_back("-fcuda-approx-transcendentals");
4758
Artem Belevich34f481a2015-11-17 22:28:50 +00004759 if (DriverArgs.hasArg(options::OPT_nocudalib))
4760 return;
4761
4762 std::string LibDeviceFile = CudaInstallation.getLibDeviceFile(
4763 DriverArgs.getLastArgValue(options::OPT_march_EQ));
4764 if (!LibDeviceFile.empty()) {
4765 CC1Args.push_back("-mlink-cuda-bitcode");
4766 CC1Args.push_back(DriverArgs.MakeArgString(LibDeviceFile));
4767
4768 // Libdevice in CUDA-7.0 requires PTX version that's more recent
4769 // than LLVM defaults to. Use PTX4.2 which is the PTX version that
4770 // came with CUDA-7.0.
4771 CC1Args.push_back("-target-feature");
4772 CC1Args.push_back("+ptx42");
4773 }
Artem Belevich0ff05cd2015-07-13 23:27:56 +00004774}
4775
Justin Lebarc43ad9e2016-07-07 18:17:52 +00004776void CudaToolChain::AddCudaIncludeArgs(const ArgList &DriverArgs,
4777 ArgStringList &CC1Args) const {
4778 // Check our CUDA version if we're going to include the CUDA headers.
4779 if (!DriverArgs.hasArg(options::OPT_nocudainc) &&
Justin Lebarf3997712016-07-07 18:24:28 +00004780 !DriverArgs.hasArg(options::OPT_no_cuda_version_check)) {
Justin Lebarc43ad9e2016-07-07 18:17:52 +00004781 StringRef Arch = DriverArgs.getLastArgValue(options::OPT_march_EQ);
4782 assert(!Arch.empty() && "Must have an explicit GPU arch.");
4783 CudaInstallation.CheckCudaVersionSupportsArch(StringToCudaArch(Arch));
4784 }
4785 Linux::AddCudaIncludeArgs(DriverArgs, CC1Args);
4786}
4787
Artem Belevich0ff05cd2015-07-13 23:27:56 +00004788llvm::opt::DerivedArgList *
4789CudaToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args,
4790 const char *BoundArch) const {
4791 DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
4792 const OptTable &Opts = getDriver().getOpts();
4793
4794 for (Arg *A : Args) {
4795 if (A->getOption().matches(options::OPT_Xarch__)) {
4796 // Skip this argument unless the architecture matches BoundArch
Justin Lebar21e5d4f2016-01-14 21:41:27 +00004797 if (!BoundArch || A->getValue(0) != StringRef(BoundArch))
Artem Belevich0ff05cd2015-07-13 23:27:56 +00004798 continue;
4799
4800 unsigned Index = Args.getBaseArgs().MakeIndex(A->getValue(1));
4801 unsigned Prev = Index;
4802 std::unique_ptr<Arg> XarchArg(Opts.ParseOneArg(Args, Index));
4803
4804 // If the argument parsing failed or more than one argument was
4805 // consumed, the -Xarch_ argument's parameter tried to consume
4806 // extra arguments. Emit an error and ignore.
4807 //
4808 // We also want to disallow any options which would alter the
4809 // driver behavior; that isn't going to work in our model. We
4810 // use isDriverOption() as an approximation, although things
4811 // like -O4 are going to slip through.
4812 if (!XarchArg || Index > Prev + 1) {
4813 getDriver().Diag(diag::err_drv_invalid_Xarch_argument_with_args)
4814 << A->getAsString(Args);
4815 continue;
4816 } else if (XarchArg->getOption().hasFlag(options::DriverOption)) {
4817 getDriver().Diag(diag::err_drv_invalid_Xarch_argument_isdriver)
4818 << A->getAsString(Args);
4819 continue;
4820 }
4821 XarchArg->setBaseArg(A);
4822 A = XarchArg.release();
4823 DAL->AddSynthesizedArg(A);
4824 }
4825 DAL->append(A);
4826 }
4827
Justin Lebar4db224e2016-06-15 23:46:11 +00004828 if (BoundArch) {
4829 DAL->eraseArg(options::OPT_march_EQ);
Justin Lebar21e5d4f2016-01-14 21:41:27 +00004830 DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_march_EQ), BoundArch);
Justin Lebar4db224e2016-06-15 23:46:11 +00004831 }
Artem Belevich0ff05cd2015-07-13 23:27:56 +00004832 return DAL;
4833}
4834
Justin Lebar21e5d4f2016-01-14 21:41:27 +00004835Tool *CudaToolChain::buildAssembler() const {
4836 return new tools::NVPTX::Assembler(*this);
4837}
4838
4839Tool *CudaToolChain::buildLinker() const {
4840 return new tools::NVPTX::Linker(*this);
4841}
4842
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004843/// XCore tool chain
Douglas Katzman54366072015-07-27 16:53:08 +00004844XCoreToolChain::XCoreToolChain(const Driver &D, const llvm::Triple &Triple,
4845 const ArgList &Args)
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004846 : ToolChain(D, Triple, Args) {
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004847 // ProgramPaths are found via 'PATH' environment variable.
4848}
4849
Douglas Katzman54366072015-07-27 16:53:08 +00004850Tool *XCoreToolChain::buildAssembler() const {
Douglas Katzman95354292015-06-23 20:42:09 +00004851 return new tools::XCore::Assembler(*this);
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004852}
4853
Douglas Katzman54366072015-07-27 16:53:08 +00004854Tool *XCoreToolChain::buildLinker() const {
4855 return new tools::XCore::Linker(*this);
4856}
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004857
Douglas Katzman54366072015-07-27 16:53:08 +00004858bool XCoreToolChain::isPICDefault() const { return false; }
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004859
Douglas Katzman54366072015-07-27 16:53:08 +00004860bool XCoreToolChain::isPIEDefault() const { return false; }
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004861
Douglas Katzman54366072015-07-27 16:53:08 +00004862bool XCoreToolChain::isPICDefaultForced() const { return false; }
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004863
Douglas Katzman54366072015-07-27 16:53:08 +00004864bool XCoreToolChain::SupportsProfiling() const { return false; }
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004865
Douglas Katzman54366072015-07-27 16:53:08 +00004866bool XCoreToolChain::hasBlocksRuntime() const { return false; }
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004867
Douglas Katzman54366072015-07-27 16:53:08 +00004868void XCoreToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
4869 ArgStringList &CC1Args) const {
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004870 if (DriverArgs.hasArg(options::OPT_nostdinc) ||
4871 DriverArgs.hasArg(options::OPT_nostdlibinc))
4872 return;
4873 if (const char *cl_include_dir = getenv("XCC_C_INCLUDE_PATH")) {
4874 SmallVector<StringRef, 4> Dirs;
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004875 const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'};
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004876 StringRef(cl_include_dir).split(Dirs, StringRef(EnvPathSeparatorStr));
4877 ArrayRef<StringRef> DirVec(Dirs);
4878 addSystemIncludes(DriverArgs, CC1Args, DirVec);
4879 }
4880}
4881
Douglas Katzman54366072015-07-27 16:53:08 +00004882void XCoreToolChain::addClangTargetOptions(const ArgList &DriverArgs,
4883 ArgStringList &CC1Args) const {
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004884 CC1Args.push_back("-nostdsysteminc");
4885}
4886
Douglas Katzman54366072015-07-27 16:53:08 +00004887void XCoreToolChain::AddClangCXXStdlibIncludeArgs(
4888 const ArgList &DriverArgs, ArgStringList &CC1Args) const {
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004889 if (DriverArgs.hasArg(options::OPT_nostdinc) ||
Robert Lyttonf9710b32014-08-01 13:11:46 +00004890 DriverArgs.hasArg(options::OPT_nostdlibinc) ||
4891 DriverArgs.hasArg(options::OPT_nostdincxx))
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004892 return;
4893 if (const char *cl_include_dir = getenv("XCC_CPLUS_INCLUDE_PATH")) {
4894 SmallVector<StringRef, 4> Dirs;
Douglas Katzmana67e50c2015-06-26 15:47:46 +00004895 const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'};
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004896 StringRef(cl_include_dir).split(Dirs, StringRef(EnvPathSeparatorStr));
4897 ArrayRef<StringRef> DirVec(Dirs);
4898 addSystemIncludes(DriverArgs, CC1Args, DirVec);
4899 }
4900}
4901
Douglas Katzman54366072015-07-27 16:53:08 +00004902void XCoreToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
4903 ArgStringList &CmdArgs) const {
Robert Lyttoncf1dd692013-10-11 10:29:40 +00004904 // We don't output any lib args. This is handled by xcc.
4905}
Douglas Katzman84a75642015-06-19 14:55:19 +00004906
Douglas Katzmand6e597c2015-09-17 19:56:40 +00004907MyriadToolChain::MyriadToolChain(const Driver &D, const llvm::Triple &Triple,
4908 const ArgList &Args)
Douglas Katzman5eddc232016-05-09 19:09:59 +00004909 : Generic_ELF(D, Triple, Args) {
Douglas Katzmand6e597c2015-09-17 19:56:40 +00004910 // If a target of 'sparc-myriad-elf' is specified to clang, it wants to use
4911 // 'sparc-myriad--elf' (note the unknown OS) as the canonical triple.
4912 // This won't work to find gcc. Instead we give the installation detector an
4913 // extra triple, which is preferable to further hacks of the logic that at
4914 // present is based solely on getArch(). In particular, it would be wrong to
4915 // choose the myriad installation when targeting a non-myriad sparc install.
4916 switch (Triple.getArch()) {
4917 default:
Eric Christopherefef8ef2015-12-07 22:43:05 +00004918 D.Diag(diag::err_target_unsupported_arch) << Triple.getArchName()
4919 << "myriad";
Douglas Katzmand6e597c2015-09-17 19:56:40 +00004920 case llvm::Triple::sparc:
4921 case llvm::Triple::sparcel:
4922 case llvm::Triple::shave:
Benjamin Kramerd45b2052015-10-07 15:48:01 +00004923 GCCInstallation.init(Triple, Args, {"sparc-myriad-elf"});
Douglas Katzmand6e597c2015-09-17 19:56:40 +00004924 }
Douglas Katzman674a3122015-11-18 16:24:46 +00004925
4926 if (GCCInstallation.isValid()) {
4927 // The contents of LibDir are independent of the version of gcc.
Douglas Katzman87da5f42016-07-25 16:36:02 +00004928 // This contains libc, libg, libm, libstdc++, libssp.
4929 // The 'ma1x00' and 'nofpu' variants are irrelevant.
Douglas Katzman674a3122015-11-18 16:24:46 +00004930 SmallString<128> LibDir(GCCInstallation.getParentLibPath());
Douglas Katzman87da5f42016-07-25 16:36:02 +00004931 llvm::sys::path::append(LibDir, "../sparc-myriad-elf/lib");
Douglas Katzman674a3122015-11-18 16:24:46 +00004932 addPathIfExists(D, LibDir, getFilePaths());
4933
4934 // This directory contains crt{i,n,begin,end}.o as well as libgcc.
4935 // These files are tied to a particular version of gcc.
4936 SmallString<128> CompilerSupportDir(GCCInstallation.getInstallPath());
Douglas Katzman674a3122015-11-18 16:24:46 +00004937 addPathIfExists(D, CompilerSupportDir, getFilePaths());
4938 }
Douglas Katzmand6e597c2015-09-17 19:56:40 +00004939}
4940
Angel Garcia Gomez637d1e62015-10-20 13:23:58 +00004941MyriadToolChain::~MyriadToolChain() {}
Douglas Katzmand6e597c2015-09-17 19:56:40 +00004942
Douglas Katzmanb1278f32015-09-17 21:20:16 +00004943void MyriadToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
4944 ArgStringList &CC1Args) const {
4945 if (!DriverArgs.hasArg(options::OPT_nostdinc))
4946 addSystemInclude(DriverArgs, CC1Args, getDriver().SysRoot + "/include");
4947}
4948
Eric Christopherefef8ef2015-12-07 22:43:05 +00004949void MyriadToolChain::AddClangCXXStdlibIncludeArgs(
4950 const ArgList &DriverArgs, ArgStringList &CC1Args) const {
James Y Knighta6c9ee72015-10-16 18:46:26 +00004951 if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
4952 DriverArgs.hasArg(options::OPT_nostdincxx))
4953 return;
4954
4955 // Only libstdc++, for now.
4956 StringRef LibDir = GCCInstallation.getParentLibPath();
4957 const GCCVersion &Version = GCCInstallation.getVersion();
4958 StringRef TripleStr = GCCInstallation.getTriple().str();
4959 const Multilib &Multilib = GCCInstallation.getMultilib();
4960
Eric Christopherefef8ef2015-12-07 22:43:05 +00004961 addLibStdCXXIncludePaths(
4962 LibDir.str() + "/../" + TripleStr.str() + "/include/c++/" + Version.Text,
4963 "", TripleStr, "", "", Multilib.includeSuffix(), DriverArgs, CC1Args);
James Y Knighta6c9ee72015-10-16 18:46:26 +00004964}
4965
Douglas Katzmand6e597c2015-09-17 19:56:40 +00004966// MyriadToolChain handles several triples:
4967// {shave,sparc{,el}}-myriad-{rtems,unknown}-elf
4968Tool *MyriadToolChain::SelectTool(const JobAction &JA) const {
4969 // The inherited method works fine if not targeting the SHAVE.
4970 if (!isShaveCompilation(getTriple()))
4971 return ToolChain::SelectTool(JA);
Douglas Katzman84a75642015-06-19 14:55:19 +00004972 switch (JA.getKind()) {
Douglas Katzman9dc4c622015-11-20 04:58:12 +00004973 case Action::PreprocessJobClass:
Douglas Katzman84a75642015-06-19 14:55:19 +00004974 case Action::CompileJobClass:
4975 if (!Compiler)
Douglas Katzman95354292015-06-23 20:42:09 +00004976 Compiler.reset(new tools::SHAVE::Compiler(*this));
Douglas Katzman84a75642015-06-19 14:55:19 +00004977 return Compiler.get();
4978 case Action::AssembleJobClass:
4979 if (!Assembler)
Douglas Katzman95354292015-06-23 20:42:09 +00004980 Assembler.reset(new tools::SHAVE::Assembler(*this));
Douglas Katzman84a75642015-06-19 14:55:19 +00004981 return Assembler.get();
4982 default:
4983 return ToolChain::getTool(JA.getKind());
4984 }
4985}
4986
Douglas Katzmand6e597c2015-09-17 19:56:40 +00004987Tool *MyriadToolChain::buildLinker() const {
4988 return new tools::Myriad::Linker(*this);
Douglas Katzman84a75642015-06-19 14:55:19 +00004989}
Dan Gohmanc2853072015-09-03 22:51:53 +00004990
Dan Gohman52816862015-12-16 23:30:41 +00004991WebAssembly::WebAssembly(const Driver &D, const llvm::Triple &Triple,
4992 const llvm::opt::ArgList &Args)
4993 : ToolChain(D, Triple, Args) {
Dan Gohman57b62c52016-02-22 19:26:15 +00004994
4995 assert(Triple.isArch32Bit() != Triple.isArch64Bit());
4996 getFilePaths().push_back(
4997 getDriver().SysRoot + "/lib" + (Triple.isArch32Bit() ? "32" : "64"));
4998
Dan Gohman52816862015-12-16 23:30:41 +00004999 // Use LLD by default.
5000 DefaultLinker = "lld";
5001}
5002
Dan Gohmanc2853072015-09-03 22:51:53 +00005003bool WebAssembly::IsMathErrnoDefault() const { return false; }
5004
5005bool WebAssembly::IsObjCNonFragileABIDefault() const { return true; }
5006
5007bool WebAssembly::UseObjCMixedDispatch() const { return true; }
5008
5009bool WebAssembly::isPICDefault() const { return false; }
5010
5011bool WebAssembly::isPIEDefault() const { return false; }
5012
5013bool WebAssembly::isPICDefaultForced() const { return false; }
5014
5015bool WebAssembly::IsIntegratedAssemblerDefault() const { return true; }
5016
5017// TODO: Support Objective C stuff.
5018bool WebAssembly::SupportsObjCGC() const { return false; }
5019
5020bool WebAssembly::hasBlocksRuntime() const { return false; }
5021
5022// TODO: Support profiling.
5023bool WebAssembly::SupportsProfiling() const { return false; }
5024
Dan Gohman52816862015-12-16 23:30:41 +00005025bool WebAssembly::HasNativeLLVMSupport() const { return true; }
5026
Dan Gohmanc2853072015-09-03 22:51:53 +00005027void WebAssembly::addClangTargetOptions(const ArgList &DriverArgs,
5028 ArgStringList &CC1Args) const {
5029 if (DriverArgs.hasFlag(options::OPT_fuse_init_array,
5030 options::OPT_fno_use_init_array, true))
5031 CC1Args.push_back("-fuse-init-array");
5032}
Filipe Cabecinhasc888e192015-10-14 12:25:43 +00005033
Dan Gohman6ad8f612016-01-14 16:00:13 +00005034ToolChain::RuntimeLibType WebAssembly::GetDefaultRuntimeLibType() const {
5035 return ToolChain::RLT_CompilerRT;
5036}
5037
5038ToolChain::CXXStdlibType WebAssembly::GetCXXStdlibType(const ArgList &Args) const {
5039 return ToolChain::CST_Libcxx;
5040}
5041
5042void WebAssembly::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
5043 ArgStringList &CC1Args) const {
5044 if (!DriverArgs.hasArg(options::OPT_nostdinc))
5045 addSystemInclude(DriverArgs, CC1Args, getDriver().SysRoot + "/include");
5046}
5047
5048void WebAssembly::AddClangCXXStdlibIncludeArgs(
5049 const llvm::opt::ArgList &DriverArgs,
5050 llvm::opt::ArgStringList &CC1Args) const {
5051 if (!DriverArgs.hasArg(options::OPT_nostdlibinc) &&
5052 !DriverArgs.hasArg(options::OPT_nostdincxx))
5053 addSystemInclude(DriverArgs, CC1Args,
5054 getDriver().SysRoot + "/include/c++/v1");
5055}
5056
Dan Gohman52816862015-12-16 23:30:41 +00005057Tool *WebAssembly::buildLinker() const {
5058 return new tools::wasm::Linker(*this);
5059}
5060
Filipe Cabecinhasc888e192015-10-14 12:25:43 +00005061PS4CPU::PS4CPU(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
5062 : Generic_ELF(D, Triple, Args) {
5063 if (Args.hasArg(options::OPT_static))
5064 D.Diag(diag::err_drv_unsupported_opt_for_target) << "-static" << "PS4";
5065
Paul Robinson9d613612016-05-16 17:22:25 +00005066 // Determine where to find the PS4 libraries. We use SCE_ORBIS_SDK_DIR
Filipe Cabecinhasc888e192015-10-14 12:25:43 +00005067 // if it exists; otherwise use the driver's installation path, which
5068 // should be <SDK_DIR>/host_tools/bin.
5069
5070 SmallString<512> PS4SDKDir;
Paul Robinson9d613612016-05-16 17:22:25 +00005071 if (const char *EnvValue = getenv("SCE_ORBIS_SDK_DIR")) {
Filipe Cabecinhasc888e192015-10-14 12:25:43 +00005072 if (!llvm::sys::fs::exists(EnvValue))
5073 getDriver().Diag(clang::diag::warn_drv_ps4_sdk_dir) << EnvValue;
5074 PS4SDKDir = EnvValue;
5075 } else {
5076 PS4SDKDir = getDriver().Dir;
5077 llvm::sys::path::append(PS4SDKDir, "/../../");
Eric Christopherefef8ef2015-12-07 22:43:05 +00005078 }
Filipe Cabecinhasc888e192015-10-14 12:25:43 +00005079
Eric Christopherefef8ef2015-12-07 22:43:05 +00005080 // By default, the driver won't report a warning if it can't find
Filipe Cabecinhasc888e192015-10-14 12:25:43 +00005081 // PS4's include or lib directories. This behavior could be changed if
Eric Christopherefef8ef2015-12-07 22:43:05 +00005082 // -Weverything or -Winvalid-or-nonexistent-directory options are passed.
Filipe Cabecinhasc888e192015-10-14 12:25:43 +00005083 // If -isysroot was passed, use that as the SDK base path.
5084 std::string PrefixDir;
5085 if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
5086 PrefixDir = A->getValue();
5087 if (!llvm::sys::fs::exists(PrefixDir))
5088 getDriver().Diag(clang::diag::warn_missing_sysroot) << PrefixDir;
5089 } else
5090 PrefixDir = PS4SDKDir.str();
5091
5092 SmallString<512> PS4SDKIncludeDir(PrefixDir);
5093 llvm::sys::path::append(PS4SDKIncludeDir, "target/include");
5094 if (!Args.hasArg(options::OPT_nostdinc) &&
5095 !Args.hasArg(options::OPT_nostdlibinc) &&
5096 !Args.hasArg(options::OPT_isysroot) &&
5097 !Args.hasArg(options::OPT__sysroot_EQ) &&
5098 !llvm::sys::fs::exists(PS4SDKIncludeDir)) {
5099 getDriver().Diag(clang::diag::warn_drv_unable_to_find_directory_expected)
5100 << "PS4 system headers" << PS4SDKIncludeDir;
5101 }
5102
5103 SmallString<512> PS4SDKLibDir(PS4SDKDir);
5104 llvm::sys::path::append(PS4SDKLibDir, "target/lib");
5105 if (!Args.hasArg(options::OPT_nostdlib) &&
5106 !Args.hasArg(options::OPT_nodefaultlibs) &&
5107 !Args.hasArg(options::OPT__sysroot_EQ) && !Args.hasArg(options::OPT_E) &&
5108 !Args.hasArg(options::OPT_c) && !Args.hasArg(options::OPT_S) &&
5109 !Args.hasArg(options::OPT_emit_ast) &&
5110 !llvm::sys::fs::exists(PS4SDKLibDir)) {
5111 getDriver().Diag(clang::diag::warn_drv_unable_to_find_directory_expected)
5112 << "PS4 system libraries" << PS4SDKLibDir;
5113 return;
5114 }
5115 getFilePaths().push_back(PS4SDKLibDir.str());
5116}
5117
5118Tool *PS4CPU::buildAssembler() const {
5119 return new tools::PS4cpu::Assemble(*this);
5120}
5121
5122Tool *PS4CPU::buildLinker() const { return new tools::PS4cpu::Link(*this); }
5123
5124bool PS4CPU::isPICDefault() const { return true; }
5125
5126bool PS4CPU::HasNativeLLVMSupport() const { return true; }
5127
5128SanitizerMask PS4CPU::getSupportedSanitizers() const {
5129 SanitizerMask Res = ToolChain::getSupportedSanitizers();
5130 Res |= SanitizerKind::Address;
5131 Res |= SanitizerKind::Vptr;
5132 return Res;
5133}